public void RemoveShortcutsForExecutable(string exeName, ShortcutLocation locations)
            {
                var releases    = Utility.LoadLocalReleases(Utility.LocalReleaseFileForAppDir(rootAppDirectory));
                var thisRelease = Utility.FindCurrentVersion(releases);

                var zf = new ZipPackage(Path.Combine(
                                            Utility.PackageDirectoryForAppDir(rootAppDirectory),
                                            thisRelease.Filename));

                var fileVerInfo = FileVersionInfo.GetVersionInfo(
                    Path.Combine(Utility.AppDirForRelease(rootAppDirectory, thisRelease), exeName));

                foreach (var f in (ShortcutLocation[])Enum.GetValues(typeof(ShortcutLocation)))
                {
                    if (!locations.HasFlag(f))
                    {
                        continue;
                    }

                    var file = linkTargetForVersionInfo(f, zf, fileVerInfo);

                    this.Log().Info("Removing shortcut for {0} => {1}", exeName, file);

                    this.ErrorIfThrows(() => {
                        if (File.Exists(file))
                        {
                            File.Delete(file);
                        }
                    }, "Couldn't delete shortcut: " + file);
                }

                fixPinnedExecutables(zf.Version);
            }
            public void CreateShortcutsForExecutable(string exeName, ShortcutLocation locations, bool updateOnly)
            {
                var releases    = Utility.LoadLocalReleases(Utility.LocalReleaseFileForAppDir(rootAppDirectory));
                var thisRelease = Utility.FindCurrentVersion(releases);

                var zf = new ZipPackage(Path.Combine(
                                            Utility.PackageDirectoryForAppDir(rootAppDirectory),
                                            thisRelease.Filename));

                var exePath     = Path.Combine(Utility.AppDirForRelease(rootAppDirectory, thisRelease), exeName);
                var fileVerInfo = FileVersionInfo.GetVersionInfo(exePath);

                foreach (var f in (ShortcutLocation[])Enum.GetValues(typeof(ShortcutLocation)))
                {
                    if (!locations.HasFlag(f))
                    {
                        continue;
                    }

                    var file       = linkTargetForVersionInfo(f, zf, fileVerInfo);
                    var fileExists = File.Exists(file);

                    // NB: If we've already installed the app, but the shortcut
                    // is no longer there, we have to assume that the user didn't
                    // want it there and explicitly deleted it, so we shouldn't
                    // annoy them by recreating it.
                    if (!fileExists && updateOnly)
                    {
                        this.Log().Warn("Wanted to update shortcut {0} but it appears user deleted it", file);
                        continue;
                    }

                    this.Log().Info("Creating shortcut for {0} => {1}", exeName, file);

                    this.ErrorIfThrows(() => {
                        if (fileExists)
                        {
                            File.Delete(file);
                        }

                        var sl = new ShellLink {
                            Target           = exePath,
                            IconPath         = exePath,
                            IconIndex        = 0,
                            WorkingDirectory = Path.GetDirectoryName(exePath),
                            Description      = zf.Description,
                        };

                        this.Log().Info("About to save shortcut: {0}", file);
                        if (ModeDetector.InUnitTestRunner() == false)
                        {
                            sl.Save(file);
                        }
                    }, "Can't write shortcut: " + file);
                }
            }
            public Dictionary <ShortcutLocation, ShellLink> GetShortcutsForExecutable(string exeName, ShortcutLocation locations, string programArguments)
            {
                this.Log().Info("About to create shortcuts for {0}, rootAppDir {1}", exeName, rootAppDirectory);

                var releases    = Utility.LoadLocalReleases(Utility.LocalReleaseFileForAppDir(rootAppDirectory));
                var thisRelease = Utility.FindCurrentVersion(releases);

                var zf = new ZipPackage(Path.Combine(
                                            Utility.PackageDirectoryForAppDir(rootAppDirectory),
                                            thisRelease.Filename));

                var exePath     = Path.Combine(Utility.AppDirForRelease(rootAppDirectory, thisRelease), exeName);
                var fileVerInfo = FileVersionInfo.GetVersionInfo(exePath);

                var ret = new Dictionary <ShortcutLocation, ShellLink>();

                foreach (var f in (ShortcutLocation[])Enum.GetValues(typeof(ShortcutLocation)))
                {
                    if (!locations.HasFlag(f))
                    {
                        continue;
                    }

                    var file                 = linkTargetForVersionInfo(f, zf, fileVerInfo);
                    var appUserModelId       = String.Format("com.squirrel.{0}.{1}", zf.Id.Replace(" ", ""), exeName.Replace(".exe", "").Replace(" ", ""));
                    var toastActivatorCLSDID = Utility.CreateGuidFromHash(appUserModelId).ToString();

                    this.Log().Info("Creating shortcut for {0} => {1}", exeName, file);
                    this.Log().Info("appUserModelId: {0} | toastActivatorCLSID: {1}", appUserModelId, toastActivatorCLSDID);

                    var target = Path.Combine(rootAppDirectory, exeName);
                    var sl     = new ShellLink
                    {
                        Target           = target,
                        IconPath         = target,
                        IconIndex        = 0,
                        WorkingDirectory = Path.GetDirectoryName(exePath),
                        Description      = zf.Description,
                    };

                    if (!String.IsNullOrWhiteSpace(programArguments))
                    {
                        sl.Arguments += String.Format(" -a \"{0}\"", programArguments);
                    }

                    sl.SetAppUserModelId(appUserModelId);
                    sl.SetToastActivatorCLSID(toastActivatorCLSDID);

                    ret.Add(f, sl);
                }

                return(ret);
            }
