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

时间:2021-01-21 07:36:15

Developing a C# .NET 2.0 WinForm Application. Need the application to close and restart itself.

开发c# . net 2.0 WinForm应用程序。需要应用程序关闭并重新启动自己。

Application.Restart();

The above method has proven to be unreliable.

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

What is a better way to restart the application?

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

20 个解决方案

#1


37  

Unfortunately you can't use Process.Start() to start an instance of the currently running process. According to the Process.Start() docs: "If the process is already running, no additional process resource is started..."

不幸的是,您不能使用process. start()来启动当前正在运行的进程的实例。根据process . start()文档:“如果流程已经在运行,则不会启动任何额外的流程资源……”

This technique will work fine under the VS debugger (because VS does some kind of magic that causes Process.Start to think the process is not already running), but will fail when not run under the debugger. (Note that this may be OS-specific - I seem to remember that in some of my testing, it worked on either XP or Vista, but I may just be remembering running it under the debugger.)

这种技术在VS调试器下可以正常工作(因为VS会产生一些导致进程的魔法)。开始认为进程还没有运行),但是如果不在调试器下运行就会失败。(注意,这可能是特定于操作系统的——我似乎记得在我的一些测试中,它可以在XP或Vista上运行,但我可能只是记得在调试器下运行它)。

This technique is exactly the one used by the last programmer on the project on which I'm currently working, and I've been trying to find a workaround for this for quite some time. So far, I've only found one solution, and it just feels dirty and kludgy to me: start a 2nd application, that waits in the background for the first application to terminate, then re-launches the 1st application. I'm sure it would work, but, yuck.

这个技巧正是我目前工作的项目上的最后一个程序员所使用的,我已经为此寻找了很长一段时间的解决方案。到目前为止,我只找到了一种解决方案,对我来说,这是一种笨拙的做法:启动第二个应用程序,在后台等待第一个应用程序终止,然后重新启动第一个应用程序。我肯定它能行,但是,妈的。

Edit: Using a 2nd application works. All I did in the second app was:

编辑:使用第二个应用程序。我在第二个应用中所做的是:

    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, "");
    }

(This is a very simplified example. The real code has lots of sanity checking, error handling, etc)

这是一个非常简单的例子。真正的代码有很多完整性检查、错误处理等)

#2


49  

If you are in main app form try to use

如果你在主应用程序表单中,试着使用

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

#3


26  

A much simpler approach that worked for me is:

对我来说更简单的方法是:

Application.Restart();
Environment.Exit(0);

This preserves the command-line arguments and works despite event handlers that would normally prevent the application from closing.

这保留了命令行参数和工作,尽管事件处理程序通常会阻止应用程序关闭。

The Restart() call tries to exit, starts a new instance anyway and returns. The Exit() call then terminates the process without giving any event handlers a chance to run. There is a very brief period in which both processes are running, which is not a problem in my case, but maybe in other cases.

Restart()调用尝试退出,启动一个新实例并返回。然后Exit()调用终止进程,不给任何事件处理程序运行的机会。有一段很短的时间,两个进程都在运行,这在我的例子中不是问题,但可能在其他情况下。

The exit code 0 in Environment.Exit(0); specifies a clean shutdown. You can also exit with 1 to specify an error occurred.

在环境中退出代码0 . exit (0);指定一个干净的关闭。还可以使用1退出,以指定发生错误。

#4


16  

I might be late to the party but here is my simple solution and it works like a charm with every application I have:

我参加聚会可能会迟到,但我有一个简单的解决方案:

        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
        { }

#5


10  

I had the same exact problem and I too had a requirement to prevent duplicate instances - I propose an alternative solution to the one HiredMind is proposing (which will work fine).

我也有同样的问题,我也有防止重复实例的要求——我为他的想法提出了另一种解决方案(这将很有效)。

What I am doing is starting the new process with the processId of the old process (the one that triggers the restart) as a cmd line argument:

我所做的是用旧进程的进程(触发重新启动的进程)作为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);

Then when the new app starts I first parse the cm line args and check if the restart flag is there with a processId, then wait for that process to Exit:

然后,当新的应用程序启动时,我首先解析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
   }
}

I am obviously not showing all the safety checks that I have in place etc.

