我们何时需要将UseShellExecute设置为True?


134
//
// 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; }

如果我们生成一个新进程,什么时候需要将UseShellExecute设置为True?

Answers:


202

UseShellExecute布尔属性是关系到使用的Windows ShellExecute的功能VS的CreateProcess的功能-简单的答案是,如果UseShellExecute为真,那么Process类将使用该ShellExecute功能,否则它会使用CreateProcess

较长的答案是该ShellExecute函数用于打开指定的程序或文件-与在运行对话框中键入要执行的命令并单击“确定”大致等效,这意味着该函数可用于(例如):

  • 使用默认浏览器打开.html文件或网络,而无需知道该浏览器是什么,
  • 打开Word文档,而无需知道Word的安装路径是什么
  • 在上运行任何命令 PATH

例如:

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

它非常易于使用,用途广泛且功能强大,但存在一些缺点:

  • 不可能重定向标准输入/输出/错误句柄

  • 不可能为子进程指定安全描述符(或其他很酷的东西)

  • 如果您对将实际运行的内容进行假设,则有可能引入安全漏洞:

     // 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是启动进程的一种更为精确的方法-它不搜索路径,并允许您重定向子进程的标准输入或输出(除其他外)。CreateProcess但是,缺点是我上面给出的3个示例都不起作用(尝试一下然后看看)。

总之,UseShellExecute如果满足以下条件,则应将其设置为false:

  • 您想重定向标准输入/输出/错误(这是最常见的原因)
  • 您不想在可执行文件的路径中搜索(例如,出于安全原因)

相反,UseShellExecute如果要打开文档,URL或批处理文件等,则应保持true,而不是必须显式提供可执行文件的路径。


2
很好,但您用ShellExecute写道:“ [您声称]无法重定向标准输入/输出/错误句柄” <-肯定不正确或不正确。即使将useShellExecute设置为true,尽管确实不能执行 processStartInfo.RedirectStandardOutput=true,但在我看来,您仍然可以通过执行重定向标准输出 process.Arguments= "cmd /c dir >c:\\crp\\a.a"。同样,您可以从运行对话框中进行操作cmd /c dir>c:\crp\a.a
barlop

4
另外,您说当UseShellExecute=falseCreateProcess时,不会检查路径,但是我看到即使我执行“ UseShellExecute = false”,即据说不检查路径,然后process.FileName =“ cmd.exe”也可以正常工作检查c:\ windows \ system32。而且,如果我将cmd.exe复制到c:\ windows并将其命名为cmmmd.exe,那么我也会执行process1.FileName =“ cmmmd.exe”,该方法也可以正常工作,因此它正在检查c:\ windows,因此似乎正在检查路径,或者一些目录。
barlop

2
MSDN文档同意@barlop:“当UseShellExecute为false时,FileName属性可以是可执行文件的完全限定路径,也可以是系统将尝试在PATH环境变量指定的文件夹中找到的简单可执行文件名。”
鲍勃

通过设置UseShellExecute为,true我可以共享一个环境变量(仅在调用过程中创建)。非常方便
Mitkins

14

我认为主要是针对非可执行文件。例如,如果要打开.html文件,则必须将其设置UseShellExecutetrue,这将.html在用户设置为默认的浏览器中打开。


12

MSDN

将此属性设置为false可使您重定向输入,输出和错误流。

如果UserName属性不为null或为空字符串,则UseShellExecute必须为false,否则在调用Process.Start(ProcessStartInfo)方法时将引发InvalidOperationException。

使用操作系统外壳程序启动进程时,可以启动任何文档(与具有默认打开操作的可执行文件关联的任何已注册文件类型),并使用Process组件对该文件执行操作,例如打印。如果UseShellExecute为false,则只能使用Process组件启动可执行文件。

如果将ErrorDialog属性设置为true,则UseShellExecute必须为true。


0

如果我们要隐藏当前的Application可执行文件窗口,则UseShellExecute应该设置为true


0

当路径包含空格或其他特殊字符(带重音符号)时,CreateProcess(UseShellExecute = false)似乎正在使用短文件名(“ DOS” 8.3表示法),ShellExecute(UseShellExecute = true)使用长文件名。因此,当您使用UseShellExecute = false时,请确保将目录和文件名转换为8.3名称(Google“ .net如何获取8.3文件名”)。(不完全确定哪些Windows版本和/或文件系统以这种方式进行了此操作,并已在Windows 7,NTFS上进行了测试。)


难道它只是切断了空间的路径?在“路径/程序名称”两边加上引号可以解决此问题。
gbarry
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.