Ejemplo n.º 4
0
            public Dictionary <ShortcutLocation, ShellLink> GetShortcutsForExecutable(string exeName, ShortcutLocation locations, string programArguments)
            {
                this.Log().Info("About to create shortcuts for {0}, rootAppDir {1}", exeName, rootAppDirectory);

                var releases    = Utility.LoadLocalReleases(Utility.LocalReleaseFileForAppDir(rootAppDirectory));
                var thisRelease = Utility.FindCurrentVersion(releases);
                var updateExe   = Path.Combine(rootAppDirectory, "update.exe");

                var zf = new ZipPackage(Path.Combine(
                                            Utility.PackageDirectoryForAppDir(rootAppDirectory),
                                            thisRelease.Filename));

                var exePath     = Path.Combine(Utility.AppDirForRelease(rootAppDirectory, thisRelease), exeName);
                var fileVerInfo = FileVersionInfo.GetVersionInfo(exePath);

                var ret = new Dictionary <ShortcutLocation, ShellLink>();

                foreach (var f in (ShortcutLocation[])Enum.GetValues(typeof(ShortcutLocation)))
                {
                    if (!locations.HasFlag(f))
                    {
                        continue;
                    }

                    var file = linkTargetForVersionInfo(f, zf, fileVerInfo);

                    this.Log().Info("Creating shortcut for {0} => {1}", exeName, file);

                    ShellLink sl;
                    sl = new ShellLink {
                        Target           = updateExe,
                        IconPath         = exePath,
                        IconIndex        = 0,
                        WorkingDirectory = Path.GetDirectoryName(exePath),
                        Description      = zf.Description,
                        Arguments        = "--processStart " + exeName,
                    };

                    if (!String.IsNullOrWhiteSpace(programArguments))
                    {
                        sl.Arguments += String.Format(" -a \"{0}\"", programArguments);
                    }

                    sl.SetAppUserModelId(String.Format("com.squirrel.{0}.{1}", zf.Id, exeName.Replace(".exe", "")));
                    sl.SetAppUserModelRelaunchCommand(String.Format("{0} {1}", sl.Target, sl.Arguments));
                    ret.Add(f, sl);
                }

                return(ret);
            }
