.NET

.NET - WindowStyle = hidden vs. CreateNoWindow = true?

As Hans said, WindowStyle is a recommendation passed to the process, the application can choose to ignore it.

CreateNoWindow controls how the console works for the child process, but it doesn't work alone.

CreateNoWindow works in conjunction with UseShellExecute as follows:

To run the process without any window:

ProcessStartInfo info = new ProcessStartInfo(fileName, arg); 
info.CreateNoWindow = true; 
info.UseShellExecute = false;
Process processChild = Process.Start(info);

To run the child process in its own window (new console)

ProcessStartInfo info = new ProcessStartInfo(fileName, arg); 
info.UseShellExecute = true; // which is the default value.
Process processChild = Process.Start(info); // separate window

To run the child process in the parent's console window

ProcessStartInfo info = new ProcessStartInfo(fileName, arg); 
info.UseShellExecute = false; // causes consoles to share window 
Process processChild = Process.Start(info);

ProcessStartInfo.CreateNoWindow Property

true if the process should be started without creating a new window to contain it; otherwise, false. The default is false.

Remarks

If the UseShellExecute property is true or the UserName and Password properties are not null, the CreateNoWindow property value is ignored and a new window is created.

.NET Core does not support creating windows directly on Unix-like platforms, including macOS and Linux. This property is ignored on such platforms.

ProcessStartInfo.UseShellExecute Property

true if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true on .NET Framework apps and false on .NET Core apps.

Remarks

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

The word "shell" in this context (UseShellExecute) refers to a graphical shell (similar to the Windows shell) rather than command shells (for example, bash or sh) and lets users launch graphical applications or open documents.

Note

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, by using the Process object. When UseShellExecute is false, you can start only executables by using the Process object.

Note

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

If you set the WindowStyle to ProcessWindowStyle.Hidden, UseShellExecute must be set to true.

WorkingDirectory

The WorkingDirectory property behaves differently depending on the value of the UseShellExecute property.

When UseShellExecute is true, the WorkingDirectory property specifies the location of the executable. If WorkingDirectory is an empty string, it is assumed that the current directory contains the executable.

When UseShellExecute is false, the WorkingDirectory property is not used to find the executable. Instead, it is used only by the process that is started and has meaning only within the context of the new process. 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.

    string text = startInfo.WorkingDirectory;
                    if (text == string.Empty)
                    {
                        text = Environment.CurrentDirectory;
                    }
                    bool flag2;

    flag2 = NativeMethods.CreateProcess(null, stringBuilder, null, null, true, num2, intPtr, text, startupinfo, process_INFORMATION);

 // Microsoft.Win32.NativeMethods
// Token: 0x06000159 RID: 345
[DllImport("kernel32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool CreateProcess([MarshalAs(UnmanagedType.LPTStr)] string lpApplicationName, StringBuilder lpCommandLine, NativeMethods.SECURITY_ATTRIBUTES lpProcessAttributes, NativeMethods.SECURITY_ATTRIBUTES lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, [MarshalAs(UnmanagedType.LPTStr)] string lpCurrentDirectory, NativeMethods.STARTUPINFO lpStartupInfo, SafeNativeMethods.PROCESS_INFORMATION lpProcessInformation);

When do we need to set 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.

原文地址:https://www.cnblogs.com/chucklu/p/13214745.html