很明显,我没有出示我所有的安全检查。

Even if not ideal - I find this a valid alternative so that you don't have to have in place a separate app just to handle restart.

即使不是很理想——我发现这是一个有效的替代方案,这样你就不需要一个单独的应用程序来处理重新启动。

#6


6  

Its Simple you just need to call the Application.Restart() methods which tends to invoke you application for being restarted. But you must have to exit from the Local environment with their error codes:

您只需调用application . restart()方法,这些方法通常会调用您的应用程序以重新启动。但是您必须使用错误代码从本地环境中退出:

Application.Restart();
Environment.exit(int errorcode);

you can create an enumeration of error code for that you may use it efficeintly.
Another method is to just exit form the application and start the process having executable path:

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

Application.exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);

#7


5  

Start/Exit Method

// 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);

This seems to work better than Application.Restart();

这似乎比Application.Restart()工作得更好;

Not sure how this handles if your program protects against multiple instance. My guess is you would be better off launching a second .exe which pauses and then starts your main application for you.

如果程序保护了多个实例,则不知道如何处理。我猜你最好启动第二个。exe,它会暂停,然后为你启动主应用程序。

#8


3  

Try this code:

试试这段代码:

bool appNotRestarted = true;

This code must also be in the function:

此代码也必须在函数中:

if (appNotRestarted == true) {
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}

#9


3  

I figured an another solution out, perhaps anyone can use it, too.

我想出了另一个解决方案,也许任何人都可以使用它。

string batchContent = "/c \"@ECHO OFF & timeout /t 6 > nul & start \"\" \"$[APPPATH]$\" & exit\"";
batchContent = batchContent.Replace("$[APPPATH]$", Application.ExecutablePath);
Process.Start("cmd", batchContent);
Application.Exit();

Code is simplified so take care of Exceptions and stuff ;)

代码简化了,所以要注意异常和内容;

#10


2  

You are forgetting the command-line options/parameters that were passed in to your currently running instance. If you don't pass those in, you are not doing a real restart. Set the Process.StartInfo with a clone of your process' parameters, then do a start.

您正在忘记传递给当前运行的实例的命令行选项/参数。如果你不把它们传递进来,你就没有真正的重新启动。设置过程。使用流程参数的克隆启动信息,然后开始。

For example, if your process was started as myexe -f -nosplash myfile.txt, your method would only execute myexe without all those flags and parameters.

例如,如果您的进程启动为myexe -f -nosplash myfile。txt,你的方法将只执行myexe而没有所有的标志和参数。

#11


2  

I wanted the new application start up after the old one shuts down.

我希望新应用程序在旧应用程序关闭后启动。

Using process.WaitForExit() to wait for your own process to shutdown makes no sense. It will always time out.

使用process. waitforexit()等待您自己的进程关闭是没有意义的。它总是会超时的。

So, my approach is to use Application.Exit() then wait, but allow events to be processed, for a period of time. Then start a new application with the same arguments as the old.

因此,我的方法是使用Application.Exit()然后等待,但是允许事件在一段时间内被处理。然后使用与旧应用程序相同的参数启动新应用程序。

static void restartApp() {
    string commandLineArgs = getCommandLineArgs();
    string exePath = Application.ExecutablePath;
    try {
        Application.Exit();
        wait_allowingEvents( 1000 );
    } catch( ArgumentException ex ) {
        throw;
    }
    Process.Start( exePath, commandLineArgs );
}

static string getCommandLineArgs() {
    Queue<string> args = new Queue<string>( Environment.GetCommandLineArgs() );
    args.Dequeue(); // args[0] is always exe path/filename
    return string.Join( " ", args.ToArray() );
}

static void wait_allowingEvents( int durationMS ) {
    DateTime start = DateTime.Now;
    do {
        Application.DoEvents();
    } while( start.Subtract( DateTime.Now ).TotalMilliseconds > durationMS );
}

#12


2  

You could also use Restarter.

你也可以使用Restarter。

Restarter is an application that automatically monitor and restarts crashed or hung programs and applications. It was originally developed to monitor and restart game servers, but it will do the job for any console or form based program or application

