我正在尝试在WPF中重新启动应用程序。
我尝试了以下内容:
Process.Start(Application.ExecutablePath);
Process.GetCurrentProcess().Kill();
它不起作用,因为应用程序被设置为单实例应用程序。
然后我厌倦了这个:
Process.GetCurrentProcess().Kill();
Process.Start(Application.ExecutablePath);
它不起作用,因为一旦我们杀死了这个过程就不会遇到第2行
有没有办法安排.Start,这样我就不会遇到问题#1。
答案 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。