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

//
// 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?

113287 次浏览

来自 MSDN:

将此属性设置为 false 启用 您可以重定向输入、输出和 错误流。

如果下列情况,则 UseShellExecute 必须为 false UserName 属性不为空或 一个空字符串,或者一个 将是 当 Process.Start (ProcessStartInfo)方法 叫做。

当您使用操作系统时 Shell 启动进程,您可以 开始任何文件(即任何 关联的注册文件类型 默认打开的可执行文件 控件上执行操作 文件,例如打印,使用 过程组件 UseShellExecute 为 false,可以这样做 方法只启动可执行文件 过程组件。

如果您使用 将 ErrorDialog 属性设置为 true。

我认为主要是针对非可执行文件。例如,如果试图打开一个 .html文件,如果您必须将 UseShellExecute设置为 true,这将在用户设置为默认的浏览器中打开 .html

UseShellExecute布尔属性与使用 windows 执行函数和使用 创建过程函数有关——简短的回答是,如果 UseShellExecute为真,那么 Process类将使用 ShellExecute函数,否则它将使用 CreateProcess

更长的回答是,ShellExecute函数用于打开指定的程序或文件——它大致相当于在运行对话框中键入要执行的命令并单击 OK,这意味着它可以用于(例如) :

  • 使用默认浏览器打开 html 文件或 web,而不需要知道该浏览器是什么,
  • 无需知道 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个示例都不能正常工作(试试看)。

总之,如果:

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

相反,如果你想打开文档、 URL 或批处理文件等,你应该保持 UseShellExecute为真。.而不是显式地给出可执行文件的路径。

如果我们想隐藏当前的 Application 可执行窗口,那么 UseShellExecute 应该设置为 true

当路径包含一个空格或一些其他特殊字符时,CreateProcess (UseShellExecute = false)似乎使用短文件名(“ DOS”8.3表示法) ,ShellExecute (UseShellExecute = true)使用长文件名。 因此,当您使用 UseShellExecute = false 时,请确保将您的目录和文件名转换为8.3个名称(google“ .net how to get 8.3 filename”)。 (不太确定 Windows 版本和/或文件系统是这样做的,在 Windows 7,NTFS 上进行了测试。)