Click here to Skip to main content
15,888,984 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I have written some code to check that all required files are present before starting a process. This is the code:
C#
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(); }
        }

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.
Posted
Updated 14-Nov-13 12:16pm
v2
Comments
Sergey Alexandrovich Kryukov 14-Nov-13 18:36pm    
I up-voted this answer with my 4, despite pretty naive attempt to solve the problem. It makes quite an interesting question, because solving it helps to understand some delicate mechanism of event-oriented architecture. I mean, if you consider Solution 3. :-)
—SA

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?
C#
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:

C#
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


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.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 14-Nov-13 18:34pm    
Sure, a 5.

I can suggest much simpler and elegant solution. Well, in a way. Also, it's a good exercise for understanding of things.
Please see Solution 3.

—SA
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.
C#
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)


[EDIT]

On second though, this can work in even funnier situation, right in the entry point of the application:
C#
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

[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
 
Share this answer
 
v6
Comments
Ron Beyer 14-Nov-13 21:01pm    
Another good solution, +5!
Sergey Alexandrovich Kryukov 14-Nov-13 23:22pm    
Thank you, Ron.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900