System.Diagnostics.Process UseShellExecute究竟做了什么?

我有一个MSBuild任务执行(除其他外)调用xcopy。 我发现,当我从批处理文件运行MSBuild任务时,对xcopy的调用正确执行,并且无法执行或生成任何输出,这些输出可以让我知道当从另一个调用同一个批处理文件时发生了什么使用System.Diagnostics.Process的C#应用​​程序。

两个进程都启动时具有或多或少相同的结构:

waitProc.StartInfo.Arguments = "/C [executable]"; waitProc.StartInfo.FileName = "cmd.exe"; waitProc.StartInfo.UseShellExecute = false; 

此外,通过在xcopy命令中将“UseShellExecute”从false更改为true,我可以在两个用例中成功,但是命令无法在第三个用例中运行。 第三个用例是我们的自动构建系统,它是一个直接调用msbuild的Windows服务。 在我们的构建机器上发生故障的情况下,copy命令无限期挂起,我相信,因为System.Diagnostics.Process试图显示一个窗口,并且服务没有与它们关联的Windows桌面会话,所以它们不能显示窗口。

我尝试使用“CreateNoWindow”属性,并尝试将“WindowStyle”设置为“ProcessWindowStyle.Hidden”,但这不会改变构建计算机上的行为。

所有这些都说,我真正想知道的是UseShellExecute属性到底是什么,因为它似乎比MSDN文档建议的要多得多。

谢谢。

ProcessStartInfo.UseShellExecute告诉进程使用Windows Shell执行指定的应用程序。

如果没有此设置,则只能直接执行EXE文件。 通过设置此选项,您可以使用Windows Shell,这允许指定.doc文件并让关联程序打开文件。

但是,使用Windows Shell需要有效的桌面上下文,这就是您的第三个用例失败的原因。

通常,除非您使用Windows Shell,否则使用cmd.exe会出现问题。 您可能只想编写代码来直接处理“批处理”操作 – 即:使用System.IO命名空间中的类型方法进行复制。 这样可以完全避免这个问题。

来自文档 :

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

注意:如果UserName属性不是空引用(在Visual Basic中为Nothing)或空字符串,则UseShellExecute必须为false,否则在调用Process.Start(ProcessStartInfo)方法时将抛出InvalidOperationException。 使用操作系统shell启动进程时,可以启动任何文档(与具有默认打开操作的可执行文件关联的任何已注册文件类型),并使用Process组件对文件执行操作(如打印)。 当UseShellExecute为false时,您只能使用Process组件启动可执行文件。

注意:如果将ErrorDialog属性设置为true,则UseShellExecute必须为true。 当UseShellExecute为true时,WorkingDirectory属性的行为与UseShellExecute为false时的行为不同。 当UseShellExecute为true时,WorkingDirectory属性指定可执行文件的位置。 如果WorkingDirectory是空字符串,则当前目录被理解为包含可执行文件。

当UseShellExecute为false时,不使用WorkingDirectory属性来查找可执行文件。 相反,它由启动的进程使用,并且仅在新进程的上下文中具有意义。

‘UseShellExecute’IIRC的使用是允许explorer(主shell)执行进程而不是.NET运行时….除非有人纠正我错了…

你是否正确指定了WorkingDirectory? 您可以通过添加>c:\log.txt 2>c:\err.txt来查看命令的实际输出。运行此添加并检查这些文件