Restarter是一个应用程序,可以自动监视和重新启动崩溃或挂起的程序和应用程序。它最初是为监视和重启游戏服务器而开发的,但它将为任何控制台或基于表单的程序或应用程序提供工作。

#13


2  

public static void appReloader()
    {
        //Start a new instance of the current program
        Process.Start(Application.ExecutablePath);

        //close the current application process
        Process.GetCurrentProcess().Kill();
    }

Application.ExecutablePath returns your aplication .exe file path Please follow the order of calls. You might want to place it in a try-catch clause.

应用程序。执行路径返回您的申请。exe文件路径请按照调用顺序。您可能想把它放在try-catch子句中。

#14


1  

Here's my 2 cents:

这是我的2分:

The sequence Start New Instance->Close Current Instance should work even for the applications that don't allow running multiple copies simultaneously as in this case the new instance may be passed a command-line argument which will indicate that there is a restart in progress so checking for other instances running will not be necessary. Waiting for the first instance to actually finish my be implemented too if it's absolutely imperative that no two intstances are running in parallel.

序列启动新实例- >关闭当前实例应该工作甚至不允许同时运行多个副本的应用程序,在这种情况下,可能通过一个命令行参数,将新实例表明有一个启动过程中所以检查运行的其他实例不会是必要的。等待第一个实例真正完成我的be实现,如果绝对需要没有两个意图并行运行。

#15


1  

I fear that restarting the entire application using Process is approaching your problem in the wrong way.

我担心使用过程重新启动整个应用程序会以错误的方式处理您的问题。

An easier way is to modify the Program.cs file to restart:

一个更简单的方法是修改程序。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;
           }
        }
    }

#16


0  

I had a similar problem, but mine was related to unmanageable memory leak that I couldn't find on an app that has to run 24/7. With the customer I agreed that safe time to restart the app was 03:00AM if the memory consumption was over the defined value.

我也遇到过类似的问题,但我的问题与无法管理的内存泄漏有关,我在一个必须全天候运行的应用程序上找不到内存泄漏。对于客户,我同意如果内存消耗超过了定义的值,重启应用程序的安全时间是03:00AM。

I tried Application.Restart, but since it seems to use some mechanism that starts new instance while it is already running, I went for another scheme. I used the trick that file system handles persist until process that created them dies. So, from The Application, i dropped the file to the disk, and didn't Dispose() the handle. I used the file to send 'myself' executable and starting directory also (to add flexibility).

我试着应用程序。重新启动,但是由于它似乎使用了某种机制,在它已经运行时启动新实例,所以我采用了另一种方案。我使用了文件系统句柄保持不变的技巧,直到创建它们的进程死亡。因此,从应用程序中,我将文件删除到磁盘,并没有处理()句柄。我使用该文件发送“我自己”可执行文件和启动目录(以增加灵活性)。

Code:

代码:

_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
    FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
    WorkingDirectory = Application.StartupPath,
    Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();

Close() at the end would initiate app shutdown, and file handle I used for StreamWriter here would be held open until process really dies. Then...

Close()在末尾将启动应用程序关机,我在这里用于StreamWriter的文件句柄将保持打开状态,直到进程真正停止。然后……

Restarter.exe comes into action. It TRIES to read the file in exclusive mode, preventing it to gain access until main app wasn't dead, then starts main app, deletes the file and exists. I guess that it can't be simpler:

重新启动。exe进入行动。它尝试在独占模式下读取文件,在主应用程序未死之前阻止它访问,然后启动主应用程序,删除文件并存在。我想这再简单不过了:

