在什么情况下Process.Start()方法返回false?

来自MSDN :

返回值true表示已启动新的进程资源。 如果StartInfo属性的FileName成员指定的进程资源已在计算机上运行 ,则不会启动其他进程资源。 相反,重用正在运行的进程资源并返回false。

尝试这样的事情:

var info = new ProcessStartInfo {FileName = @"CMD"}; var p1 = new Process { StartInfo = info }; var result = p1.Start(); //true result = p1.Start(); //true var p2 = new Process { StartInfo = info }; result = p2.Start(); //true 

如果我使用FilePath = @"c:\myapp.exe"而不是CMD则会得到相同的结果。

在什么情况下它会返回false

如果您查看参考源,您将看到Process.Start工作原理:

http://referencesource.microsoft.com/System/R/c50d8ac0eb7bc0d6.html

这是调用Process.Start时调用的两个方法之一。 请注意底部附近返回值true或false。 如果在启动进程后无法获取已启动进程的句柄,则仅返回False。

为了启动该过程,它使用NativeMethods.CreateProcess ,您可以在这里找到源代码: http : //referencesource.microsoft.com/System/compmod/microsoft/win32/NativeMethods.cs.html#9c52a5ca5f3eeea3

这只是Kernel32.CreateProcess的方法原型,其API可在此处找到: https : //msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v = Kernel32.CreateProcess

如果你查看返回值,它会说:

如果函数成功,则返回值为非零。 如果函数失败,则返回值为零。

我在CreateProcess的API中找不到任何内容,如果请求的进程已经运行,它会失败,也许如果进程无法启动,因为它是单实例应用程序(如Outlook),那么它可能会失败,但对于多个实例像命令提示符这样的应用程序,它不应该无法创建进程的句柄。

所以,在说了所有这些之后,MSDN文档可能不完全正确,我没有你的链接,但对于Process.Start(StartInfo) ,MSDN说这个关于返回值:

与流程资源关联的新流程,如果未启动流程资源,则为null。 请注意,与已经运行相同进程的实例一起启动的新进程将独立于其他进程。 此外,Start可能会返回一个非空进程,其HasExited属性已设置为true。 在这种情况下,启动的进程可能已激活其自身的现有实例,然后退出。

(我强调的重点)。 它并没有说如果它已经运行,它将失败。

对于Process.Start() ,它说:

返回值类型:System.Boolean如果启动了进程资源,则为true;否则为false。 如果没有启动新进程资源,则返回false(例如,如果重用现有进程)。

因此它表示如果重用现有流程 ,这完全取决于正在启动的应用程序或启动它的方法。

当您使用ProcessStartInfo.UseShellExecute = true(默认值)时,您可以从技术上获得错误的返回,并通过传递文档文件名来启动该过程。 并且shell以某种方式能够想出将文档打开请求传递给已经运行的进程实例。

唯一记录在案的情况是在Internet Explorer中打开一个网页。 可能还有其他一些,可能与传统DDE激活有关。 这是猜测。

这是Process.Start()的一般问题的特定情况,有很多单实例应用程序。 Office应用程序是最常见的示例。 您观察到的最典型的行为是该过程很快就会终止。 它刚刚检测到应用程序已在运行并使用process-interop来请求正在运行的实例打开文档。 .NET中也支持这种function。

您不知道哪个特定进程显示该文档,除非您知道它是单实例应用程序及其进程名称,因此您有希望使用Process.GetProcessesByName()找回它。 但这不是故障安全的,可能有一个不相关的进程正在运行,恰好具有相同的名称。 获得虚假的好处是你知道等待它终止是没有意义的。