Ejemplo n.º 5
0
            public async Task <UpdateInfo> CheckForUpdate(
                string localReleaseFile,
                string updateUrlOrPath,
                bool ignoreDeltaUpdates       = false,
                Action <int> progress         = null,
                IFileDownloader urlDownloader = null)
            {
                progress = progress ?? (_ => { });

                var localReleases = Enumerable.Empty <ReleaseEntry>();

                bool shouldInitialize = false;

                try {
                    localReleases = Utility.LoadLocalReleases(localReleaseFile);
                } catch (Exception ex) {
                    // Something has gone pear-shaped, let's start from scratch
                    this.Log().WarnException("Failed to load local releases, starting from scratch", ex);
                    shouldInitialize = true;
                }

                if (shouldInitialize)
                {
                    await initializeClientAppDirectory();
                }

                string releaseFile;

                var latestLocalRelease = localReleases.Count() > 0 ?
                                         localReleases.MaxBy(x => x.Version).First() :
                                         default(ReleaseEntry);

                // Fetch the remote RELEASES file, whether it's a local dir or an
                // HTTP URL
                if (Utility.IsHttpUrl(updateUrlOrPath))
                {
                    if (updateUrlOrPath.EndsWith("/"))
                    {
                        updateUrlOrPath = updateUrlOrPath.Substring(0, updateUrlOrPath.Length - 1);
                    }

                    this.Log().Info("Downloading RELEASES file from {0}", updateUrlOrPath);

                    int retries = 3;

retry:

                    try {
                        var url = String.Format("{0}/{1}", updateUrlOrPath, "RELEASES");
                        if (latestLocalRelease != null)
                        {
                            url = String.Format("{0}/RELEASES?id={1}&localVersion={2}&arch={3}",
                                                updateUrlOrPath,
                                                Uri.EscapeUriString(latestLocalRelease.PackageName),
                                                Uri.EscapeUriString(latestLocalRelease.Version.ToString()),
                                                Environment.Is64BitOperatingSystem ? "amd64" : "x86");
                        }

                        var data = await urlDownloader.DownloadUrl(url);

                        releaseFile = Encoding.UTF8.GetString(data);
                    } catch (WebException ex) {
                        this.Log().InfoException("Download resulted in WebException (returning blank release list)", ex);

                        if (retries <= 0)
                        {
                            throw;
                        }
                        retries--;
                        goto retry;
                    }

                    progress(33);
                }
                else
                {
                    this.Log().Info("Reading RELEASES file from {0}", updateUrlOrPath);

                    if (!Directory.Exists(updateUrlOrPath))
                    {
                        var message = String.Format(
                            "The directory {0} does not exist, something is probably broken with your application",
                            updateUrlOrPath);

                        throw new Exception(message);
                    }

                    var fi = new FileInfo(Path.Combine(updateUrlOrPath, "RELEASES"));
                    if (!fi.Exists)
                    {
                        var message = String.Format(
                            "The file {0} does not exist, something is probably broken with your application",
                            fi.FullName);

                        this.Log().Warn(message);

                        var packages = (new DirectoryInfo(updateUrlOrPath)).GetFiles("*.nupkg");
                        if (packages.Length == 0)
                        {
                            throw new Exception(message);
                        }

                        // NB: Create a new RELEASES file since we've got a directory of packages
                        ReleaseEntry.WriteReleaseFile(
                            packages.Select(x => ReleaseEntry.GenerateFromFile(x.FullName)), fi.FullName);
                    }

                    releaseFile = File.ReadAllText(fi.FullName, Encoding.UTF8);
                    progress(33);
                }

                var ret            = default(UpdateInfo);
                var remoteReleases = ReleaseEntry.ParseReleaseFile(releaseFile);

                progress(66);

                if (!remoteReleases.Any())
                {
                    throw new Exception("Remote release File is empty or corrupted");
                }

                ret = determineUpdateInfo(localReleases, remoteReleases, ignoreDeltaUpdates);

                progress(100);
                return(ret);
            }
            public void CreateShortcutsForExecutable(string exeName, ShortcutLocation locations, bool updateOnly, string programArguments, string icon)
            {
                this.Log().Info("About to create shortcuts for {0}, rootAppDir {1}", exeName, rootAppDirectory);

                var releases    = Utility.LoadLocalReleases(Utility.LocalReleaseFileForAppDir(rootAppDirectory));
                var thisRelease = Utility.FindCurrentVersion(releases);

                var zf = new ZipPackage(Path.Combine(
                                            Utility.PackageDirectoryForAppDir(rootAppDirectory),
                                            thisRelease.Filename));

                var exePath     = Path.Combine(Utility.AppDirForRelease(rootAppDirectory, thisRelease), exeName);
                var fileVerInfo = FileVersionInfo.GetVersionInfo(exePath);

                foreach (var f in (ShortcutLocation[])Enum.GetValues(typeof(ShortcutLocation)))
                {
                    if (!locations.HasFlag(f))
                    {
                        continue;
                    }

                    var file       = linkTargetForVersionInfo(f, zf, fileVerInfo);
                    var fileExists = File.Exists(file);

                    // NB: If we've already installed the app, but the shortcut
                    // is no longer there, we have to assume that the user didn't
                    // want it there and explicitly deleted it, so we shouldn't
                    // annoy them by recreating it.
                    if (!fileExists && updateOnly)
                    {
                        this.Log().Warn("Wanted to update shortcut {0} but it appears user deleted it", file);
                        continue;
                    }

                    this.Log().Info("Creating shortcut for {0} => {1}", exeName, file);

                    ShellLink sl;
                    this.ErrorIfThrows(() => Utility.Retry(() => {
                        File.Delete(file);

                        var target = Path.Combine(rootAppDirectory, exeName);
                        sl         = new ShellLink {
                            Target           = target,
                            IconPath         = icon ?? target,
                            IconIndex        = 0,
                            WorkingDirectory = Path.GetDirectoryName(exePath),
                            Description      = zf.Description,
                        };

                        if (!String.IsNullOrWhiteSpace(programArguments))
                        {
                            sl.Arguments += String.Format(" -a \"{0}\"", programArguments);
                        }

                        var appUserModelId      = String.Format("com.squirrel.{0}.{1}", zf.Id.Replace(" ", ""), exeName.Replace(".exe", "").Replace(" ", ""));
                        var toastActivatorCLSID = Utility.CreateGuidFromHash(appUserModelId).ToString();

                        sl.SetAppUserModelId(appUserModelId);
                        sl.SetToastActivatorCLSID(toastActivatorCLSID);

                        this.Log().Info("About to save shortcut: {0} (target {1}, workingDir {2}, args {3}, toastActivatorCSLID {4})", file, sl.Target, sl.WorkingDirectory, sl.Arguments, toastActivatorCLSID);
                        if (ModeDetector.InUnitTestRunner() == false)
                        {
                            sl.Save(file);
                        }
                    }, 4), "Can't write shortcut: " + file);
                }

                fixPinnedExecutables(zf.Version);
            }
