170
//
// Summary:
//     Gets or sets a value indicating whether to use the operating system shell
//     to start the process.
//
// Returns:
//     true to use the shell when starting the process; otherwise, the process is
//     created directly from the executable file. The default is true.
[DefaultValue(true)]
[MonitoringDescription("ProcessUseShellExecute")]
[NotifyParentProperty(true)]
public bool UseShellExecute { get; set; }

If we spawn a new process, when do we need to set UseShellExecute to True?

5 Answers 5

267

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.

4
  • 3
    Great Stuff, but you write that (with ShellExecute), "It[you claim] isn't possible to redirect the standard input / output / error handles" <-- Surely that is incorrect or inaccurate. Even with useShellExecute set to true, while indeed you can't do processStartInfo.RedirectStandardOutput=true, it seems to me you can still redirect standard output by doing process.Arguments= "cmd /c dir >c:\\crp\\a.a". Likewise from a run dialog box you can do cmd /c dir>c:\crp\a.a
    – barlop
    Commented Apr 24, 2016 at 22:51
  • 8
    also, you say that when UseShellExecute=false i.e. CreateProcess, won't check the path, but I see that even when I do "UseShellExecute=false" i.e. supposedly not checking the path, then process.FileName="cmd.exe" works so it is checking c:\windows\system32. And if I copy cmd.exe to c:\windows and name it cmmmd.exe then I do process1.FileName="cmmmd.exe" that works too so it's checking c:\windows so it seems like it's checking the path, or some bunch of directories.
    – barlop
    Commented Apr 24, 2016 at 23:29
  • 3
    MSDN docs agree with @barlop: "When UseShellExecute is false, the FileName property can be either a fully qualified path to the executable, or a simple executable name that the system will attempt to find within folders specified by the PATH environment variable."
    – Bob
    Commented Aug 18, 2016 at 12:05
  • 2
    By setting UseShellExecute to true I was able to share an environment variable (that was only created in the calling process). Very handy
    – Mitkins
    Commented Sep 20, 2018 at 6:43
20

I think mostly for non-executables. For instance if are trying to open a .html file, if you'll have to set UseShellExecute to true and that will open the .html in a browser that's set as default by the user.

13

From MSDN:

Setting this property to false enables you to redirect input, output, and error streams.

UseShellExecute must be false if the UserName property is not null or an empty string, or an InvalidOperationException will be thrown when the Process.Start(ProcessStartInfo) method is called.

When you use the operating system shell to start processes, you can start any document (which is any registered file type associated with an executable that has a default open action) and perform operations on the file, such as printing, with the Process component. When UseShellExecute is false, you can start only executables with the Process component.

UseShellExecute must be true if you set the ErrorDialog property to true.

0

When the path contains a space or some other special (i.e. accented) characters, CreateProcess (UseShellExecute=false) seems to be using short file names ("DOS" 8.3 notation), ShellExecute (UseShellExecute=true) uses long file names. So when you use UseShellExecute=false, make sure to convert your directory and file names to 8.3 names (google ".net how to get 8.3 filename"). (Not exectly sure what Windows versions and/or file systems do it this way, tested on Windows 7, NTFS.)

1
  • Could it be that it is just cutting off the path at the space? Putting quotes around the "path/program name" solves this.
    – gbarry
    Commented Jun 27, 2019 at 19:00
-1

If we want to hide the current Application executable window , Then UseShellExecute should be set to true

Not the answer you're looking for? Browse other questions tagged or ask your own question.