public override bool Execute() { try { if (!File.Exists(VsixPath)) { throw new Exception("Cannot find VSIX file " + VsixPath); } var visualStudios = GetAllVisualStudios(); if (visualStudios.Length == 0) { throw new Exception("Cannot find any installed copies of Visual Studio."); } var vsix = ExtensionManagerService.CreateInstallableExtension(VsixPath); foreach (var vs in visualStudios) { Console.WriteLine("Installing {0} version {1} to Visual Studio {2} /RootSuffix {3}", vsix.Header.Name, vsix.Header.Version, vs.Version, RootSuffix); Install(vs.ExePath, vsix, RootSuffix); } return(true); } catch (Exception ex) { Log.LogErrorFromException(ex); return(false); } }
public void InstallExtension(string vsixPath) { if (!Exists()) { throw new InvalidOperationException("Cannot install VSIX in non-existing instance."); } using (var settings = ExternalSettingsManager.CreateForApplication(GetExePath(), Suffix)) { var ems = new ExtensionManagerService(settings); IInstallableExtension vsix = ExtensionManagerService.CreateInstallableExtension(vsixPath); if (ems.IsInstalled(vsix)) { IInstalledExtension installedVsix = ems.GetInstalledExtension(vsix.Header.Identifier); ems.Uninstall(installedVsix); if (ems.IsInstalled(vsix)) { throw new InvalidOperationException("Could not uninstall already installed GoogleTestAdapter."); } } ems.Install(vsix, perMachine: false); if (!ems.IsInstalled(vsix)) { throw new InvalidOperationException("Could not install GoogleTestAdapter."); } ems.Close(); } }
static void Main(string[] args) { Log("Starting HostProcess..."); if (args.Length < 2) { LogError($"Invalid number of arguments. Expected 3 but was {args.Length}: {string.Join(", ", args)}"); Environment.Exit(-1); } string vsixPath = args[0]; string devenvPath = args[1]; string hive = args.Length == 3 ? args[2] : null; try { IInstallableExtension vsix = ExtensionManagerService.CreateInstallableExtension(vsixPath); if (string.IsNullOrWhiteSpace(hive)) { hive = ""; } PerformInstallation(vsix, devenvPath, hive); } catch (Exception) { Environment.Exit(-1); } Log("Exiting HostProcess..."); }
internal void InstallExtension(string vsixPath) { if (!Exists()) throw new InvalidOperationException("Cannot install VSIX in non-existing instance."); using (var settings = ExternalSettingsManager.CreateForApplication(GetExePath(), Suffix)) { var ems = new ExtensionManagerService(settings); IInstallableExtension vsix = ExtensionManagerService.CreateInstallableExtension(vsixPath); if (ems.IsInstalled(vsix)) { IInstalledExtension installedVsix = ems.GetInstalledExtension(vsix.Header.Identifier); ems.Uninstall(installedVsix); if (ems.IsInstalled(vsix)) throw new InvalidOperationException("Could not uninstall already installed GoogleTestAdapter."); } ems.Install(vsix, perMachine: false); if (!ems.IsInstalled(vsix)) throw new InvalidOperationException("Could not install GoogleTestAdapter."); ems.Close(); } }
static int Main(string[] args) { if (args.Length != 2 && args.Length != 3) { PrintUsage(); return(1); } string version; if (args.Length == 3) { version = args[0]; args = args.Skip(1).ToArray(); } else { version = FindVsVersions().LastOrDefault().ToString(); if (string.IsNullOrEmpty(version)) { return(PrintError("Cannot find any installed copies of Visual Studio.")); } } string vsExe = GetVersionExe(version); if (string.IsNullOrEmpty(vsExe) && version.All(char.IsNumber)) { version += ".0"; vsExe = GetVersionExe(version); } if (string.IsNullOrEmpty(vsExe)) { Console.Error.WriteLine("Cannot find Visual Studio " + version); PrintVsVersions(); return(1); } if (!File.Exists(args[1])) { return(PrintError("Cannot find VSIX file " + args[1])); } var vsix = ExtensionManagerService.CreateInstallableExtension(args[1]); Console.WriteLine("Installing " + vsix.Header.Name + " version " + vsix.Header.Version + " to Visual Studio " + version + " /RootSuffix " + args[0]); try { Install(vsExe, vsix, args[0]); } catch (Exception ex) { return(PrintError("Error: " + ex.Message)); } return(0); }
public static void Install(string vsExe, IInstallableExtension vsix, string rootSuffix) { using (var esm = ExternalSettingsManager.CreateForApplication(vsExe, rootSuffix)) { var ems = new ExtensionManagerService(esm); ems.Install(vsix, perMachine: false); } }
private static void RevertUninstall(ExtensionManagerService extensionManager, IInstalledExtension oldExtension) { if (oldExtension == null || extensionManager.IsInstalled(oldExtension)) { return; } Log($"Reverting uninstall of '{oldExtension.Header.Name}'..."); extensionManager.RevertUninstall(oldExtension); }
static int Main(string[] args) { try { if (args.Length != 3) { PrintUsage(); return 1; } var vsixFile = args[0]; if (!File.Exists(vsixFile)) { Console.Error.WriteLine("VSIX file could not be found: {0}", vsixFile); return 1; } var vsExecutable = args[1]; if (!File.Exists(vsExecutable)) { Console.Error.WriteLine("Visual Studio executable file could not be found: {0}", vsExecutable); return 1; } var rootSuffix = args[2]; if (string.IsNullOrWhiteSpace(rootSuffix)) { Console.Error.WriteLine("RootSuffix must have a value"); return 1; } var vsix = ExtensionManagerService.CreateInstallableExtension(vsixFile); Console.WriteLine( "Installing {0} version {1} to Visual Studio /RootSuffix {2}", vsix.Header.Name, vsix.Header.Version, rootSuffix ); using (var settingsManager = ExternalSettingsManager.CreateForApplication(vsExecutable, rootSuffix)) { var extensionManagerService = new ExtensionManagerService(settingsManager); extensionManagerService.Install(vsix, perMachine: false); } return 0; } catch (Exception ex) { Console.Error.WriteLine("Error: {0}", ex.Message); return 1; } }
static void Install(string vsExe, IInstallableExtension vsix, string rootSuffix) { using (var esm = ExternalSettingsManager.CreateForApplication(vsExe, rootSuffix)) { var ems = new ExtensionManagerService(esm); var installed = ems.GetInstalledExtensions().FirstOrDefault(x => x.Header.Identifier == vsix.Header.Identifier); if (installed != null) { ems.Uninstall(installed); } ems.Install(vsix, perMachine: false); } }
public static void Install(string vsExe, IInstallableExtension vsix, string rootSuffix) { using (var esm = ExternalSettingsManager.CreateForApplication(vsExe, rootSuffix)) { var ems = new ExtensionManagerService(esm); IInstalledExtension installedVsix = null; if (ems.TryGetInstalledExtension(vsix.Header.Identifier, out installedVsix)) { Console.WriteLine($"Extension {vsix.Header.Name} version {vsix.Header.Version} already installed, unistalling first."); ems.Uninstall(installedVsix); } ems.Install(vsix, perMachine: false); } }
static void UninstallAll(ExtensionManagerService service) { // We only want extensions which are not installed per machine and we want them sorted by their dependencies. var installedExtensions = service.GetInstalledExtensions() .Where((installedExtension) => !installedExtension.InstalledPerMachine) .OrderBy((installedExtension) => installedExtension, Comparer <IInstalledExtension> .Create((left, right) => { if (left.References.Count() == 0) { // When left.References.Count() is zero, then we have two scenarios: // * right.References.Count() is zero, and the order of the two components doesn't matter, so we return 0 // * right.References.Count() is not zero, which means it should be uninstalled after left, so we return -1 return(right.References.Count() == 0 ? 0 : -1); } else if (right.References.Count() == 0) { // When left.References.Count() is not zero, but right.References.Count() is, then we have one scenario: // * right should be uninstalled before left, so we return 1 return(1); } if (left.References.Any((extensionReference) => extensionReference.Identifier == right.Header.Identifier)) { // When left.References contains right, then we have one scenario: // * left is dependent on right, which means it must be uninstalled afterwards, so we return 1 return(1); } else if (right.References.Any((extensionReference) => extensionReference.Identifier == left.Header.Identifier)) { // When right.References contains left, then we have one scenario: // * right is dependent on left, which means it must be uninstalled afterwards, so we return -1 return(-1); } // Finally, if both projects contain references, but neither depends on the other, we have one scenario: // * left and right are independent of each other, and the order of the two components doesn't matter, so we return 0 return(0); })); foreach (var installedExtension in installedExtensions) { Console.WriteLine(" Uninstalling {0}... ", installedExtension.Header.Name); service.Uninstall(installedExtension); } }
private static IInstalledExtension PerformInstallation(IInstallableExtension vsix, string devenvPath, string hive) { IInstalledExtension extension; using (var settingsManager = ExternalSettingsManager.CreateForApplication(devenvPath, hive)) { var identifier = vsix.Header.Identifier; var name = vsix.Header.Name; Log($"Preparing to install '{name}' with identifier '{identifier}' into '{hive}'"); var extensionManager = new ExtensionManagerService(settingsManager); if (extensionManager.TryGetInstalledExtension(identifier, out extension)) { Log($"Extension '{name}' was already installed. Uninstalling..."); try { extensionManager.Uninstall(extension); extensionManager.CommitExternalUninstall(extension); } catch (Exception ex) { LogError($"An error ocurred while trying to uninstall '{name}'. Rolling back...", ex); RevertUninstall(extensionManager, extension); throw; } } try { Log($"Starting installation of '{name}'"); extensionManager.Install(vsix, perMachine: false); extension = extensionManager.GetInstalledExtension(identifier); Log($"Installation of '{name}' into '{hive}' completed successfully."); } catch (Exception ex) { LogError($"An error ocurred while trying to install '{name}'. Rolling back...", ex); RevertUninstall(extensionManager, extension); throw; } } return(extension); }
protected override ContextMenuStrip CreateMenu() { var menuStrip = new ContextMenuStrip(); var item = new ToolStripMenuItem("Copy VSIX ID to Clipboard"); item.Click += (sender, args) => { string path = SelectedItemPaths.FirstOrDefault(); if (string.IsNullOrEmpty(path)) { return; } IInstallableExtension vsix = ExtensionManagerService.CreateInstallableExtension(path); Clipboard.SetText(vsix.Header.Identifier); }; menuStrip.Items.Add(item); return(menuStrip); }
protected override bool CanShowMenu() { var paths = SelectedItemPaths.ToArray(); if (paths.Length != 1 || Path.GetExtension(paths[0]).ToLowerInvariant() != ".vsix") { return(false); } try { vsix = ExtensionManagerService.CreateInstallableExtension(paths[0]); } catch (Exception ex) { LogError($"Unable to load the extension '{paths[0]}'", ex); return(false); } return(vsix != null); }
public static int Main(string[] args) { if (args.Length == 0) { PrintUsage(); return(0); } var argList = new List <string>(args); var rootSuffix = ExtractArg(argList, "rootSuffix") ?? "Exp"; var skipIfEqualOrNewerInstalled = FindArg(argList, "skipIfEqualOrNewerInstalled"); var uninstall = FindArg(argList, "u"); var uninstallAll = FindArg(argList, "uninstallAll"); var printHelp = FindArg(argList, "?") || FindArg(argList, "h") || FindArg(argList, "help"); var vsInstallDir = ExtractArg(argList, "vsInstallDir") ?? Environment.GetEnvironmentVariable("VsInstallDir"); var expectedArgCount = uninstallAll ? 0 : 1; if (argList.Count != expectedArgCount) { PrintUsage(); return(1); } string extensionPath = uninstallAll ? string.Empty : argList[0]; string devenvPath; try { devenvPath = GetDevenvPath(vsInstallDir); var assemblyResolutionPaths = new string[] { Path.Combine(vsInstallDir, @"Common7\IDE"), Path.Combine(vsInstallDir, @"Common7\IDE\PrivateAssemblies"), Path.Combine(vsInstallDir, @"Common7\IDE\PublicAssemblies") }; AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs eventArgs) => { var assemblyFileName = $"{eventArgs.Name.Split(',')[0]}.dll"; foreach (var assemblyResolutionPath in assemblyResolutionPaths) { var assemblyFilePath = Path.Combine(assemblyResolutionPath, assemblyFileName); if (File.Exists(assemblyFilePath)) { return(Assembly.LoadFrom(assemblyFilePath)); } } return(null); }; Console.WriteLine(Environment.CommandLine); if (IsRunningAsAdmin()) { Console.WriteLine(" Running as Admin."); } RunProgram(); // Move all of this into a local method so that it only causes the assembly loads after the resolver has been hooked up void RunProgram() { var installedExtensionComparer = Comparer <IInstalledExtension> .Create((left, right) => { if (left.References.Count() == 0) { // When left.References.Count() is zero, then we have two scenarios: // * right.References.Count() is zero, and the order of the two components doesn't matter, so we return 0 // * right.References.Count() is not zero, which means it should be uninstalled after left, so we return -1 return(right.References.Count() == 0 ? 0 : -1); } else if (right.References.Count() == 0) { // When left.References.Count() is not zero, but right.References.Count() is, then we have one scenario: // * right should be uninstalled before left, so we return 1 return(1); } if (left.References.Any((extensionReference) => extensionReference.Identifier == right.Header.Identifier)) { // When left.References contains right, then we have one scenario: // * left is dependent on right, which means it must be uninstalled afterwards, so we return 1 return(1); } else if (right.References.Any((extensionReference) => extensionReference.Identifier == left.Header.Identifier)) { // When right.References contains left, then we have one scenario: // * right is dependent on left, which means it must be uninstalled afterwards, so we return -1 return(-1); } // Finally, if both projects contain references, but neither depends on the other, we have one scenario: // * left and right are independent of each other, and the order of the two components doesn't matter, so we return 0 return(0); }); using (var settingsManager = ExternalSettingsManager.CreateForApplication(devenvPath, rootSuffix)) { ExtensionManagerService extensionManagerService = null; try { extensionManagerService = new ExtensionManagerService(settingsManager); if (uninstallAll) { Console.WriteLine(" Uninstalling all local extensions..."); UninstallAll(); } else { var extensionManager = (IVsExtensionManager)(extensionManagerService); var installableExtension = extensionManager.CreateInstallableExtension(extensionPath); var status = GetInstallStatus(installableExtension.Header); var installedVersionIsEqualOrNewer = installableExtension.Header.Version < status.installedExtension?.Header.Version; if (uninstall) { if (status.installed) { if (installedVersionIsEqualOrNewer && skipIfEqualOrNewerInstalled) { Environment.ExitCode = INSTALL_OR_UNINSTALL_SKIPPED_EXCEPTION_CODE; throw new Exception($"Skipping uninstall of version ({status.installedExtension.Header.Version}), which is equal to or newer than the one supplied on the command line ({installableExtension.Header.Version})."); } if (status.installedGlobally) { Console.WriteLine($" Skipping uninstall for global extension: '{status.installedExtension.InstallPath}'"); } else { Console.WriteLine($" Uninstalling local extension: '{status.installedExtension.InstallPath}'"); Uninstall(status.installedExtension); } } else { Console.WriteLine(" Nothing to uninstall..."); } } else { if (status.installed) { if (installedVersionIsEqualOrNewer && skipIfEqualOrNewerInstalled) { Environment.ExitCode = INSTALL_OR_UNINSTALL_SKIPPED_EXCEPTION_CODE; throw new Exception($"Skipping install of version ({installableExtension.Header.Version}), which is older than the one currently installed ({status.installedExtension.Header.Version})."); } if (status.installedGlobally) { if (installedVersionIsEqualOrNewer) { Environment.ExitCode = GLOBAL_VERSION_NEWER_EXCEPTION_CODE; throw new Exception($"The version you are attempting to install ({installableExtension.Header.Version}) has a version that is less than the one installed globally ({status.installedExtension.Header.Version})."); } else { Console.WriteLine($" Installing local extension ({extensionPath}) over global extension ({status.installedExtension.InstallPath})"); } } else { Console.WriteLine($" Updating local extension ({status.installedExtension.InstallPath}) to '{extensionPath}'"); Uninstall(status.installedExtension); } } else { Console.WriteLine($" Installing local extension: '{extensionPath}'"); } Install(installableExtension); } } } finally { extensionManagerService?.Close(); extensionManagerService = null; } bool IsInstalledGlobally(IInstalledExtension installedExtension) { return(installedExtension.InstalledPerMachine || installedExtension.InstallPath.StartsWith(vsInstallDir, StringComparison.OrdinalIgnoreCase)); } (bool installed, bool installedGlobally, IInstalledExtension installedExtension) GetInstallStatus(IExtensionHeader extensionHeader) { var installed = extensionManagerService.TryGetInstalledExtension(extensionHeader.Identifier, out var installedExtension); var installedGlobally = installed && IsInstalledGlobally(installedExtension); return(installed, installedGlobally, installedExtension); } void Install(IInstallableExtension installableExtension) { extensionManagerService.Install(installableExtension, perMachine: false); var settingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings); EnableLoadingAllExtensions(settingsStore); RemoveExtensionFromPendingDeletions(settingsStore, installableExtension.Header); UpdateLastExtensionsChange(settingsStore); // Recreate the extensionManagerService to force the extension cache to recreate extensionManagerService?.Close(); extensionManagerService = new ExtensionManagerService(settingsManager); var status = GetInstallStatus(installableExtension.Header); if (!status.installed) { Environment.ExitCode = INSTALL_FAILED_NOTFOUND_EXCEPTION_CODE; throw new Exception($"The extension failed to install. It could not be located."); } else if (status.installedExtension.Header.Version != installableExtension.Header.Version) { Environment.ExitCode = INSTALL_FAILED_VERSION_EXCEPTION_CODE; throw new Exception($"The extension failed to install. The located version ({status.installedExtension.Header.Version}) does not match the expected version ({installableExtension.Header.Version})."); } else if (status.installedGlobally) { Console.WriteLine($" The extension was succesfully installed globally: '{status.installedExtension.InstallPath}'"); } else { Console.WriteLine($" The extension was succesfully installed locally: '{status.installedExtension.InstallPath}'"); } } void Uninstall(IInstalledExtension installedExtension) { extensionManagerService.Uninstall(installedExtension); // Recreate the extensionManagerService to force the extension cache to recreate extensionManagerService?.Close(); extensionManagerService = new ExtensionManagerService(settingsManager); var status = GetInstallStatus(installedExtension.Header); if (status.installed) { var wasInstalledGlobally = IsInstalledGlobally(installedExtension); if (wasInstalledGlobally) { // We should never hit this case, as we shouldn't be passing in gobally installed extensions if (status.installedGlobally) { Environment.ExitCode = GLOBAL_UNINSTALL_FAILED_EXCEPTION_CODE; throw new Exception("The global extension failed to uninstall."); } else { // This should be impossible even if we tried to uninstall a global extension... Environment.ExitCode = LOCAL_UNINSTALL_FAILED_EXCEPTION_CODE; throw new Exception($"The global extension was uninstalled. A local extension still exists: '{status.installedExtension.InstallPath}'"); } } else if (status.installedGlobally) { Console.WriteLine($" The local extension was succesfully uninstalled. A global extension still exists: '{status.installedExtension.InstallPath}'"); } else { throw new Exception("The local extension failed to uninstall."); } } else { Console.WriteLine(" The local extension was succesfully uninstalled."); } } void UninstallAll() { // We only want extensions which are not installed per machine and we want them sorted by their dependencies. var installedExtensions = extensionManagerService.GetInstalledExtensions() .Where((installedExtension) => !IsInstalledGlobally(installedExtension)) .OrderBy((installedExtension) => installedExtension, installedExtensionComparer); foreach (var installedExtension in installedExtensions) { Console.WriteLine($" Uninstalling local extension: '{installedExtension.InstallPath}'"); Uninstall(installedExtension); } } } } } catch (Exception e) when(Environment.ExitCode != 0) { if (Environment.ExitCode < 0) { Console.Error.WriteLine(e); } else { Console.WriteLine(" " + e.Message); } } return(Environment.ExitCode); }
static void Install(string vsExe, IInstallableExtension vsix, string rootSuffix) { using (var esm = ExternalSettingsManager.CreateForApplication(vsExe, rootSuffix)) { var ems = new ExtensionManagerService(esm); var installed = ems.GetInstalledExtensions().FirstOrDefault(x => x.Header.Identifier == vsix.Header.Identifier); if (installed != null) ems.Uninstall(installed); ems.Install(vsix, perMachine: false); } }
static int Main(string[] args) { var app = new CommandLineApplication { Name = "vsix" }; app.HelpOption("-?|-h|--help"); var vsixPath = app.Option( "-f|--vsix", "The path to the vsix to install", CommandOptionType.SingleValue); var version = app.Option( "-v|--version", "The version of VS to install to.", CommandOptionType.SingleValue); var suffix = app.Option( "-s|--suffix", "The Visual Studio root suffix to use.", CommandOptionType.SingleValue); app.OnExecute(() => { if (!vsixPath.HasValue()) { Console.Error.WriteLine("Need to specify the --vsix parameter."); return(1); } if (!File.Exists(vsixPath.Value())) { Console.Error.Write($"Cannot find the vsix at {vsixPath.Value()}"); return(1); } var versionValue = version.HasValue() ? version.Value() : "14.0"; var vsExe = GetVersionExe(versionValue); if (string.IsNullOrEmpty(vsExe)) { Console.Error.WriteLine("Cannot find Visual Studio " + version); return(1); } var suffixValue = suffix.HasValue() ? suffix.Value() : "exp"; var vsixPackage = ExtensionManagerService.CreateInstallableExtension(vsixPath.Value()); Console.Error.WriteLine($"Installing {vsixPackage.Header.Name} version {vsixPackage.Header.Version}"); try { Install(vsExe, vsixPackage, suffixValue); } catch (Exception ex) { Console.Error.WriteLine($"Failed to install extension: {ex.Message}"); return(1); } return(0); }); return(app.Execute(args)); }
public static int Main(string[] args) { if (args.Length == 0) { PrintUsage(); return(0); } var argList = new List <string>(args); var rootSuffix = ExtractArg(argList, "rootSuffix") ?? "Exp"; var uninstall = FindArg(argList, "u"); var uninstallAll = FindArg(argList, "uninstallAll"); var printHelp = FindArg(argList, "?") || FindArg(argList, "h") || FindArg(argList, "help"); var vsInstallDir = ExtractArg(argList, "vsInstallDir") ?? Environment.GetEnvironmentVariable("VsInstallDir"); var expectedArgCount = uninstallAll ? 0 : 1; if (argList.Count != expectedArgCount) { PrintUsage(); return(1); } string vsixPath = uninstallAll ? string.Empty : argList[0]; string devenvPath; try { devenvPath = GetDevenvPath(vsInstallDir); var assemblyResolutionPaths = new string[] { Path.Combine(vsInstallDir, @"Common7\IDE"), Path.Combine(vsInstallDir, @"Common7\IDE\PrivateAssemblies"), Path.Combine(vsInstallDir, @"Common7\IDE\PublicAssemblies") }; AppDomain.CurrentDomain.AssemblyResolve += (object sender, ResolveEventArgs eventArgs) => { var assemblyFileName = $"{eventArgs.Name.Split(',')[0]}.dll"; foreach (var assemblyResolutionPath in assemblyResolutionPaths) { var assemblyFilePath = Path.Combine(assemblyResolutionPath, assemblyFileName); if (File.Exists(assemblyFilePath)) { return(Assembly.LoadFrom(assemblyFilePath)); } } return(null); }; RunProgram(); // Move all of this into a local method so that it only causes the assembly loads after the resolver has been hooked up void RunProgram() { using (var settingsManager = ExternalSettingsManager.CreateForApplication(devenvPath, rootSuffix)) { ExtensionManagerService extensionManagerService = null; try { extensionManagerService = new ExtensionManagerService(settingsManager); if (uninstallAll) { Console.WriteLine("Uninstalling all... "); UninstallAll(extensionManagerService); } else { var extensionManager = (IVsExtensionManager)(extensionManagerService); var vsixToInstall = extensionManager.CreateInstallableExtension(vsixPath); var vsixToInstallHeader = vsixToInstall.Header; var foundBefore = extensionManagerService.TryGetInstalledExtension(vsixToInstallHeader.Identifier, out var installedVsixBefore); var installedGloballyBefore = foundBefore && installedVsixBefore.InstallPath.StartsWith(vsInstallDir, StringComparison.OrdinalIgnoreCase); if (uninstall) { if (foundBefore && !installedGloballyBefore) { Console.WriteLine("Uninstalling {0}... ", vsixPath); extensionManagerService.Uninstall(installedVsixBefore); } else { Console.WriteLine("Nothing to uninstall... "); } } else { if (foundBefore && installedGloballyBefore && (vsixToInstallHeader.Version < installedVsixBefore.Header.Version)) { throw new Exception($"The version you are attempting to install ({vsixToInstallHeader.Version}) has a version that is less than the one installed globally ({installedVsixBefore.Header.Version})."); } else if (foundBefore && !installedGloballyBefore) { Console.WriteLine("Updating {0}... ", vsixPath); extensionManagerService.Uninstall(installedVsixBefore); } else { Console.WriteLine("Installing {0}... ", vsixPath); } extensionManagerService.Install(vsixToInstall, perMachine: false); var settingsStore = settingsManager.GetWritableSettingsStore(SettingsScope.UserSettings); EnableLoadingAllExtensions(settingsStore); RemoveExtensionFromPendingDeletions(settingsStore, vsixToInstallHeader); UpdateLastExtensionsChange(settingsStore); // Recreate the extensionManagerService to force the extension cache to recreate extensionManagerService?.Close(); extensionManagerService = new ExtensionManagerService(settingsManager); var foundAfter = extensionManagerService.TryGetInstalledExtension(vsixToInstallHeader.Identifier, out var installedVsixAfter); var installedGloballyAfter = foundAfter && installedVsixAfter.InstallPath.StartsWith(vsInstallDir, StringComparison.OrdinalIgnoreCase); if (uninstall && foundAfter) { if (installedGloballyBefore && installedGloballyAfter) { throw new Exception($"The extension failed to uninstall. It is still installed globally."); } else if (!installedGloballyBefore && installedGloballyAfter) { Console.WriteLine("The local extension was succesfully uninstalled. However, the global extension is still installed."); } else { Console.WriteLine("The extension was succesfully uninstalled."); } } else if (!uninstall) { if (!foundAfter) { throw new Exception($"The extension failed to install. It could not be located."); } else if (installedVsixAfter.Header.Version != vsixToInstallHeader.Version) { throw new Exception("The extension failed to install. The located version does not match the expected version."); } else { Console.WriteLine("The extension was succesfully installed."); } } } } } finally { extensionManagerService?.Close(); extensionManagerService = null; } Console.WriteLine("Done!"); } } } catch (Exception e) { string message = e.GetType().Name + ": " + e.Message + Environment.NewLine + e.ToString(); Console.Error.WriteLine(message); return(2); } return(0); }