Ejemplo n.º 7
0
            public async Task <UpdateInfo> CheckForUpdate(
                string localReleaseFile,
                string updateUrlOrPath,
                bool ignoreDeltaUpdates       = false,
                Action <int> progress         = null,
                IFileDownloader urlDownloader = null,
                bool startOverIfNone          = false)
            {
                progress = progress ?? (_ => { });

                var localReleases = Enumerable.Empty <ReleaseEntry>();

                bool shouldInitialize = false;

                try {
                    localReleases = Utility.LoadLocalReleases(localReleaseFile);
                } catch (Exception ex) {
                    // Something has gone pear-shaped, let's start from scratch
                    this.Log().WarnException("Failed to load local releases, starting from scratch", ex);
                    shouldInitialize = true;
                }

restart:

                if (shouldInitialize)
                {
                    await initializeClientAppDirectory();
                }

                string releaseFile;

                var latestLocalRelease = localReleases.Count() > 0 ?
                                         localReleases.MaxBy(x => x.Version).First() :
                                         default(ReleaseEntry);

                // Fetch the remote RELEASES file, whether it's a local dir or an
                // HTTP URL
                if (Utility.IsHttpUrl(updateUrlOrPath))
                {
                    if (updateUrlOrPath.EndsWith("/"))
                    {
                        updateUrlOrPath = updateUrlOrPath.Substring(0, updateUrlOrPath.Length - 1);
                    }

                    this.Log().Info("Downloading RELEASES file from {0}", updateUrlOrPath);

                    int retries = 3;

retry:

                    try {
                        var uri = Utility.AppendPathToUri(new Uri(updateUrlOrPath), "RELEASES");

                        if (latestLocalRelease != null)
                        {
                            uri = Utility.AddQueryParamsToUri(uri, new Dictionary <string, string> {
                                { "id", latestLocalRelease.PackageName },
                                { "localVersion", latestLocalRelease.Version.ToString() },
                                { "arch", Environment.Is64BitOperatingSystem ? "amd64" : "x86" }
                            });
                        }

                        var data = await urlDownloader.DownloadUrl(uri.ToString());

                        releaseFile = Encoding.UTF8.GetString(data);
                    } catch (WebException ex) {
                        this.Log().InfoException("Download resulted in WebException (returning blank release list)", ex);

                        if (retries <= 0)
                        {
                            throw;
                        }
                        retries--;
                        goto retry;
                    }

                    progress(33);
                }
                else
                {
                    this.Log().Info("Reading RELEASES file from {0}", updateUrlOrPath);

                    if (!Directory.Exists(updateUrlOrPath))
                    {
                        var message = String.Format(
                            "The directory {0} does not exist, something is probably broken with your application",
                            updateUrlOrPath);

                        throw new Exception(message);
                    }

                    var fi = new FileInfo(Path.Combine(updateUrlOrPath, "RELEASES"));
                    if (!fi.Exists)
                    {
                        var message = String.Format(
                            "The file {0} does not exist, something is probably broken with your application",
                            fi.FullName);

                        this.Log().Warn(message);

                        var packages = (new DirectoryInfo(updateUrlOrPath)).GetFiles("*.nupkg");
                        if (packages.Length == 0)
                        {
                            throw new Exception(message);
                        }

                        // NB: Create a new RELEASES file since we've got a directory of packages
                        ReleaseEntry.WriteReleaseFile(
                            packages.Select(x => ReleaseEntry.GenerateFromFile(x.FullName)), fi.FullName);
                    }

                    releaseFile = File.ReadAllText(fi.FullName, Encoding.UTF8);
                    progress(33);
                }

                var ret            = default(UpdateInfo);
                var remoteReleases = ReleaseEntry.ParseReleaseFile(releaseFile);

                progress(66);

                if (!remoteReleases.Any())
                {
                    throw new Exception("Remote release File is empty or corrupted");
                }

                ret = determineUpdateInfo(localReleases, remoteReleases, ignoreDeltaUpdates);
                progress(100);
                if (startOverIfNone && !ret.ReleasesToApply.Any())
                {
                    // User has apparently re-run the installer for the version already installed.
                    // Assume the intent is to repair a broken installation.
                    // These rather awkward steps cause it to erase the installed-version directory
                    // and re-create it, much like a first-time install (though it won't run the app
                    // with the special arguments for first-time).
                    shouldInitialize = true;
                    localReleases    = Enumerable.Empty <ReleaseEntry>();
                    goto restart;
                }
                return(ret);
            }
