为什么从 C# 启动时从 VB 调用 C# COM 对象时出现 0x80070002 错误?

Why do I get 0x80070002 error calling a C# COM object from VB when launched from C#?

我在使用 regasm.exe 注册的 dll 中有一个 C# COM 对象。 我在 COM 对象上创建对象并在 vbs 脚本 运行 中使用 cscript.

调用该对象的方法

如果我在命令行上 运行 这一切正常,创建对象通过 com 调用方法。

cscript.exe c:\mypath\myvb.vbs argument

我现在正在尝试 运行 从 C# 中执行相同的命令。我使用 System.Diagnostics.Process 方法

ProcessStartInfo si = new ProcessStartInfo();
si.Filename = "cscript.exe";
si.Arguments = "c:\mypath\myvb.vbs argument";
Process exe = ProcessStart(si);
...

当我 运行 这样我得到 0x80070002 错误,这基本上是一个找不到文件的错误。我不明白为什么它从 C# 到命令行不同。

编辑 - 更多信息

我运行正在使用 64 位 OS。 C# COM dll 是用 "AnyCPU" 构建的。 我使用了 64 位 regasm。 我使用的 cscript 来自 c:\windows\system32 所以它是 64 位版本。

如果我故意使用 32 位版本的 cscript,我也会从命令行收到 0x80070002 错误。这让我怀疑 c# 的问题是相关的,但我还是不明白。

"File not found" 不是您在这种情况下预期的第一种错误。不过肯定是可以的,你要注册程序集两次。使用 64 位版本的 Regasm.exe 一次,以便写入 64 位注册表项。对于 32 位版本,它将密钥写入 HKLM\Software\Wow6432Node,32 位客户端程序在其中搜索密钥。

当然,这很容易被忽视,您从未提到这样做,所以这是一个大红旗。您通常会得到 "Class not registered",但这并没有发生,也许有一个我们不知道的更早的注册。就像 Visual Studio 注册它一样,您通常总是喜欢这样做,因为它可以防止注册表污染。对项目或文件的简单更改便可以触发 "File not found"。 运行 32 位版本的 Regasm 时忘记 /codebase 选项是另一种方法。

最好的办法就是不要猜测这个。使用 SysInternals' Process Monitor 很容易诊断文件未找到错误。您会看到 cscript.exe 正在搜索文件,但没有找到。该文件的名称为您提供了潜在原因的强烈暗示。从下往上查看轨迹以避免淹没在数据中。并先发制人地确保您使用 Regasm.exe 的两个版本,因为您知道这是必要的。