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

Hop*_*ess 12 .net c#

来自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
Run Code Online (Sandbox Code Playgroud)

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

在什么情况下会返回false

Ron*_*yer 11

如果您查看参考源,您将看到如何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.CreateProcessAPI 的方法原型,这里有API:https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v = vs.85).aspx

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

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

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

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

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

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

因为Process.Start(),它说:

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

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


Han*_*ant 6

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

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

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

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