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");
            }
        }
Exemple #4
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);
                }

                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);
        }
Exemple #5
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);
        }
Exemple #6
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);
        }
Exemple #7
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();
        }
Exemple #8
0
        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();
        }
Exemple #9
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)
                {
                    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);
        }
Exemple #11
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;
             }
         }
     });
Exemple #12
0
 public static void ShowWindow(TimeSpan initialDelay, CancellationToken token, ProgressSource progressSource)
 {
 }