int executeCommandLine(string[] args) { var animatedGifWindowToken = new CancellationTokenSource(); using (Disposable.Create(() => animatedGifWindowToken.Cancel())) { this.Log().Info("Starting Squirrel Updater: " + String.Join(" ", args)); if (args.Any(x => x.StartsWith("/squirrel", StringComparison.OrdinalIgnoreCase))) { // NB: We're marked as Squirrel-aware, but we don't want to do // anything in response to these events return 0; } bool silentInstall = false; var updateAction = default(UpdateAction); string target = default(string); string releaseDir = default(string); string packagesDir = default(string); string bootstrapperExe = default(string); string backgroundGif = default(string); string signingParameters = default(string); string baseUrl = default(string); string processStart = default(string); string processStartArgs = default(string); string setupIcon = default(string); string icon = default(string); string shortcutArgs = default(string); bool shouldWait = false; opts = new OptionSet() { "Usage: Squirrel.exe command [OPTS]", "Manages Squirrel packages", "", "Commands", { "install=", "Install the app whose package is in the specified directory", v => { updateAction = UpdateAction.Install; target = v; } }, { "uninstall", "Uninstall the app the same dir as Update.exe", v => updateAction = UpdateAction.Uninstall}, { "download=", "Download the releases specified by the URL and write new results to stdout as JSON", v => { updateAction = UpdateAction.Download; target = v; } }, { "update=", "Update the application to the latest remote version specified by URL", v => { updateAction = UpdateAction.Update; target = v; } }, { "releasify=", "Update or generate a releases directory with a given NuGet package", v => { updateAction = UpdateAction.Releasify; target = v; } }, { "createShortcut=", "Create a shortcut for the given executable name", v => { updateAction = UpdateAction.Shortcut; target = v; } }, { "removeShortcut=", "Remove a shortcut for the given executable name", v => { updateAction = UpdateAction.Deshortcut; target = v; } }, { "updateSelf=", "Copy the currently executing Update.exe into the default location", v => { updateAction = UpdateAction.UpdateSelf; target = v; } }, { "processStart=", "Start an executable in the latest version of the app package", v => { updateAction = UpdateAction.ProcessStart; processStart = v; }, true}, { "processStartAndWait=", "Start an executable in the latest version of the app package", v => { updateAction = UpdateAction.ProcessStart; processStart = v; shouldWait = true; }, true}, "", "Options:", { "h|?|help", "Display Help and exit", _ => {} }, { "r=|releaseDir=", "Path to a release directory to use with releasify", v => releaseDir = v}, { "p=|packagesDir=", "Path to the NuGet Packages directory for C# apps", v => packagesDir = v}, { "bootstrapperExe=", "Path to the Setup.exe to use as a template", v => bootstrapperExe = v}, { "g=|loadingGif=", "Path to an animated GIF to be displayed during installation", v => backgroundGif = v}, { "i=|icon", "Path to an ICO file that will be used for icon shortcuts", v => icon = v}, { "setupIcon=", "Path to an ICO file that will be used for the Setup executable's icon", v => setupIcon = v}, { "n=|signWithParams=", "Sign the installer via SignTool.exe with the parameters given", v => signingParameters = v}, { "s|silent", "Silent install", _ => silentInstall = true}, { "b=|baseUrl=", "Provides a base URL to prefix the RELEASES file packages with", v => baseUrl = v, true}, { "a=|process-start-args=", "Arguments that will be used when starting executable", v => processStartArgs = v, true}, { "l=|shortcut-locations=", "Comma-separated string of shortcut locations, e.g. 'Desktop,StartMenu'", v => shortcutArgs = v}, }; opts.Parse(args); // NB: setupIcon and icon are just aliases for compatibility // reasons, because of a dumb breaking rename I made in 1.0.1 setupIcon = setupIcon ?? icon; if (updateAction == UpdateAction.Unset) { ShowHelp(); return -1; } switch (updateAction) { case UpdateAction.Install: var progressSource = new ProgressSource(); if (!silentInstall) { AnimatedGifWindow.ShowWindow(TimeSpan.FromSeconds(4), animatedGifWindowToken.Token, progressSource); } Install(silentInstall, progressSource, Path.GetFullPath(target)).Wait(); animatedGifWindowToken.Cancel(); break; case UpdateAction.Uninstall: Uninstall().Wait(); break; case UpdateAction.Download: Console.WriteLine(Download(target).Result); break; case UpdateAction.Update: Update(target).Wait(); break; case UpdateAction.UpdateSelf: UpdateSelf().Wait(); break; case UpdateAction.Releasify: Releasify(target, releaseDir, packagesDir, bootstrapperExe, backgroundGif, signingParameters, baseUrl, setupIcon); break; case UpdateAction.Shortcut: Shortcut(target, shortcutArgs, processStartArgs, setupIcon); break; case UpdateAction.Deshortcut: Deshortcut(target, shortcutArgs); break; case UpdateAction.ProcessStart: ProcessStart(processStart, processStartArgs, shouldWait); break; } } return 0; }
public async Task Install(bool silentInstall, ProgressSource progressSource, string sourceDirectory = null) { sourceDirectory = sourceDirectory ?? Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var releasesPath = Path.Combine(sourceDirectory, "RELEASES"); this.Log().Info("Starting install, writing to {0}", sourceDirectory); if (!File.Exists(releasesPath)) { this.Log().Info("RELEASES doesn't exist, creating it at " + releasesPath); var nupkgs = (new DirectoryInfo(sourceDirectory)).GetFiles() .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase)) .Select(x => ReleaseEntry.GenerateFromFile(x.FullName)); ReleaseEntry.WriteReleaseFile(nupkgs, releasesPath); } var ourAppName = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releasesPath, Encoding.UTF8)) .First().PackageName; var rootDir = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); using (var mgr = new UpdateManager(sourceDirectory, ourAppName, FrameworkVersion.Net45, rootDir)) { Directory.CreateDirectory(mgr.RootAppDirectory); var updateTarget = Path.Combine(mgr.RootAppDirectory, "Update.exe"); this.ErrorIfThrows(() => File.Copy(Assembly.GetExecutingAssembly().Location, updateTarget, true), "Failed to copy Update.exe to " + updateTarget); await mgr.FullInstall(silentInstall, progressSource.Raise); await this.ErrorIfThrows(() => mgr.CreateUninstallerRegistryEntry(), "Failed to create uninstaller registry entry"); } }
public async Task Install(bool silentInstall, ProgressSource progressSource, string sourceDirectory = null) { sourceDirectory = sourceDirectory ?? Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var releasesPath = Path.Combine(sourceDirectory, "RELEASES"); this.Log().Info("Starting install, writing to {0}", sourceDirectory); if (!File.Exists(releasesPath)) { this.Log().Info("RELEASES doesn't exist, creating it at " + releasesPath); var nupkgs = (new DirectoryInfo(sourceDirectory)).GetFiles() .Where(x => x.Name.EndsWith(".nupkg", StringComparison.OrdinalIgnoreCase)) .Select(x => ReleaseEntry.GenerateFromFile(x.FullName)); ReleaseEntry.WriteReleaseFile(nupkgs, releasesPath); } var ourAppName = ReleaseEntry.ParseReleaseFile(File.ReadAllText(releasesPath, Encoding.UTF8)) .First().PackageName; using (var mgr = new UpdateManager(sourceDirectory, ourAppName)) { this.Log().Info("About to install to: " + mgr.RootAppDirectory); if (Directory.Exists(mgr.RootAppDirectory)) { this.Log().Warn("Install path {0} already exists, burning it to the ground", mgr.RootAppDirectory); await this.ErrorIfThrows(() => Utility.DeleteDirectory(mgr.RootAppDirectory), "Failed to remove existing directory on full install, is the app still running???"); this.ErrorIfThrows(() => Utility.Retry(() => Directory.CreateDirectory(mgr.RootAppDirectory), 3), "Couldn't recreate app directory, perhaps Antivirus is blocking it"); } Directory.CreateDirectory(mgr.RootAppDirectory); var updateTarget = Path.Combine(mgr.RootAppDirectory, "Update.exe"); this.ErrorIfThrows(() => File.Copy(Assembly.GetExecutingAssembly().Location, updateTarget, true), "Failed to copy Update.exe to " + updateTarget); await mgr.FullInstall(silentInstall, progressSource.Raise); await this.ErrorIfThrows(() => mgr.CreateUninstallerRegistryEntry(), "Failed to create uninstaller registry entry"); } }
// Use this for initialization void Start() { _ProgressSource = progressSource as ProgressSource; }