static void Main(string[] args)
{
    string filename = args[0];
    DateTime start = DateTime.Now;
    bool done = false;
    while ((DateTime.Now - start).TotalSeconds < 30 && !done)
    {
        try
        {
            StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
            string[] runData = new string[2];
            runData[0] = sr.ReadLine();
            runData[1] = sr.ReadLine();
            Thread.Sleep(1000);
            Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
            sr.Dispose();
            File.Delete(filename);
            done = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Thread.Sleep(1000);
    }
}

#17


0  

How about create a bat file, run the batch file before closing, and then close the current instance.

如何创建一个bat文件,在关闭之前运行批处理文件,然后关闭当前实例。

The batch file does this:

批处理文件是这样做的:

  1. wait in a loop to check whether the process has exited.
  2. 在循环中等待检查进程是否已退出。
  3. start the process.
  4. 启动过程。

#18


0  

I use the following and it does exactly what you are looking for:

我用下面的方法来做你想要的:

ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
UpdateCheckInfo info = null;
info = ad.CheckForDetailedUpdate();
if (info.IsUpdateRequired)
{
    ad.UpdateAsync(); // I like the update dialog
    MessageBox.Show("Application was upgraded and will now restart.");
    Environment.Exit(0);
}

#19


0  

for using As logout you need to terminate all app from Ram Cache so close The Application first and then Rerun it

要使用As注销,您需要终止所有来自Ram缓存的应用程序,因此首先关闭应用程序,然后重新运行它

//on clicking Logout Button

/ /点击注销按钮

foreach(Form frm in Application.OpenForms.Cast<Form>().ToList())
        {
            frm.Close();
        }
System.Diagnostics.Process.Start(Application.ExecutablePath);

#20


0  

The problem of using Application.Restart() is, that it starts a new process but the "old" one is still remaining. Therefor I decided to Kill the old process by using the following code snippet:

使用Application.Restart()的问题是,它启动了一个新进程,但“旧”进程仍然存在。为此,我决定使用以下代码片段来终止旧的进程:

            if(Condition){
            Application.Restart();
            Process.GetCurrentProcess().Kill();
            }

And it works proper good. In my case MATLAB and a C# Application are sharing the same SQLite database. If MATLAB is using the database, the Form-App should restart (+Countdown) again, until MATLAB reset its busy bit in the database. (Just for side information)

而且效果很好。在我的例子中,MATLAB和c#应用程序共享同一个SQLite数据库。如果MATLAB使用的是数据库,那么表单应用程序应该重新启动(+倒计时),直到MATLAB重新启动数据库中繁忙的部分。(只是为了信息)

#1


37  

Unfortunately you can't use Process.Start() to start an instance of the currently running process. According to the Process.Start() docs: "If the process is already running, no additional process resource is started..."

不幸的是,您不能使用process. start()来启动当前正在运行的进程的实例。根据process . start()文档:“如果流程已经在运行,则不会启动任何额外的流程资源……”

This technique will work fine under the VS debugger (because VS does some kind of magic that causes Process.Start to think the process is not already running), but will fail when not run under the debugger. (Note that this may be OS-specific - I seem to remember that in some of my testing, it worked on either XP or Vista, but I may just be remembering running it under the debugger.)

这种技术在VS调试器下可以正常工作(因为VS会产生一些导致进程的魔法)。开始认为进程还没有运行),但是如果不在调试器下运行就会失败。(注意,这可能是特定于操作系统的——我似乎记得在我的一些测试中,它可以在XP或Vista上运行,但我可能只是记得在调试器下运行它)。

This technique is exactly the one used by the last programmer on the project on which I'm currently working, and I've been trying to find a workaround for this for quite some time. So far, I've only found one solution, and it just feels dirty and kludgy to me: start a 2nd application, that waits in the background for the first application to terminate, then re-launches the 1st application. I'm sure it would work, but, yuck.

这个技巧正是我目前工作的项目上的最后一个程序员所使用的,我已经为此寻找了很长一段时间的解决方案。到目前为止,我只找到了一种解决方案,对我来说,这是一种笨拙的做法:启动第二个应用程序,在后台等待第一个应用程序终止,然后重新启动第一个应用程序。我肯定它能行,但是,妈的。

Edit: Using a 2nd application works. All I did in the second app was:

编辑:使用第二个应用程序。我在第二个应用中所做的是:

    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, "");
    }

(This is a very simplified example. The real code has lots of sanity checking, error handling, etc)

这是一个非常简单的例子。真正的代码有很多完整性检查、错误处理等)

#2


49  

If you are in main app form try to use

如果你在主应用程序表单中,试着使用

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

#3


26  

A much simpler approach that worked for me is:

对我来说更简单的方法是:

Application.Restart();
Environment.Exit(0);

This preserves the command-line arguments and works despite event handlers that would normally prevent the application from closing.

这保留了命令行参数和工作,尽管事件处理程序通常会阻止应用程序关闭。

