public async Task Start(IProgress<InstallerProgress> progress, Action<string> commandChanged, CancellationToken ct) { await Task.Run(() => { var progressSource = new ProgressSource(); progressSource.Progress += (sender, i) => progress.Report(new InstallerProgress(i)); progressSource.Command += (sender, name) => commandChanged(name); _install(progressSource, ct); }); }
public static void ShowWindow(TimeSpan initialDelay, CancellationToken token, ProgressSource progressSource) { var wnd = default(AnimatedGifWindow); var thread = new Thread(() => { if (token.IsCancellationRequested) return; try { Task.Delay(initialDelay, token).ContinueWith(t => { return true; }).Wait(); } catch (Exception) { return; } wnd = new AnimatedGifWindow(); wnd.Show(); Task.Delay(TimeSpan.FromSeconds(5.0), token).ContinueWith(t => { if (t.IsCanceled) return; wnd.Dispatcher.BeginInvoke(new Action(() => wnd.Topmost = false)); }); token.Register(() => wnd.Dispatcher.BeginInvoke(new Action(wnd.Close))); EventHandler<int> progressSourceOnProgress = ((sender, p) => wnd.Dispatcher.BeginInvoke( new Action(() => wnd.TaskbarItemInfo.ProgressValue = p/100.0))); progressSource.Progress += progressSourceOnProgress; try { (new Application()).Run(wnd); } finally { progressSource.Progress -= progressSourceOnProgress; } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); }
public async Task Install(bool silentInstall, ProgressSource progressSource, string ourAppName, string sourceDirectory) { this.Log().Info("Starting install, writing to {0}", sourceDirectory); 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); mgr.KillAllExecutablesBelongingToPackage(); await Task.Delay(250); 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"); } this.ErrorIfThrows(() => Utility.Retry(() => Directory.CreateDirectory(mgr.RootAppDirectory), 3), "Couldn't create app directory, perhaps Antivirus is blocking it"); var updateTarget = Path.Combine(mgr.RootAppDirectory, "Update.exe"); this.ErrorIfThrows(() => File.Copy(Assembly.GetExecutingAssembly().Location, updateTarget, true), "Failed to copy Update.exe to " + updateTarget); var updateDep = "Update.GUI.dll"; this.ErrorIfThrows(() => File.Copy(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), updateDep), Path.Combine(mgr.RootAppDirectory, updateDep), true), "Failed to copy " + updateDep + " to " + updateTarget); await mgr.FullInstall(silentInstall, progressSource); await this.ErrorIfThrows(() => mgr.CreateUninstallerRegistryEntry(), "Failed to create uninstaller registry entry"); } }
int executeCommandLine(string[] args) { var animatedGifWindowToken = new CancellationTokenSource(); #if !MONO // Uncomment to test Gifs /* * var ps = new ProgressSource(); * int i = 0; var t = new Timer(_ => ps.Raise(i += 10), null, 0, 1000); * AnimatedGifWindow.ShowWindow(TimeSpan.FromMilliseconds(0), animatedGifWindowToken.Token, ps); * Thread.Sleep(10 * 60 * 1000); */ #endif 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); string frameworkVersion = "net45"; bool shouldWait = false; bool noMsi = (Environment.OSVersion.Platform != PlatformID.Win32NT); // NB: WiX doesn't work under Mono / Wine bool noDelta = 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; } }, { "checkForUpdate=", "Check for one available update and writes new results to stdout as JSON", v => { updateAction = UpdateAction.CheckForUpdate; 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 }, { "no-msi", "Don't generate an MSI package", v => noMsi = true }, { "no-delta", "Don't generate delta packages to save time", v => noDelta = true }, { "framework-version=", "Set the required .NET framework version, e.g. net461", v => frameworkVersion = 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) { #if !MONO 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.CheckForUpdate: Console.WriteLine(CheckForUpdate(target).Result); break; case UpdateAction.UpdateSelf: UpdateSelf().Wait(); 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; #endif case UpdateAction.Releasify: Releasify(target, releaseDir, packagesDir, bootstrapperExe, backgroundGif, signingParameters, baseUrl, setupIcon, !noMsi, frameworkVersion, !noDelta); break; } } return(0); }
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 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=|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); 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(target).Wait(); break; case UpdateAction.Releasify: Releasify(target, releaseDir, packagesDir, bootstrapperExe, backgroundGif, signingParameters, baseUrl, setupIcon); break; case UpdateAction.Shortcut: Shortcut(target, shortcutArgs); break; case UpdateAction.Deshortcut: Deshortcut(target, shortcutArgs); break; case UpdateAction.ProcessStart: ProcessStart(processStart, processStartArgs, shouldWait); break; } } return(0); }
int executeCommandLine(string[] args) { var animatedGifWindowToken = new CancellationTokenSource(); #if !MONO // Uncomment to test Gifs /* * var ps = new ProgressSource(); * int i = 0; var t = new Timer(_ => ps.Raise(i += 10), null, 0, 1000); * AnimatedGifWindow.ShowWindow(TimeSpan.FromMilliseconds(0), animatedGifWindowToken.Token, ps); * Thread.Sleep(10 * 60 * 1000); */ #endif 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); } if (opt.updateAction == UpdateAction.Unset) { var message = "Update.exe called with no recognized command. Arguments were " + string.Join(" ", args); if (NativeMethods.GetConsoleWindow() != IntPtr.Zero) { // already have a console, run from command line, don't UI. Console.WriteLine(message); ShowHelp(); } else { #if !MONO // Enhance: if we want our version to work in Mono we'll need to reference something that supports this MessageBox.Show(message); #endif } return(-1); } if (opt.unknownArgs.Any()) { var message = "Update.exe called with unexpected arguments: " + string.Join(" ", opt.unknownArgs) + ". Full arguments were " + string.Join(" ", args); if (NativeMethods.GetConsoleWindow() != IntPtr.Zero) { // already have a console, run from command line, don't UI. Console.WriteLine(message); ShowHelp(); } else { #if !MONO // Enhance: if we want our version to work in Mono we'll need to reference something that supports this MessageBox.Show(message); #endif } return(-1); } switch (opt.updateAction) { #if !MONO case UpdateAction.Install: var progressSource = new ProgressSource(); if (!opt.silentInstall) { AnimatedGifWindow.ShowWindow(TimeSpan.FromSeconds(0), animatedGifWindowToken.Token, progressSource); } // If we get allUsers we do NOT want to launch the program (running as admin!) afterwards. Passing silent here // will prevent that and has no other effects. Install(opt.silentInstall || opt.allUsers, progressSource, Path.GetFullPath(opt.target)).Wait(); animatedGifWindowToken.Cancel(); break; case UpdateAction.Uninstall: Uninstall().Wait(); break; case UpdateAction.Download: Console.WriteLine(Download(opt.target).Result); break; case UpdateAction.Update: Update(opt.target).Wait(); break; case UpdateAction.CheckForUpdate: Console.WriteLine(CheckForUpdate(opt.target).Result); break; case UpdateAction.UpdateSelf: UpdateSelf().Wait(); break; case UpdateAction.Shortcut: Shortcut(opt.target, opt.shortcutArgs, opt.processStartArgs, opt.setupIcon); break; case UpdateAction.Deshortcut: Deshortcut(opt.target, opt.shortcutArgs); break; case UpdateAction.ProcessStart: ProcessStart(opt.processStart, opt.processStartArgs, opt.shouldWait); break; #endif case UpdateAction.Releasify: return(Releasify(opt.target, opt.releaseDir, opt.packagesDir, opt.bootstrapperExe, opt.backgroundGif, opt.signingParameters, opt.baseUrl, opt.setupIcon, !opt.noMsi, opt.packageAs64Bit, opt.frameworkVersion, !opt.noDelta)); } } this.Log().Info("Finished Squirrel Updater"); return(0); }
public static void ShowWindow(TimeSpan initialDelay, CancellationToken token, ProgressSource progressSource) { var thread = new Thread(() => { if (token.IsCancellationRequested) { return; } try { Task.Delay(initialDelay, token).ContinueWith(_ => { return(true); }).Wait(); } catch (Exception) { // NB: Cancellation will end up here, so we'll bail out return; } var wnd = new AnimatedGifWindow(); if (token.IsCancellationRequested) { return; } try { wnd.Show(); } catch (Exception) { return; } token.Register(() => wnd.Invoke(new Action(() => wnd.Close()))); var t = new System.Windows.Forms.Timer(); var taskbar = TaskbarManager.Instance; t.Tick += (o, e) => { wnd.WindowState = FormWindowState.Normal; taskbar.SetProgressState(TaskbarProgressBarState.Normal, wnd.Handle); progressSource.Progress += (_o, val) => { if (wnd.IsDisposed) { return; } wnd.Invoke(new Action(() => taskbar.SetProgressValue(val, 100, wnd.Handle))); }; t.Stop(); }; t.Interval = 400; t.Start(); Task.Delay(TimeSpan.FromSeconds(5.0), token).ContinueWith(task => { if (task.IsCanceled) { return; } if (wnd.IsDisposed) { return; } wnd.Invoke(new Action(() => wnd.TopMost = false)); }); if (token.IsCancellationRequested) { return; } #if !DEBUG try { #endif Application.Run(wnd); #if !DEBUG } catch (Exception) { return; } #endif }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); }
public static void ShowWindow(TimeSpan initialDelay, CancellationToken token, ProgressSource progressSource) { var wnd = default(AnimatedGifWindow); var thread = new Thread(() => { if (token.IsCancellationRequested) { return; } if (!Equals(initialDelay, TimeSpan.Zero)) { try { Task.Delay(initialDelay, token).ContinueWith(t => { return(true); }).Wait(); } catch (Exception) { return; } } wnd = new AnimatedGifWindow(); wnd.Show(); Task.Delay(TimeSpan.FromSeconds(5.0), token).ContinueWith(t => { if (t.IsCanceled) { return; } wnd.Dispatcher.BeginInvoke(new Action(() => wnd.Topmost = false)); }); token.Register(() => wnd.Dispatcher.BeginInvoke(new Action(wnd.Close))); EventHandler <int> progressSourceOnProgress = ((sender, p) => wnd.Dispatcher.BeginInvoke( new Action(() => wnd.TaskbarItemInfo.ProgressValue = p / 100.0))); progressSource.Progress += progressSourceOnProgress; try { (new Application()).Run(wnd); } finally { progressSource.Progress -= progressSourceOnProgress; } }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); }
int executeCommandLine(string[] args) { var animatedGifWindowToken = new CancellationTokenSource(); #if !MONO // Uncomment to test Gifs /* * var ps = new ProgressSource(); * int i = 0; var t = new Timer(_ => ps.Raise(i += 10), null, 0, 1000); * AnimatedGifWindow.ShowWindow(TimeSpan.FromMilliseconds(0), animatedGifWindowToken.Token, ps); * Thread.Sleep(10 * 60 * 1000); */ #endif 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); } if (opt.updateAction == UpdateAction.Unset) { ShowHelp(); return(-1); } switch (opt.updateAction) { #if !MONO case UpdateAction.Install: var progressSource = new ProgressSource(); if (!opt.silentInstall) { AnimatedGifWindow.ShowWindow(TimeSpan.FromSeconds(4), animatedGifWindowToken.Token, progressSource); } Install(opt.silentInstall, progressSource, Path.GetFullPath(opt.target)).Wait(); animatedGifWindowToken.Cancel(); break; case UpdateAction.Uninstall: Uninstall().Wait(); break; case UpdateAction.Download: Console.WriteLine(Download(opt.target).Result); break; case UpdateAction.Update: Update(opt.target).Wait(); break; case UpdateAction.CheckForUpdate: Console.WriteLine(CheckForUpdate(opt.target).Result); break; case UpdateAction.UpdateSelf: UpdateSelf().Wait(); break; case UpdateAction.Shortcut: Shortcut(opt.target, opt.shortcutArgs, opt.processStartArgs, opt.setupIcon); break; case UpdateAction.Deshortcut: Deshortcut(opt.target, opt.shortcutArgs); break; case UpdateAction.ProcessStart: ProcessStart(opt.processStart, opt.processStartArgs, opt.shouldWait); break; #endif case UpdateAction.Releasify: Releasify(opt.target, opt.releaseDir, opt.packagesDir, opt.licenseDir, opt.bootstrapperExe, opt.backgroundGif, opt.signingParameters, opt.baseUrl, opt.setupIcon, !opt.noMsi, opt.packageAs64Bit, opt.frameworkVersion, !opt.noDelta); break; } } this.Log().Info("Finished Squirrel Updater"); return(0); }
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; bool noMsi = (Environment.OSVersion.Platform != PlatformID.Win32NT); // NB: WiX doesn't work under Mono / Wine bool allUsers = 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; } }, { "checkForUpdate=", "Check for one available update and writes new results to stdout as JSON", v => { updateAction = UpdateAction.CheckForUpdate; 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 }, { "no-msi", "Don't generate an MSI package", v => noMsi = true }, { "allUsers", "Install for all users in Program files (x86); requires admin privileges; no updates", _ => allUsers = true }, { "rerunningWithoutUAC", "Ignored...passed when master installer accidentally run from admin prompt", _ => {} } }; var unknownArgs = 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) { var message = "Update.exe called with no recognized command. Arguments were " + string.Join(" ", args); if (NativeMethods.GetConsoleWindow() != IntPtr.Zero) { // already have a console, run from command line, don't UI. Console.WriteLine(message); ShowHelp(); } else { MessageBox.Show(message); } return(-1); } if (unknownArgs.Any()) { var message = "Update.exe called with unexpected arguments: " + string.Join(" ", unknownArgs) + ". Full arguments were " + string.Join(" ", args); if (NativeMethods.GetConsoleWindow() != IntPtr.Zero) { // already have a console, run from command line, don't UI. Console.WriteLine(message); ShowHelp(); } else { MessageBox.Show(message); } return(-1); } switch (updateAction) { #if !MONO case UpdateAction.Install: var progressSource = new ProgressSource(); if (!silentInstall) { AnimatedGifWindow.ShowWindow(TimeSpan.FromSeconds(0), animatedGifWindowToken.Token, progressSource); } // If we get allUsers we do NOT want to launch the program (running as admin!) afterwards. Passing silent here // will prevent that and has no other effects. Install(silentInstall || allUsers, 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.CheckForUpdate: Console.WriteLine(CheckForUpdate(target).Result); break; case UpdateAction.UpdateSelf: UpdateSelf().Wait(); 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; #endif case UpdateAction.Releasify: return(Releasify(target, releaseDir, packagesDir, bootstrapperExe, backgroundGif, signingParameters, baseUrl, setupIcon, !noMsi)); } } return(0); }
public static void ShowWindow(TimeSpan initialDelay, CancellationToken token, ProgressSource progressSource) { AnimatedGifWindow wnd = null; Thread thread1 = new Thread(delegate { if (!token.IsCancellationRequested) { EventHandler <int> < > 9__5; Action < > 9__4; Action <Task> < > 9__2; try { Task.Delay(initialDelay, token).ContinueWith <bool>(t => true).Wait(); } catch (Exception) { return; } wnd = new AnimatedGifWindow(); wnd.Show(); Action <Task> continuationAction = < > 9__2; if (< > 9__2 == null) { Action <Task> local3 = < > 9__2; continuationAction = < > 9__2 = delegate(Task t) { if (!t.IsCanceled) { Action < > 9__3; Action method = < > 9__3; if (< > 9__3 == null) { Action local1 = < > 9__3; method = < > 9__3 = () => wnd.Topmost = false; } wnd.Dispatcher.BeginInvoke(method, new object[0]); } }; } Task.Delay(TimeSpan.FromSeconds(5.0), token).ContinueWith(continuationAction); Action callback = < > 9__4; if (< > 9__4 == null) { Action local4 = < > 9__4; callback = < > 9__4 = () => wnd.Dispatcher.BeginInvoke(new Action(wnd.Close), new object[0]); } token.Register(callback); EventHandler <int> handler3 = < > 9__5; if (< > 9__5 == null) { EventHandler <int> local5 = < > 9__5; handler3 = < > 9__5 = (sender, p) => wnd.Dispatcher.BeginInvoke(() => wnd.get_TaskbarItemInfo().set_ProgressValue(((double)p) / 100.0), new object[0]); } EventHandler <int> handler = handler3; progressSource.Progress += handler; try { new Application().Run(wnd); } finally { progressSource.Progress -= handler; } } });
public static void ShowWindow(TimeSpan initialDelay, CancellationToken token, ProgressSource progressSource) { }