When Do We Need to Set Processstartinfo.Useshellexecute to True

When do we need to set ProcessStartInfo.UseShellExecute to True?

The UseShellExecute boolean property is related to the use of the windows ShellExecute function vs the CreateProcess function - the short answer is that if UseShellExecute is true then the Process class will use the ShellExecute function, otherwise it will use CreateProcess.

The longer answer is that the ShellExecute function is used to open a specified program or file - it is roughly equivalnt to typing the command to be executed into the run dialog and clicking OK, which means that it can be used to (for example):

  • Open .html files or web using the default browser without needing to know what that browser is,
  • Open a word document without needing to know what the installation path for Word is
  • Run any command on the PATH

For example:

Process p = new Process();
p.StartInfo.UseShellExecute = true;
p.StartInfo.FileName = "www.google.co.uk";
p.Start();

It is very easy to use, versatile and powerful however comes with some drawbacks:

  • It isn't possible to redirect the standard input / output / error handles

  • It isn't possibly to specify security descriptors (or other cool things) for the child process

  • There is a potential to introduce security vulnerabilities if you make assumptions about what will actually be run:

     // If there is an executable called "notepad.exe" somewhere on the path 
    // then this might not do what we expect
    p.StartInfo.FileName = "notepad.exe";
    p.Start();

CreateProcess is a far more precise way of starting a process - it doesn't search the path and allows you to redirect the standard input or output of the child process (among other things). The disadvantage of CreateProcess however is that none of the 3 examples I gave above will work (try it and see).

In summary, you should set UseShellExecute to false if:

  • You want to redirect the standard input / output / error (this is the most common reason)
  • You don't want to search the path for the executable (e.g. for security reasons)

Conversely you should keep UseShellExecute true if you want to open documents, urls or batch files etc... rather than having to explicitly give the path to an executable.

How to decide whether or not to set ProcessStartInfo.UseShellExecute Property to true or false?

You can see in .NET source :

  • UseShellExecute = true =>

internal function StartWithShellExecuteEx => calls ShellExecuteEx

  • UseShellExecute = false =>

internal function StartWithCreateProcess => calls CreateProcessWithLogonW or CreateProcessW

You usually use true when you want to launch the executable asociated with an extension.
like :

            using (Process p = new Process())
{
string sImage = @"e:\test.jpg";
p.StartInfo.FileName = sImage;
p.StartInfo.Verb = "open";
p.StartInfo.UseShellExecute = true;
p.Start();
}

If I set false, it will fail because it will try to call CreateProcessW with "e:\test.jpg" as command line

What exactly does System.Diagnostics.Process UseShellExecute do?

ProcessStartInfo.UseShellExecute tells the Process to use the Windows Shell to execute the specified application.

Without this set, you can only execute an EXE file directly. By setting this, you allow the Windows Shell to be used, which allows things such as specifying a .doc file and having the associated program open the file.

However, using the Windows Shell requires a valid desktop context, which is why your third use case fails.

In general, using cmd.exe is problematic unless you're using the Windows Shell. You may want to just write the code to handle your "batch" operation directly - ie: use the methods from types in the System.IO namespace to do your copying. This would avoid this issue entirely.

How to set windows forms application useshellexecute to true?

You could try putting this at the start of your program:

Environment.CurrentDirectory = AppDomain.CurrentDomain.BaseDirectory;

That will ensure that your program's current working directory (CWD) is always set to the same folder as the executable when your program starts up.

I suspect what's happening is that the shortcut you're using has a missing or incorrect folder for its "Start in" property. Fixing that would be another approach (right-click the shortcut, select Properties and then the Shortcut tab, and enter the correct folder in the Start in section.)

what is the difference between ProcessStartInfo's UseShellExecute and CreateNoWindow?

It plays no role. The rule is that CreateNoWindow will only have an effect when:

  1. You use UseShellExecute = false so that the CreateProcess() winapi is used to start the program
  2. The program you start is a console mode application.

If the app is a native Windows GUI app that creates it own window then you can ask it to not create a visible window with WindowStyle = ProcessWindowStyle.Hidden. There are however a lot of programs that ignore this request. They should, only way to stop it is through Task Manager. Next reasonable choice is ProcessWindowStyle.Minimized



Related Topics



Leave a reply



Submit