void updateLink(ShellLink shortcut, string newAppPath) { this.Log().Info("Processing shortcut '{0}'", shortcut.ShortCutFile); var target = Environment.ExpandEnvironmentVariables(shortcut.Target); var targetIsUpdateDotExe = target.EndsWith("update.exe", StringComparison.OrdinalIgnoreCase); this.Log().Info("Old shortcut target: '{0}'", target); // NB: In 1.5.0 we accidentally fixed the target of pinned shortcuts but left the arguments, // so if we find a shortcut with --processStart in the args, we're gonna stomp it even though // what we _should_ do is stomp it only if the target is Update.exe if (shortcut.Arguments.Contains("--processStart")) { shortcut.Arguments = ""; } if (!targetIsUpdateDotExe) { target = Path.Combine(rootAppDirectory, Path.GetFileName(shortcut.Target)); } else { target = Path.Combine(rootAppDirectory, Path.GetFileName(shortcut.IconPath)); } this.Log().Info("New shortcut target: '{0}'", target); shortcut.WorkingDirectory = newAppPath; shortcut.Target = target; this.Log().Info("Old iconPath is: '{0}'", shortcut.IconPath); shortcut.IconPath = target; shortcut.IconIndex = 0; this.ErrorIfThrows(() => Utility.Retry(() => shortcut.Save(), 2), "Couldn't write shortcut " + shortcut.ShortCutFile); this.Log().Info("Finished shortcut successfully"); }
public static async Task ExtractZipForInstall(string zipFilePath, string outFolder) { var zf = new ZipFile(zipFilePath); var entries = zf.OfType <ZipEntry>().ToArray(); var re = new Regex(@"lib[\\\/][^\\\/]*[\\\/]", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); try { await Utility.ForEachAsync(entries, (zipEntry) => { if (!zipEntry.IsFile) { return; } var entryFileName = Uri.UnescapeDataString(zipEntry.Name); if (!re.Match(entryFileName).Success) { return; } var fullZipToPath = Path.Combine(outFolder, re.Replace(entryFileName, "", 1)); var failureIsOkay = false; if (entryFileName.Contains("_ExecutionStub.exe")) { // NB: On upgrade, many of these stubs will be in-use, nbd tho. failureIsOkay = true; fullZipToPath = Path.Combine( Directory.GetParent(Path.GetDirectoryName(fullZipToPath)).FullName, Path.GetFileName(fullZipToPath).Replace("_ExecutionStub.exe", ".exe")); LogHost.Default.Info("Rigging execution stub for {0} to {1}", entryFileName, fullZipToPath); } var directoryName = Path.GetDirectoryName(fullZipToPath); var buffer = new byte[64 * 1024]; if (directoryName.Length > 0) { Utility.Retry(() => Directory.CreateDirectory(directoryName), 2); } try { Utility.Retry(() => { using (var zipStream = zf.GetInputStream(zipEntry)) using (FileStream streamWriter = File.Create(fullZipToPath)) { StreamUtils.Copy(zipStream, streamWriter, buffer); } }, 5); } catch (Exception e) { if (!failureIsOkay) { LogHost.Default.WarnException("Can't write execution stub, probably in use", e); throw e; } } }, 4); } finally { zf.Close(); } }
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 static Task ExtractZipForInstall(string zipFilePath, string outFolder, string rootPackageFolder) { var re = new Regex(@"lib[\\\/][^\\\/]*[\\\/]", RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); return(Task.Run(() => { using (var za = ZipArchive.Open(zipFilePath)) using (var reader = za.ExtractAllEntries()) { while (reader.MoveToNextEntry()) { var parts = reader.Entry.Key.Split('\\', '/'); var decoded = String.Join(Path.DirectorySeparatorChar.ToString(), parts); if (!re.IsMatch(decoded)) { continue; } decoded = re.Replace(decoded, "", 1); var fullTargetFile = Path.Combine(outFolder, decoded); var fullTargetDir = Path.GetDirectoryName(fullTargetFile); Directory.CreateDirectory(fullTargetDir); var failureIsOkay = false; if (!reader.Entry.IsDirectory && decoded.Contains("_ExecutionStub.exe")) { // NB: On upgrade, many of these stubs will be in-use, nbd tho. failureIsOkay = true; fullTargetFile = Path.Combine( rootPackageFolder, Path.GetFileName(decoded).Replace("_ExecutionStub.exe", ".exe")); LogHost.Default.Info("Rigging execution stub for {0} to {1}", decoded, fullTargetFile); } try { Utility.Retry(() => { if (reader.Entry.IsDirectory) { Directory.CreateDirectory(fullTargetFile); } else { reader.WriteEntryToFile(fullTargetFile); } }, 5); } catch (Exception e) { if (!failureIsOkay) { throw; } LogHost.Default.WarnException("Can't write execution stub, probably in use", e); } } } })); }