Ejemplo n.º 8
0
            public void CreateShortcutsForExecutable(string exeName, ShortcutLocation locations, bool updateOnly)
            {
                this.Log().Info("About to create shortcuts for {0}, rootAppDir {1}", exeName, rootAppDirectory);

                var releases    = Utility.LoadLocalReleases(Utility.LocalReleaseFileForAppDir(rootAppDirectory));
                var thisRelease = Utility.FindCurrentVersion(releases);
                var updateExe   = Path.Combine(rootAppDirectory, "update.exe");

                var zf = new ZipPackage(Path.Combine(
                                            Utility.PackageDirectoryForAppDir(rootAppDirectory),
                                            thisRelease.Filename));

                var exePath     = Path.Combine(Utility.AppDirForRelease(rootAppDirectory, thisRelease), exeName);
                var fileVerInfo = FileVersionInfo.GetVersionInfo(exePath);

                foreach (var f in (ShortcutLocation[])Enum.GetValues(typeof(ShortcutLocation)))
                {
                    if (!locations.HasFlag(f))
                    {
                        continue;
                    }

                    var file       = linkTargetForVersionInfo(f, zf, fileVerInfo);
                    var fileExists = File.Exists(file);

                    // NB: If we've already installed the app, but the shortcut
                    // is no longer there, we have to assume that the user didn't
                    // want it there and explicitly deleted it, so we shouldn't
                    // annoy them by recreating it.
                    if (!fileExists && updateOnly)
                    {
                        this.Log().Warn("Wanted to update shortcut {0} but it appears user deleted it", file);
                        continue;
                    }

                    this.Log().Info("Creating shortcut for {0} => {1}", exeName, file);

                    ShellLink sl;
                    this.ErrorIfThrows(() => {
                        if (fileExists)
                        {
                            try {
                                sl = new ShellLink();

                                sl.Open(file);
                                if (sl.Target == updateExe && sl.Description == zf.Description && sl.IconPath == exePath)
                                {
                                    return;
                                }

                                File.Delete(file);
                            } catch (Exception ex) {
                                this.Log().WarnException("Tried to compare shortcut and failed", ex);
                                File.Delete(file);
                            }
                        }

                        sl = new ShellLink {
                            Target           = updateExe,
                            IconPath         = exePath,
                            IconIndex        = 0,
                            WorkingDirectory = Path.GetDirectoryName(exePath),
                            Description      = zf.Description,
                            Arguments        = "--processStart " + exeName,
                        };

                        sl.SetAppUserModelId(String.Format("com.squirrel.{0}.{1}", zf.Id, exeName.Replace(".exe", "")));

                        this.Log().Info("About to save shortcut: {0} (target {1}, workingDir {2}, args {3})", file, sl.Target, sl.WorkingDirectory, sl.Arguments);
                        if (ModeDetector.InUnitTestRunner() == false)
                        {
                            sl.Save(file);
                        }
                    }, "Can't write shortcut: " + file);
                }
            }