如何重新启动C#WinForm应用程序?

Ada*_*ger 79 .net c#

开发C#.NET 2.0 WinForm应用程序.需要应用程序关闭并重新启动自身.

Application.Restart();
Run Code Online (Sandbox Code Playgroud)

上述方法已被证明是不可靠的.

什么是重启应用程序的更好方法?

Dar*_*qer 55

如果您在主应用程序表单中尝试使用

System.Diagnostics.Process.Start( Application.ExecutablePath); // to start new instance of application
this.Close(); //to turn off current app
Run Code Online (Sandbox Code Playgroud)

  • 它是相似的,但不同.Application.Exit不适用于我,而this.Close()完成了这项工作. (7认同)
  • `Enviorment.Exit` 是一个肮脏且极具侵入性的退出,因为它会阻止应用程序清理代码运行。大多数时候不是正确的选择。 (2认同)

EMP*_*EMP 51

一个更简单的方法对我有用:

Application.Restart();
Environment.Exit(0);
Run Code Online (Sandbox Code Playgroud)

这保留了命令行参数,并且尽管事件处理程序通常会阻止应用程序关闭.

Restart()调用尝试退出,无论如何都启动一个新实例并返回.然后,Exit()调用终止进程,而不给任何事件处理程序提供运行的机会.有一个非常短暂的时期,两个进程都在运行,这在我的情况下不是问题,但可能在其他情况下.

退出代码0 in Environment.Exit(0);指定干净关闭.您也可以使用1退出以指定发生的错误.

  • Application.Restart()本身为我工作,谢谢! (2认同)

Hir*_*ind 39

遗憾的是,您无法使用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, "");
    }
Run Code Online (Sandbox Code Playgroud)

(这是一个非常简单的例子.真正的代码有很多健全性检查,错误处理等)


Sol*_*ake 16

我可能会迟到,但这是我的简单解决方案,它就像我的每个应用程序的魅力:

        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
        { }
Run Code Online (Sandbox Code Playgroud)


Joh*_*dol 11

我有同样的问题,我也有要求防止重复的实例 - 我提出了一个HiredMind建议的替代解决方案(这将工作正常).

我正在做的是使用旧进程的processId(触发重启的进程)作为cmd行参数启动新进程:

// 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);
Run Code Online (Sandbox Code Playgroud)

然后当新应用程序启动时,我首先解析cm行args并检查是否有一个processId重启标志,然后等待该进程退出:

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
   }
}
Run Code Online (Sandbox Code Playgroud)

我显然没有显示我所有的安全检查等.

即使不理想 - 我发现这是一个有效的替代方案,因此您不必为了处理重启而拥有一个单独的应用程序.


Son*_*onu 6

它的简单你只需要调用Application.Restart()那些倾向于调用你的应用程序重启的方法.但您必须使用错误代码退出本地环境:

Application.Restart();
Environment.exit(int errorcode);
Run Code Online (Sandbox Code Playgroud)

您可以创建一个错误代码的枚举,您可以使用它来有效地使用它.
另一种方法是从应用程序退出并启动具有可执行路径的进程:

Application.exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);
Run Code Online (Sandbox Code Playgroud)


Ada*_*ger 5

开始/退出方法

// 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);
Run Code Online (Sandbox Code Playgroud)

这似乎比Application.Restart()更好用;

如果您的程序防止多个实例,则不确定如何处理.我的猜测是,您最好启动第二个.exe暂停,然后为您启动主应用程序.

  • 如果应用程序受到多个实例的保护,那可能不起作用. (2认同)