Process.Start 为什么会引发“系统找不到指定的文件”异常

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Process.Start 为什么会引发“系统找不到指定的文件”异常相关的知识,希望对你有一定的参考价值。

前言

偶然发现,如果想用如下代码在 .NET 6 中打开指定 URL:

Process.Start("https://baidu.com");

会引发异常:

而同样的代码在 .NET Framework 中是可以正常执行的。

难道,.NET 6 下的实现逻辑不一样?

深入探究

通过调用堆栈,我们发现最后调用的是StartWithCreateProcess方法:

对应的 .NET 6 源代码如下:

private bool StartCore(ProcessStartInfo startInfo)

    if (!startInfo.UseShellExecute)
    
        return this.StartWithCreateProcess(startInfo);
    
    return this.StartWithShellExecuteEx(startInfo);

这和 .NET Framework 中的实现逻辑基本一致:

public bool Start()

    this.Close();
    ProcessStartInfo processStartInfo = this.StartInfo;
    if (processStartInfo.FileName.Length == 0)
    
      throw new InvalidOperationException(SR.GetString("FileNameMissing"));
    
    if (processStartInfo.UseShellExecute)
    
      return this.StartWithShellExecuteEx(processStartInfo);
    
    return this.StartWithCreateProcess(processStartInfo);

那么问题出在哪呢?

通过 dnspy 调试 .NET Framework 版本的测试程序,我们发现,最后执行的是StartWithShellExecuteEx而不是StartWithCreateProcess方法:

而之所以走不同的逻辑分支,是由processStartInfo.UseShellExecute控制的。

所以,解决方案也很简单,设置UseShellExecute = true:

Process.Start(new ProcessStartInfo("https://baidu.com")  UseShellExecute = true );

结论

造成这样的原因,是因为UseShellExecute在 .NET 6 上默认为 false:

public bool UseShellExecute  get; set; 

而在 .NET Framework 上默认为 true:

[DefaultValue(true)]
[MonitoringDescription("ProcessUseShellExecute")]
[NotifyParentProperty(true)]
public bool UseShellExecute

    get
    
        return this.useShellExecute;
    
    set
    
        this.useShellExecute = value;
    


private bool useShellExecute = true;

UseShellExecute = false时,代码会将传入参数作为文件名使用,从而引发“系统找不到指定的文件”异常。

添加微信号【MyIO666】,邀你加入技术交流群

以上是关于Process.Start 为什么会引发“系统找不到指定的文件”异常的主要内容,如果未能解决你的问题,请参考以下文章

Process.Start() 打开 URL 有时会抛出 Win32Exception?

调用process.start时为什么StartInfo.stuff不起作用但Process.start在C#中工作正常

从 Process.Start 返回不同的引用

Process.Start() 啥都不做

当我调用 process.start() 时,Python 多处理进程只会停止我的代码运行

process.start() 参数