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

C# 在什么情况下Process.Start()方法返回false?,c#,.net,C#,.net,发件人: 返回值true表示已创建新的进程资源 开始如果由成员的文件名指定的进程资源 StartInfo属性已在计算机上运行,没有 其他进程资源已启动。相反,正在运行的进程 资源被重用,并返回false 试着这样做: var info = new ProcessStartInfo {FileName = @"CMD"}; var p1 = new Process { StartInfo = info }; var result = p1.Start(); //true result

发件人:

返回值true表示已创建新的进程资源 开始如果由成员的文件名指定的进程资源 StartInfo属性已在计算机上运行,没有 其他进程资源已启动。相反,正在运行的进程 资源被重用,并返回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

如果您查看参考源,您将看到
过程。Start
的工作原理:

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

为了启动流程,它使用
NativeMethods.CreateProcess
,您可以在此处找到其来源:

这只是
Kernel32.CreateProcess
的方法原型,API可以在这里找到:

如果查看返回值,它会显示:

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

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

所以,在说了所有这些之后,有可能MSDN文档并不完全正确,我没有您的链接,但是对于,MSDN说了关于返回值的以下内容:

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

(重点由我补充)。它并没有说如果调用已经运行,调用将失败

例如,它说:

返回值 类型:System.Boolean 如果流程资源已启动,则为true;如果未启动新流程资源(例如,如果重用现有流程),则为false

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

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

唯一记录在案的案例是在Internet Explorer中打开网页。可能还有其他原因,可能与遗留DDE激活有关。那是猜测

这是Process.Start()的一般问题的一个特殊情况,有很多单实例应用程序。Office应用程序是最常见的例子。您所观察到的最典型的行为是该过程很快再次终止。它只是检测到应用程序已在运行,并使用process interop请求正在运行的实例打开文档。这类功能也很重要


您将不知道哪个特定进程正在显示文档,除非您知道它是一个单实例应用程序及其进程名称,这样您就有希望通过process.getProcessByName()找到它。但是,这不是故障安全的,可能有一个不相关的进程正在运行,而该进程恰好具有相同的名称。获取false的好处是,您知道等待它终止是没有意义的。

FWIW可能重复,这取决于您是否使用Shell Execute开始进程,以下是确定它的实际代码:,。那么在什么实际情况下它可能是false?我尝试了outlook和运行windows服务(如Sql Server),一切都返回
True
@AlexK。我想我已经修复了在最后的编辑中,将在一秒钟内为实例方法添加链接的问题。@Vova当它无法为进程创建进程句柄时,返回false。Outlook可能有点不同,因为它是一个单实例应用程序,但将创建多个窗口。我不确定重用是否仅在
流程
用作表单应用程序上的
组件时发生。例如,我没有亲自运行代码测试进行验证。似乎另一个案例不涉及
CreateProcess
startInfo.UseShellExecute
)很可能不会创建新进程。如果您想在实践中得到false,可以尝试将一些.txt文件重命名为.exe,并尝试使用
process.Start
运行。在这种情况下,它将返回
False