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");
            }
Example #2
0
        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);
            }
Example #4
0
        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);
                            }
                        }
                    }
            }));
        }