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); }
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); }
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); }
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); }
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); } }