如何在WPF中安排Process.Start

时间:2010-06-16 17:51:01

标签: c# wpf process.start

我正在尝试在WPF中重新启动应用程序。

我尝试了以下内容:

Process.Start(Application.ExecutablePath);
Process.GetCurrentProcess().Kill();

它不起作用,因为应用程序被设置为单实例应用程序。

然后我厌倦了这个:

Process.GetCurrentProcess().Kill();
Process.Start(Application.ExecutablePath);

它不起作用,因为一旦我们杀死了这个过程就不会遇到第2行

有没有办法安排.Start,这样我就不会遇到问题#1。

2 个答案:

答案 0 :(得分:2)

您可以启动辅助应用程序,然后在延迟后重新启动主程序。几年前,当我写一个自我更新程序时,那是我采用的实现路径。这只是一个简单的程序,将可执行文件作为命令行arg,将睡眠十分之一秒,然后。启动它。

比我更好的实现路径是让新启动的程序等待启动它的进程终止。等待任意长度的时间可能会使问题复杂化。为了实现这一点,我可能会将进程ID传递给重新启动器,以便确切知道要等待的进程。

答案 1 :(得分:2)

这并不像你想象的那么难。您需要做的就是调用以下方法,为重新启动的实例传递命令行:

public static void RestartMe(string commandLine)
{
  var myId = Process.GetCurrentProcess().Id;
  var myPath = Assembly.GetEntryAssembly().CodeBase.Replace("file:///", "");
  var systemPath = typeof(object).Assembly.CodeBase.Replace("file:///", "");

  var tempPath = Path.GetTempFileName();

  File.WriteAllText(tempPath + ".cs", @"
    using System;
    using System.Diagnostics;
    public class App
    {
      public static void Main(string[] args)
      {
        try { Process.GetProcessById(" + myId + @").WaitForExit(); } catch {}
        Process.Start(""" + myPath + @""", Environment.CommandLine);
      }
    }");

  var compiler = new ProcessStartInfo
  {
    FileName = Path.Combine(Path.GetDirectoryName(systemPath), "csc.exe"),
    Arguments = tempPath + ".cs",
    WorkingDirectory = Path.GetDirectoryName(tempPath),
    WindowStyle = ProcessWindowStyle.Hidden,
  };

  var restarter = new ProcessStartInfo
  {
    FileName = tempPath + ".exe",
    Arguments = commandLine,
    WindowStyle = ProcessWindowStyle.Hidden,
  };

  Process.Start(compiler).WaitForExit();
  Process.Start(restarter); // No WaitForExit: restarter WaitForExits us instead

  File.Delete(tempPath);
  File.Delete(tempPath + ".cs");
  Environment.Exit(0);
}

它如何工作:这实际上确实创建了另一个“重启”程序,但它可以轻松自动地完成。 restarter程序具有当前进程ID和内置的可执行文件名。它总能找到编译器,因为.NET Framework版本在与System.dll相同的文件夹中附带了兼容的csc.exe。