The Restart() call tries to exit, starts a new instance anyway and returns. The Exit() call then terminates the process without giving any event handlers a chance to run. There is a very brief period in which both processes are running, which is not a problem in my case, but maybe in other cases.

Restart()调用尝试退出,启动一个新实例并返回。然后Exit()调用终止进程,不给任何事件处理程序运行的机会。有一段很短的时间,两个进程都在运行,这在我的例子中不是问题,但可能在其他情况下。

The exit code 0 in Environment.Exit(0); specifies a clean shutdown. You can also exit with 1 to specify an error occurred.

在环境中退出代码0 . exit (0);指定一个干净的关闭。还可以使用1退出,以指定发生错误。

#4


16  

I might be late to the party but here is my simple solution and it works like a charm with every application I have:

我参加聚会可能会迟到,但我有一个简单的解决方案:

        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
        { }

#5


10  

I had the same exact problem and I too had a requirement to prevent duplicate instances - I propose an alternative solution to the one HiredMind is proposing (which will work fine).

我也有同样的问题,我也有防止重复实例的要求——我为他的想法提出了另一种解决方案(这将很有效)。

What I am doing is starting the new process with the processId of the old process (the one that triggers the restart) as a cmd line argument:

我所做的是用旧进程的进程(触发重新启动的进程)作为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);

Then when the new app starts I first parse the cm line args and check if the restart flag is there with a processId, then wait for that process to Exit:

然后,当新的应用程序启动时,我首先解析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
   }
}

I am obviously not showing all the safety checks that I have in place etc.

很明显,我没有出示我所有的安全检查。

Even if not ideal - I find this a valid alternative so that you don't have to have in place a separate app just to handle restart.

即使不是很理想——我发现这是一个有效的替代方案,这样你就不需要一个单独的应用程序来处理重新启动。

#6


6  

Its Simple you just need to call the Application.Restart() methods which tends to invoke you application for being restarted. But you must have to exit from the Local environment with their error codes:

您只需调用application . restart()方法,这些方法通常会调用您的应用程序以重新启动。但是您必须使用错误代码从本地环境中退出:

Application.Restart();
Environment.exit(int errorcode);

you can create an enumeration of error code for that you may use it efficeintly.
Another method is to just exit form the application and start the process having executable path:

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

Application.exit();
System.Diagnostics.Process.Start(Application.ExecutablePath);

#7


5  

Start/Exit Method

// 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);

This seems to work better than Application.Restart();

这似乎比Application.Restart()工作得更好;

Not sure how this handles if your program protects against multiple instance. My guess is you would be better off launching a second .exe which pauses and then starts your main application for you.

如果程序保护了多个实例,则不知道如何处理。我猜你最好启动第二个。exe,它会暂停,然后为你启动主应用程序。

#8


3  

Try this code:

试试这段代码:

bool appNotRestarted = true;

This code must also be in the function:

此代码也必须在函数中:

if (appNotRestarted == true) {
    appNotRestarted = false;
    Application.Restart();
    Application.ExitThread();
}

#9


3  

I figured an another solution out, perhaps anyone can use it, too.

我想出了另一个解决方案,也许任何人都可以使用它。

string batchContent = "/c \"@ECHO OFF & timeout /t 6 > nul & start \"\" \"$[APPPATH]$\" & exit\"";
batchContent = batchContent.Replace("$[APPPATH]$", Application.ExecutablePath);
Process.Start("cmd", batchContent);
Application.Exit();

Code is simplified so take care of Exceptions and stuff ;)

代码简化了,所以要注意异常和内容;

#10


2  

You are forgetting the command-line options/parameters that were passed in to your currently running instance. If you don't pass those in, you are not doing a real restart. Set the Process.StartInfo with a clone of your process' parameters, then do a start.

您正在忘记传递给当前运行的实例的命令行选项/参数。如果你不把它们传递进来,你就没有真正的重新启动。设置过程。使用流程参数的克隆启动信息,然后开始。

For example, if your process was started as myexe -f -nosplash myfile.txt, your method would only execute myexe without all those flags and parameters.

例如,如果您的进程启动为myexe -f -nosplash myfile。txt,你的方法将只执行myexe而没有所有的标志和参数。

#11


2  

I wanted the new application start up after the old one shuts down.

