当应用程序被告知退出时,进程仍然会启动 [英] Process still starts when application is told to exit

查看:103
本文介绍了当应用程序被告知退出时,进程仍然会启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了一些代码来检查在开始进程之前是否存在所有必需的文件。这是代码:

I have written some code to check that all required files are present before starting a process. This is the code:

public void LaunchServices()
        {
            string LaunchConfig = "C:/Users/Henry/AppData/Local/WeatherLink/LaunchConfig.xml";
            if (File.Exists(LaunchConfig))
            {
                XmlDocument config = new XmlDocument();
                config.Load(LaunchConfig);

                string MainExecutable = "";
                string ExceptionModule = "";
                string FilesystemModule = "";

                try
                {
                    MainExecutable = config.SelectSingleNode("//MainExecutable").InnerText;
                    ExceptionModule = config.SelectSingleNode("//ExceptionModule").InnerText;
                    FilesystemModule = config.SelectSingleNode("//FilesystemModule").InnerText;
                }
                catch (NullReferenceException)
                { MessageBox.Show("Weather Link cannot start because the module reference file is corrupted"); Application.Exit(); }

                if (File.Exists(ExceptionModule)) { Process.Start(ExceptionModule); }
                else { MessageBox.Show("Weather Link cannot start because the exception module does not exist or is corrupted"); Application.Exit(); }
                if (File.Exists(FilesystemModule)) { Process.Start(FilesystemModule); }
                else { MessageBox.Show("Weather Link cannot start because the filesystem watcher module does not exist or is corrupted"); Application.Exit(); }
                if (File.Exists(MainExecutable)) { Process.Start(MainExecutable); }
                else { MessageBox.Show("Weather Link cannot start because the main executable file does not exist or is corrupted"); Application.Exit(); }
            }
            else { MessageBox.Show("Weather Link cannot start because the module reference file is missing"); Application.Exit(); }
        }



目前,异常模块的消息框是唯一显示但在我的XML文件中唯一正确的是主可执行文件的路径,其他2是空的。真正的问题是它在解除消息框后没有退出。如果我单击确定,主可执行文件启动但不应该,因为我告诉它在所有消息框后关闭。怎么了?我似乎无法解决它。


At the moment, the message box for the exception module is the only one that shows but in my XML file the only thing that is correct is the path to the main executable, the other 2 are empty. The real problem is that it is not exiting after dismissing the message box. If I click OK, the main executable starts but it shouldn't because I have told it to close after all message boxes. What is wrong? I cannot seem to solve it.

推荐答案

好的,首先你必须学会​​正确格式化你的代码,让一行上的所有内容都很难阅读,并且更难调试。



这看起来更容易阅读吗?

Ok, first you have to learn to properly format your code, having everything on a single line is very difficult to read, and even more difficult to debug.

Does this look easier to read?
if (File.Exists(ExceptionModule)) 
{ 
    Process.Start(ExceptionModule); 
}
else
{
    MessageBox.Show("Weather Link cannot start because the exception module does not exist or is corrupted"); 
    Application.Exit(); 
}

if (File.Exists(FilesystemModule)) 
{ 
    Process.Start(FilesystemModule); 
}
else 
{ 
    MessageBox.Show("Weather Link cannot start because the filesystem watcher module does not exist or is corrupted"); 
    Application.Exit(); 
}
                
if (File.Exists(MainExecutable)) 
{ 
    Process.Start(MainExecutable); 
}
else 
{ 
    MessageBox.Show("Weather Link cannot start because the main executable file does not exist or is corrupted"); 
    Application.Exit(); 
}





好​​的,你应该做的第一件事就是检查所有模块是否存在,并且只在启动流程时启动它们都存在:





Ok, the first thing you should do is check if all the module exists, and only start the processes if they all exist:

if (!File.Exists(ExceptionModule) || !File.Exists(FilesystemModule) || !File.Exists(MainExecutable))
{
     //One of the modules don't exist, show an error and exit the application
}

//Start the modules here





除此之外,如果使用Process.Start启动进程,退出应用程序将不会停止进程。您必须使用Process.Start保存对ProcessInfo对象的引用,以便可以显式关闭它们。 Application.Exit不会为你做这件事。



On top of that, if you start a process with Process.Start, exiting your application will not stop the processes. You have to hold a reference to the ProcessInfo object using Process.Start so you can explicitly close them. Application.Exit will not do it for you.


这不是一个非常简单的问题,但你可以很容易地做到。



这是一个技巧:当你已经调用了 System.Windows.Forms.Application.Run(System.Windows.Forms.Form)时,你应该在某个地方执行此操作,比如,在主窗口的代码中的某个地方。如果你从它的构造函数中调用它,它肯定会起作用。让我们说,它是用表单构造函数调用的。

This is not a very trivial issue, but you can do it very easily.

Here is one trick: you should do it somewhere when the System.Windows.Forms.Application.Run(System.Windows.Forms.Form) is already called, say, somewhere in the code of the main window. If you call it from its constructor, it will certainly work. Let's say, it is called withing the form constructor.
internal MyForm() {

    //...

    if (/* ... */) {
        //...
    } else {
        MessageBox.Show("Weather Link cannot start because the module reference file is missing");
        //Application.Exit(); //remove it, won't work
        BeginInvoke(new System.Action(() => { System.Windows.Forms.Application.Exit(); })); //that's the real trick!
    } //if

} //MyForm (constructor)









第二,虽然这可以在更有趣的情况下工作,就在应用程序的入口点:





On second though, this can work in even funnier situation, right in the entry point of the application:

using System.Windows.Forms;
//...

void Main() {

    Form mainForm = // create your main form    

    if (/* ... */) {
        //...
    } else {
        MessageBox.Show("Weather Link cannot start [...] is missing");
        mainForm.BeginInvoke(new System.Action(() => {
            System.Windows.Forms.Application.Exit();
        })); 
        // practically, you can simply exit here... :-)
    } //if

    Application.Run(mainForm); // application will perform full event cycle
    // you will get all side-effect of starting and closing in place...

} //Main



[结束编辑]



注意,它应该是 BeginInvoke ,而不是调用。为什么?为什么 BeginInvoke 有效?我会把它作为你作业的练习。它将真正帮助您了解有关面向事件的编程如何工作的很多内容。 :-)



这是一个相对罕见的例子,当 BeginInvoke 很有用时,即使没有多线程也是如此参与!



-SA


[END EDIT]

Note, it should be BeginInvoke, not Invoke. Why? Why BeginInvoke works? I would leave it as the exercise for your homework. It will really help you to understand a lot about how event-oriented programming works. :-)

And this is one of the relatively rare example when BeginInvoke is useful even when no multithreading is involved!

—SA


这篇关于当应用程序被告知退出时,进程仍然会启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