Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem launching a System.Diagnostics.Process under Windows 7

I’m trying to launch an application (Operating System, My Application and the application I want to launch are all 32 bits), from .NET 3.51.

The code that launches the Process is used for other applications, but there’s one that is giving us a headache. If we “double click” on the application’s icon, it works as expected, meaning that it works fine as an application in the computer. Double clicking the .exe directly, also works.

The operating system is Windows 7 32Bits (Home and/or Professional).

Our .NET application is compiled with x86 to avoid problems.

The code that launches “Processes” is located inside a DLL (also 32 bits) made by us, basically it’s a simple DLL that holds some “Common Code” across the board, common methods, functions and stuff we use throughout our code. One of those methods look like this:

public static bool FireUpProcess( Process process, string path, bool enableRaisingEvents,
        ProcessWindowStyle windowStyle, string arguments )
    {
        if ( process != null )
        {
            try
            {
                process.StartInfo.FileName = @path;
                if ( arguments != null )
                {
                    if ( arguments != String.Empty )
                    {
                        process.StartInfo.Arguments = arguments;
                    }
                }
                process.StartInfo.WindowStyle = windowStyle;
                process.EnableRaisingEvents = enableRaisingEvents;
                process.Start();
            }
            catch
            {
                try
                {
                    process.Kill();
                }
                catch ( InvalidOperationException )
                {
                } // The process is not even created

                return false;
            }
        }
        else
        {
            return false;
        }
        return true;
    }

I don’t know who wrote this method, but it has been working for roughly six years with different applications, therefore I assume it’s “ok”. However, we have a customer with a piece of software that won’t launch when passed through that argument.

The arguments are:

  1. process is a System.Diagnostics.Process created with a simple "new Process();”
  2. path is a full path to the .exe “c:/path/to/my.exe”.
  3. enableRaisingEvents is false
  4. windowStyle is Maximized (but have tried others).

It gives a crappy MessageBox… which I have happily immortalized. It’s in spanish but the translation ought to be easy:

alt text

It says:

Application Error An unexpected exception has occurred for the program (0x0eedfade) at …

Googling that 0x0eedfade gives strange results that look scary, but the truth is, if I go to the .exe that I’m trying to launch and double click it, it works perfectly.

For The Record: If I try to launch other things (I.e.: Notepad.exe, Adobe Acrobat Reader) it works, but Firefox doesn’t open and doesn’t show an error.

This “some work, some doesn’t” behavior leads me to believe that there might be a problem with a Windows 7 security mechanism or similar that I don’t know.

What am I missing or doing wrong?

UPDATE: Ok; I’ve gotten a copy of the software. It’s a messy software but it works. Now that I can debug, I see that the program gives an error when launched with my FireUpProcess method.

As suggested I added the WorkingDirectory code, but here’s the code:

    public static bool FireUpProcess(Process process, string path, bool enableRaisingEvents, ProcessWindowStyle windowStyle)
    {
        if (process != null)
        {
            try
            {
                if ( !String.IsNullOrEmpty(@path) )
                {
                    process.StartInfo.FileName = @path;
                    process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);
                    process.StartInfo.WindowStyle = windowStyle;
                    // Suscribe to the exit notification
                    process.EnableRaisingEvents = enableRaisingEvents;
                    // Disable to prevent multiple launchs
                    Framework.Check.LogWarning("LAUNCHING EXTERNAL DEVICE WITH PATH: " + path);
                    process.Start(); // HERE The program reports the following:

alt text

That means, “The program could not be started because ddip.dll is missing… try reinstalling bla bla”.

The thing is, if I execute the same @path from the command line, the program opens perfectly:

alt text

That opens the program. And the same happens if I click on the “shortcut” that it’s located in the “programs” menu. There aren’t any parameters in that shortcut, it’s a simple call to the executable file.

So the question is now: What is the difference between my code and the other methods?

There has got to be something different that causes my process not to start.

Any ideas?

UPDATE AND SOLUTION

I made it work by using one of the below provided answers. Turns out that none directly pointed me to the solution, but they all gave me good ideas here and there.

I added an app manifest to our application (should have had it since the age of vista, don’t know why it wasn’t there in the 1st place). The app manifest I added by using VStudio 2008 add file -> app manifest.

In it, I made sure we have this:

<requestedExecutionLevel level=“asInvoker” uiAccess=“false” />

We don’t need admin or anything like that, but apparently Vista/7 need to know it.

After that was added, the process is correctly launched.

note: UseShellExecute is true by default (as suggested by some), you have to explicitly turn it to false if that’s what you want.

like image 481
Martin Marconcini Avatar asked Oct 29 '10 11:10

Martin Marconcini


People also ask

What is System diagnostics ProcessStartInfo?

ProcessStartInfo. Arguments Property (System. Diagnostics) Gets or sets the set of command-line arguments to use when starting the application.

How do I start a process in VB net?

Start another application using your . NET code As a . NET method, Start has a series of overloads, which are different sets of parameters that determine exactly what the method does. The overloads let you specify just about any set of parameters that you might want to pass to another process when it starts.

What is System Diagnostics C#?

TraceSource Class (System. Diagnostics) Provides a set of methods and properties that enable applications to trace the execution of code and associate trace messages with their source.

How can you tell if a process is completed in C#?

You can use Process. GetProcessesByName Method (String) to find whether a particular process is running or not.


2 Answers

You are not setting the process.StartInfo.WorkingDirectory property. There's plenty of poorly written software out there that assumes the working directory will be the directory in which the EXE is stored. At least add this line:

 process.StartInfo.WorkingDirectory = System.IO.Path.GetDirectoryName(@path);

The exception is however rather strange. I'd definitely recommend you tell the customer to update their anti-malware tools.

like image 167
Hans Passant Avatar answered Sep 22 '22 16:09

Hans Passant


If the exe has a manifest, you should set UseShellExecute to true on the process object before you call Start. It's not a bad idea in any case.

like image 34
Kate Gregory Avatar answered Sep 20 '22 16:09

Kate Gregory