为什么我从c#启动时从VB调用c# COM对象时得到0x80070002错误

本文关键字:错误 0x80070002 对象 VB 启动 为什么 调用 COM | 更新日期: 2023-09-27 18:09:02

我在dll中有一个c# COM对象,我使用regasm.exe注册。我在COM对象上创建一个createObject,并在使用cscript运行的vbs脚本中调用该对象的方法。

如果我在命令行上运行这个,它就会正常工作,创建对象,通过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位操作系统上运行。c# COM dll是用"AnyCPU"构建的。我使用了64位的正则表达式。我使用的脚本来自c:'windows'system32,所以它是64位版本。

从命令行中,如果我故意使用32位版本的cscript,我也会得到0x80070002错误。这让我怀疑这个问题与c#有关,但我仍然不明白。

为什么我从c#启动时从VB调用c# COM对象时得到0x80070002错误

"File not found"并不是您在此场景中所期望的第一种错误。但这当然是可能的,您必须注册程序集两次。一次使用64位版本的Regasm.exe,以便写入64位注册表项。对于32位版本,它将密钥写入HKLM'Software'Wow6432Node,其中32位客户端程序搜索密钥。

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

最好的办法就是不要猜测。文件未发现错误是非常容易诊断SysInternals的进程监视器。您将看到cscript.exe搜索该文件,但没有找到它。文件的名称给了您一个非常强烈的提示,说明潜在的原因可能是什么。从下往上查看跟踪,以避免淹没在数据中。并且确保你使用了两个版本的Regasm.exe,因为你知道这是必要的。