正在开发一个 C# .NET 2.0 WinForm 应用程序。需要应用程序关闭并重新启动自己。
Application.Restart();
上述方法已被证明不可靠。有没有更好的方法来重新启动应用程序?
正在开发一个 C# .NET 2.0 WinForm 应用程序。需要应用程序关闭并重新启动自己。
Application.Restart();
上述方法已被证明不可靠。有没有更好的方法来重新启动应用程序?
我使用了一种更简单的方法,它对我很有效:
Application.Restart();
Environment.Exit(0);
这样可以保存命令行参数,并且可以避免通常会阻止应用程序关闭的事件处理程序的影响。
Restart()调用尝试退出,无论如何开始新的实例并返回。Exit()调用然后终止进程,不会给任何事件处理程序运行的机会。在两个进程同时运行的非常短暂的时间段内可能存在问题,但在我的情况下没有问题,但在其他情况下可能存在问题。
Environment.Exit(0);
中的退出代码0指定了干净的关闭。您也可以使用1退出以指定发生了错误。
OnClose()
表单事件等。 - Artfaith如果您在主应用程序表单中,请尝试使用以下内容
System.Diagnostics.Process.Start( Application.ExecutablePath); // to start new instance of application
this.Close(); //to turn off current app
Enviorment.Exit(0)
也能完成任务。 - Dwza很遗憾,您无法使用Process.Start()启动当前正在运行的进程的实例。根据Process.Start()文档: “如果进程已经在运行,则不会启动任何其他进程资源…”
这种技术在VS调试器下可以正常工作(因为VS会进行某种魔法使Process.Start认为进程尚未运行),但在非调试状态下将失败。(请注意,这可能是特定于操作系统的——我记得在我的一些测试中,它在XP或Vista上工作,但我可能只是记得在调试器下运行它。)
这种技术正是我目前正在工作的项目上最后一个程序员使用的技术,我一直在努力寻找解决方法。到目前为止,我只找到了一种解决方案,但它让我感觉很肮脏和笨拙:启动第二个应用程序,在后台等待第一个应用程序终止,然后重新启动第一个应用程序。我相信它会起作用,但是,呸。
编辑:使用第二个应用程序可行。我在第二个应用程序中所做的只是:
static void RestartApp(int pid, string applicationName )
{
// Wait for the process to terminate
Process process = null;
try
{
process = Process.GetProcessById(pid);
process.WaitForExit(1000);
}
catch (ArgumentException ex)
{
// ArgumentException to indicate that the
// process doesn't exist? LAME!!
}
Process.Start(applicationName, "");
}
WaitForExit(1000)
。但是整个等待并不是启动新进程所必需的。这可能是您想要的附加行为,但启动新进程并不需要它。 - usr我可能有点晚参加这个活动,但这是我的简单解决方案,它在我使用的每个应用程序中都运行得很好:
try
{
//run the program again and close this one
Process.Start(Application.StartupPath + "\\blabla.exe");
//or you can use Application.ExecutablePath
//close this one
Process.GetCurrentProcess().Kill();
}
catch
{ }
我曾经遇到过完全相同的问题,并且我也有一个要求防止重复实例的需求 - 我提出了一种替代解决方案,与HiredMind提出的解决方案(这个方案是可行的)不同。
我的做法是,将旧进程的processId(触发重新启动的进程)作为命令行参数启动新进程:
// Shut down the current app instance.
Application.Exit();
// Restart the app passing "/restart [processId]" as cmd line args
Process.Start(Application.ExecutablePath, "/restart" + Process.GetCurrentProcess().Id);
当新应用程序启动时,我首先解析cm行参数并检查是否存在带有进程ID的重启标识,然后等待该进程退出:
if (_isRestart)
{
try
{
// get old process and wait UP TO 5 secs then give up!
Process oldProcess = Process.GetProcessById(_restartProcessId);
oldProcess.WaitForExit(5000);
}
catch (Exception ex)
{
// the process did not exist - probably already closed!
//TODO: --> LOG
}
}
显然我并没有展示我所有的安全检查等内容。
即使不是最理想的情况 - 我认为这是一种有效的替代方案,这样您就不必再单独创建一个应用程序来处理重启。
/allowMultipleInstances
标志,而不是那个相当奇怪的/restart
标志。 - DennisApplication.Restart()
方法,这将重新启动您的应用程序。您还必须使用错误代码退出本地环境:Application.Restart();
Environment.Exit(int errorcode);
Application.Exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);
// Get the parameters/arguments passed to program if any
string arguments = string.Empty;
string[] args = Environment.GetCommandLineArgs();
for (int i = 1; i < args.Length; i++) // args[0] is always exe path/filename
arguments += args[i] + " ";
// Restart current application, with same arguments/parameters
Application.Exit();
System.Diagnostics.Process.Start(Application.ExecutablePath, arguments);
这似乎比Application.Restart()更有效。
不确定如果您的程序防止多个实例,该如何处理。我的猜测是您最好启动第二个.exe文件,暂停一下,然后为您启动主应用程序。
试试这段代码:
bool appNotRestarted = true;
if (appNotRestarted == true) {
appNotRestarted = false;
Application.Restart();
Application.ExitThread();
}
我想出了另一种解决方案,或许其他人也可以使用它。
string batchContent = "/c \"@ECHO OFF & timeout /t 6 > nul & start \"\" \"$[APPPATH]$\" & exit\"";
batchContent = batchContent.Replace("$[APPPATH]$", Application.ExecutablePath);
Process.Start("cmd", batchContent);
Application.Exit();
代码被简化了,因此需要注意异常等问题;)
我担心使用Process重新启动整个应用程序是错误的解决方法。
一个更简单的方法是修改Program.cs文件进行重启:
static bool restart = true; // A variable that is accessible from program
static int restartCount = 0; // Count the number of restarts
static int maxRestarts = 3; // Maximum restarts before quitting the program
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
while (restart && restartCount < maxRestarts)
{
restart = false; // if you like.. the program can set it to true again
restartCount++; // mark another restart,
// if you want to limit the number of restarts
// this is useful if your program is crashing on
// startup and cannot close normally as it will avoid
// a potential infinite loop
try {
Application.Run(new YourMainForm());
}
catch { // Application has crashed
restart = true;
}
}
}