.Net Core 2.0 Process.Start 抛出“指定的可执行文件不是此 OS 平台的有效应用程序”

Posted

技术标签:

【中文标题】.Net Core 2.0 Process.Start 抛出“指定的可执行文件不是此 OS 平台的有效应用程序”【英文标题】:.Net Core 2.0 Process.Start throws "The specified executable is not a valid application for this OS platform" 【发布时间】:2018-03-30 05:13:34 【问题描述】:

我需要让 .reg 文件和 .msi 文件使用与用户 Windows 相关联的这两种文件类型的任何可执行文件自动执行。

.NET Core 2.0 Process.Start(string fileName) docs 说: “文件名不需要代表可执行文件。它可以是扩展名与系统上安装的应用程序相关联的任何文件类型。”

然而

using(var proc = Process.Start(@"C:\Users\user2\Desktop\XXXX.reg"))   //.msi also

给我

System.ComponentModel.Win32Exception (0x80004005): The specified executable is not a valid application for this OS platform.
   at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start(String fileName)

ErrorCode 和 HResult -2147467259,以及 NativeErrorCode 193。

相同的代码在 .Net Framework 3.5 或 4 控制台应用程序中确实有效。

我无法指定确切的 exe 文件路径作为方法的参数,因为用户的环境是不同的(包括 Windows 版本)并且不受我的控制。这也是我需要将程序移植到 .Net Core 的原因,试图让它作为SCD 控制台应用程序运行,这样就不需要安装特定的 .Net Framework 或 .NET Core 版本。

在 Visual Studio 调试运行和发布为 win-x86 SCD 时都会引发异常。我的 PC 是 Win7 64 位,我确信 .reg 和 .msi 与通常的 Windows PC 一样与常规程序相关联。

有解决办法吗?任何帮助表示赞赏。

【问题讨论】:

【参考方案1】:

您还可以将ProcessStartInfoUseShellExecute 属性设置为true

var p = new Process();
p.StartInfo = new ProcessStartInfo(@"C:\Users\user2\Desktop\XXXX.reg")
 
    UseShellExecute = true 
;
p.Start();

似乎是 .net Core 中的一个变化,正如 here 所记录的那样。

【讨论】:

UseShellExecutefalse 更改为 true 对我有用 :-) 见微软breaking changes doc here【参考方案2】:

您可以将 UseShellExecute 设置为 true,并将此路径和您的路径包含在 ProcessStartInfo 对象中:

Process.Start(new ProcessStartInfo(@"C:\Users\user2\Desktop\XXXX.reg")  UseShellExecute = true );

【讨论】:

将应用程序从 net48 转换为 netcoreapp3.1,dotnetcore 上需要“UseShellExecute = true”(在 Windows 上运行) 我使用的 .msg 文件没有打开。我收到此错误“System.ComponentModel.Win32Exception:'系统找不到指定的文件。' "。【参考方案3】:

如果这也困扰您:

对于我们这些习惯于简单地调用Process.Start(fileName); 的人来说,上面的语法可能会让我们感到焦虑......所以我可以补充一下,您可以用一行代码编写它吗?

new Process  StartInfo = new ProcessStartInfo(fileName)  UseShellExecute = true  .Start();

【讨论】:

这应该是公认的答案,效果很好 我同意@dgxhubbard 这应该是可接受的答案,因为这个答案会抑制命令窗口,而接受的答案不会(并且在应用程序打开时显示命令窗口)。【参考方案4】:

你必须执行 cmd.exe

var proc = Process.Start(@"cmd.exe ",@"/c C:\Users\user2\Desktop\XXXX.reg")

别忘了 /c

【讨论】:

这可行,但会一直打开一个 cmd 窗口,直到打开的应用程序关闭。例如,如果我想打开一个 doc 文件,cmd 窗口会一直打开,直到我关闭 Word。最好使用 UseShellExecute 的其他解决方案。 这不应该是公认的答案。使用带有 UseShellExecute = true 的 ProcessStartInfo 效果更好。【参考方案5】:

用它打开一个文件

new ProcessStartInfo(@"C:\Temp\1.txt").StartProcess();

需要这个扩展方法

public static class UT

    public static Process StartProcess(this ProcessStartInfo psi, bool useShellExecute = true)
    
        psi.UseShellExecute = useShellExecute;
        return Process.Start(psi);
    

【讨论】:

以上是关于.Net Core 2.0 Process.Start 抛出“指定的可执行文件不是此 OS 平台的有效应用程序”的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core 2.0中的HttpContext

Azure Functions .NET Core 中的 EF Core 2.0 连接字符串

.Net Core 2.0 Windows 服务

如何在 net-core 2.0 中手动解析 JSON 字符串

ASP.NET Core 2.0 新特性全新体验

.NET Core 2.0 身份和 jwt?