我希望新应用程序在旧应用程序关闭后启动。

Using process.WaitForExit() to wait for your own process to shutdown makes no sense. It will always time out.

使用process. waitforexit()等待您自己的进程关闭是没有意义的。它总是会超时的。

So, my approach is to use Application.Exit() then wait, but allow events to be processed, for a period of time. Then start a new application with the same arguments as the old.

因此,我的方法是使用Application.Exit()然后等待,但是允许事件在一段时间内被处理。然后使用与旧应用程序相同的参数启动新应用程序。

static void restartApp() {
    string commandLineArgs = getCommandLineArgs();
    string exePath = Application.ExecutablePath;
    try {
        Application.Exit();
        wait_allowingEvents( 1000 );
    } catch( ArgumentException ex ) {
        throw;
    }
    Process.Start( exePath, commandLineArgs );
}

static string getCommandLineArgs() {
    Queue<string> args = new Queue<string>( Environment.GetCommandLineArgs() );
    args.Dequeue(); // args[0] is always exe path/filename
    return string.Join( " ", args.ToArray() );
}

static void wait_allowingEvents( int durationMS ) {
    DateTime start = DateTime.Now;
    do {
        Application.DoEvents();
    } while( start.Subtract( DateTime.Now ).TotalMilliseconds > durationMS );
}

#12


2  

You could also use Restarter.

你也可以使用Restarter。

Restarter is an application that automatically monitor and restarts crashed or hung programs and applications. It was originally developed to monitor and restart game servers, but it will do the job for any console or form based program or application

Restarter是一个应用程序,可以自动监视和重新启动崩溃或挂起的程序和应用程序。它最初是为监视和重启游戏服务器而开发的,但它将为任何控制台或基于表单的程序或应用程序提供工作。

#13


2  

public static void appReloader()
    {
        //Start a new instance of the current program
        Process.Start(Application.ExecutablePath);

        //close the current application process
        Process.GetCurrentProcess().Kill();
    }

Application.ExecutablePath returns your aplication .exe file path Please follow the order of calls. You might want to place it in a try-catch clause.

应用程序。执行路径返回您的申请。exe文件路径请按照调用顺序。您可能想把它放在try-catch子句中。

#14


1  

Here's my 2 cents:

这是我的2分:

The sequence Start New Instance->Close Current Instance should work even for the applications that don't allow running multiple copies simultaneously as in this case the new instance may be passed a command-line argument which will indicate that there is a restart in progress so checking for other instances running will not be necessary. Waiting for the first instance to actually finish my be implemented too if it's absolutely imperative that no two intstances are running in parallel.

序列启动新实例- >关闭当前实例应该工作甚至不允许同时运行多个副本的应用程序,在这种情况下,可能通过一个命令行参数,将新实例表明有一个启动过程中所以检查运行的其他实例不会是必要的。等待第一个实例真正完成我的be实现,如果绝对需要没有两个意图并行运行。

#15


1  

I fear that restarting the entire application using Process is approaching your problem in the wrong way.

我担心使用过程重新启动整个应用程序会以错误的方式处理您的问题。

An easier way is to modify the Program.cs file to restart:

一个更简单的方法是修改程序。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;
           }
        }
    }

#16


0  

I had a similar problem, but mine was related to unmanageable memory leak that I couldn't find on an app that has to run 24/7. With the customer I agreed that safe time to restart the app was 03:00AM if the memory consumption was over the defined value.

我也遇到过类似的问题,但我的问题与无法管理的内存泄漏有关,我在一个必须全天候运行的应用程序上找不到内存泄漏。对于客户,我同意如果内存消耗超过了定义的值,重启应用程序的安全时间是03:00AM。

I tried Application.Restart, but since it seems to use some mechanism that starts new instance while it is already running, I went for another scheme. I used the trick that file system handles persist until process that created them dies. So, from The Application, i dropped the file to the disk, and didn't Dispose() the handle. I used the file to send 'myself' executable and starting directory also (to add flexibility).

我试着应用程序。重新启动,但是由于它似乎使用了某种机制,在它已经运行时启动新实例,所以我采用了另一种方案。我使用了文件系统句柄保持不变的技巧,直到创建它们的进程死亡。因此,从应用程序中,我将文件删除到磁盘,并没有处理()句柄。我使用该文件发送“我自己”可执行文件和启动目录(以增加灵活性)。

