(string exeName, string arguments, bool shouldWait)
| 455 | } |
| 456 | |
| 457 | public void ProcessStart(string exeName, string arguments, bool shouldWait) |
| 458 | { |
| 459 | if (String.IsNullOrWhiteSpace(exeName)) { |
| 460 | ShowHelp(); |
| 461 | return; |
| 462 | } |
| 463 | |
| 464 | // Find the latest installed version's app dir |
| 465 | var appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); |
| 466 | var releases = ReleaseEntry.ParseReleaseFile( |
| 467 | File.ReadAllText(Utility.LocalReleaseFileForAppDir(appDir), Encoding.UTF8)); |
| 468 | |
| 469 | // NB: We add the hacked up version in here to handle a migration |
| 470 | // issue, where versions of Squirrel pre PR #450 will not understand |
| 471 | // prerelease tags, so it will end up writing the release name sans |
| 472 | // tags. However, the RELEASES file _will_ have them, so we need to look |
| 473 | // for directories that match both the real version, and the sanitized |
| 474 | // version, giving priority to the former. |
| 475 | var latestAppDir = releases |
| 476 | .OrderByDescending(x => x.Version) |
| 477 | .SelectMany(x => new[] { |
| 478 | Utility.AppDirForRelease(appDir, x), |
| 479 | Utility.AppDirForVersion(appDir, new SemanticVersion(x.Version.Version.Major, x.Version.Version.Minor, x.Version.Version.Build, "")) |
| 480 | }) |
| 481 | .FirstOrDefault(x => Directory.Exists(x)); |
| 482 | |
| 483 | // Check for the EXE name they want |
| 484 | var targetExe = new FileInfo(Path.Combine(latestAppDir, exeName.Replace("%20", " "))); |
| 485 | this.Log().Info("Want to launch '{0}'", targetExe); |
| 486 | |
| 487 | // Check for path canonicalization attacks |
| 488 | if (!targetExe.FullName.StartsWith(latestAppDir, StringComparison.Ordinal)) { |
| 489 | throw new ArgumentException(); |
| 490 | } |
| 491 | |
| 492 | if (!targetExe.Exists) { |
| 493 | this.Log().Error("File {0} doesn't exist in current release", targetExe); |
| 494 | throw new ArgumentException(); |
| 495 | } |
| 496 | |
| 497 | if (shouldWait) waitForParentToExit(); |
| 498 | |
| 499 | try { |
| 500 | this.Log().Info("About to launch: '{0}': {1}", targetExe.FullName, arguments ?? ""); |
| 501 | Process.Start(new ProcessStartInfo(targetExe.FullName, arguments ?? "") { WorkingDirectory = Path.GetDirectoryName(targetExe.FullName) }); |
| 502 | } catch (Exception ex) { |
| 503 | this.Log().ErrorException("Failed to start process", ex); |
| 504 | } |
| 505 | } |
| 506 | |
| 507 | public void ShowHelp() |
| 508 | { |
nothing calls this directly
no test coverage detected