【问题标题】:When do we need to set ProcessStartInfo.UseShellExecute to True?我们什么时候需要将 ProcessStartInfo.UseShellExecute 设置为 True?
【发布时间】:2011-07-12 10:09:06
【问题描述】:
//
// 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?

【问题讨论】:

    标签: c# .net winapi


    【解决方案1】:

    UseShellExecute 布尔属性与窗口 ShellExecute 函数与 CreateProcess 函数的使用有关 - 简短的回答是,如果 UseShellExecute 为真,那么 Process 类将使用 @987654326 @函数,否则会使用CreateProcess

    更长的答案是ShellExecute函数用于打开指定的程序或文件——大致相当于在运行对话框中输入要执行的命令并点击OK,也就是说它可以用来(例如):

    • 使用默认浏览器打开 .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,如果:

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

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

    【讨论】:

    • 好东西,但你写的是(使用 ShellExecute),“它[你声称]不可能重定向标准输入/输出/错误句柄”processStartInfo.RedirectStandardOutput=true,但在我看来,您仍然可以通过执行 process.Arguments= "cmd /c dir >c:\\crp\\a.a" 来重定向标准输出。同样,您可以在运行对话框中执行cmd /c dir>c:\crp\a.a
    • 另外,您说当UseShellExecute=false 即CreateProcess 时,不会检查路径,但我看到即使我执行“UseShellExecute=false”即应该不检查路径,然后处理。 FileName="cmd.exe" 有效,因此它正在检查 c:\windows\system32。如果我将 cmd.exe 复制到 c:\windows 并将其命名为 cmmmd.exe 然后我执行 process1.FileName="cmmmd.exe" 也可以,因此它正在检查 c:\windows 所以它似乎正在检查路径,或者一些目录。
    • MSDN 文档同意@barlop:“当 UseShellExecute 为 false 时,FileName 属性可以是可执行文件的完全限定路径,也可以是系统将尝试在指定文件夹中查找的简单可执行文件名称通过 PATH 环境变量。”
    • 通过将UseShellExecute 设置为true 我能够共享一个环境变量(仅在调用过程中创建)。很方便
    【解决方案2】:

    我认为主要用于非可执行文件。例如,如果尝试打开 .html 文件,则必须将 UseShellExecute 设置为 true,这将在用户设置为默认浏览器的浏览器中打开 .html

    【讨论】:

      【解决方案3】:

      来自MSDN

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

      UseShellExecute 必须为假,如果 UserName 属性不为 null 或 一个空字符串,或者一个 InvalidOperationException 将是 抛出时 Process.Start(ProcessStartInfo) 方法 被调用。

      当您使用操作系统时 shell 启动进程,你可以 开始任何文件(这是任何 与相关的注册文件类型 默认打开的可执行文件 动作)并在 文件,例如打印,与 流程组件。什么时候 UseShellExecute 为假,可以 仅启动可执行文件 进程组件。

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          【讨论】:

          • 会不会只是在空间处截断了路径?在“路径/程序名称”周围加上引号可以解决这个问题。
          猜你喜欢
          • 2017-03-02
          • 1970-01-01
          • 2019-07-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-30
          • 1970-01-01
          • 2011-09-20
          相关资源
          最近更新 更多