Code:

代码:

_restartInProgress = true;
string dropFilename = Path.Combine(Application.StartupPath, "restart.dat");
StreamWriter sw = new StreamWriter(new FileStream(dropFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite));
sw.WriteLine(Application.ExecutablePath);
sw.WriteLine(Application.StartupPath);
sw.Flush();
Process.Start(new ProcessStartInfo
{
    FileName = Path.Combine(Application.StartupPath, "VideoPhill.Restarter.exe"),
    WorkingDirectory = Application.StartupPath,
    Arguments = string.Format("\"{0}\"", dropFilename)
});
Close();

Close() at the end would initiate app shutdown, and file handle I used for StreamWriter here would be held open until process really dies. Then...

Close()在末尾将启动应用程序关机,我在这里用于StreamWriter的文件句柄将保持打开状态,直到进程真正停止。然后……

Restarter.exe comes into action. It TRIES to read the file in exclusive mode, preventing it to gain access until main app wasn't dead, then starts main app, deletes the file and exists. I guess that it can't be simpler:

重新启动。exe进入行动。它尝试在独占模式下读取文件,在主应用程序未死之前阻止它访问,然后启动主应用程序,删除文件并存在。我想这再简单不过了:

static void Main(string[] args)
{
    string filename = args[0];
    DateTime start = DateTime.Now;
    bool done = false;
    while ((DateTime.Now - start).TotalSeconds < 30 && !done)
    {
        try
        {
            StreamReader sr = new StreamReader(new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
            string[] runData = new string[2];
            runData[0] = sr.ReadLine();
            runData[1] = sr.ReadLine();
            Thread.Sleep(1000);
            Process.Start(new ProcessStartInfo { FileName = runData[0], WorkingDirectory = runData[1] });
            sr.Dispose();
            File.Delete(filename);
            done = true;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        Thread.Sleep(1000);
    }
}

#17


0  

How about create a bat file, run the batch file before closing, and then close the current instance.

如何创建一个bat文件,在关闭之前运行批处理文件,然后关闭当前实例。

The batch file does this:

批处理文件是这样做的:

  1. wait in a loop to check whether the process has exited.
  2. 在循环中等待检查进程是否已退出。
  3. start the process.
  4. 启动过程。

#18


0  

I use the following and it does exactly what you are looking for:

我用下面的方法来做你想要的:

ApplicationDeployment ad = ApplicationDeployment.CurrentDeployment;
UpdateCheckInfo info = null;
info = ad.CheckForDetailedUpdate();
if (info.IsUpdateRequired)
{
    ad.UpdateAsync(); // I like the update dialog
    MessageBox.Show("Application was upgraded and will now restart.");
    Environment.Exit(0);
}

#19


0  

for using As logout you need to terminate all app from Ram Cache so close The Application first and then Rerun it

要使用As注销,您需要终止所有来自Ram缓存的应用程序,因此首先关闭应用程序,然后重新运行它

//on clicking Logout Button

/ /点击注销按钮

foreach(Form frm in Application.OpenForms.Cast<Form>().ToList())
        {
            frm.Close();
        }
System.Diagnostics.Process.Start(Application.ExecutablePath);

#20


0  

The problem of using Application.Restart() is, that it starts a new process but the "old" one is still remaining. Therefor I decided to Kill the old process by using the following code snippet:

使用Application.Restart()的问题是,它启动了一个新进程,但“旧”进程仍然存在。为此,我决定使用以下代码片段来终止旧的进程:

            if(Condition){
            Application.Restart();
            Process.GetCurrentProcess().Kill();
            }

And it works proper good. In my case MATLAB and a C# Application are sharing the same SQLite database. If MATLAB is using the database, the Form-App should restart (+Countdown) again, until MATLAB reset its busy bit in the database. (Just for side information)

而且效果很好。在我的例子中,MATLAB和c#应用程序共享同一个SQLite数据库。如果MATLAB使用的是数据库,那么表单应用程序应该重新启动(+倒计时),直到MATLAB重新启动数据库中繁忙的部分。(只是为了信息)