C# Interop - 无法创建对象
我创建了一个 C# COM 对象,并尝试从 VBscript(在 Windows Scripting Host 下)实例化它。
程序集正确构建等,并且 RegAsm 声称它已成功注册。但是,每当我尝试在 .vbs 脚本中实例化它时,我都会得到:
错误:无法创建名为的对象
“MyProgId.blah”代码:80040154
我正在运行 Win7 x64 Ultimate,该对象是使用 VS2010 为 .NET 3.5 构建的。
我还尝试将编译后的 DLL 复制到 Win Server 2003 计算机上,并得到相同的结果。
帮助。
另外,值得注意的是:我可以注册但不能实例化任何旧的 VB6 COM DLL。 (是的,我正在以管理员身份运行脚本。)
更新
只是为了开心,我创建了一个测试应用程序,它使用 Type.GetFromProgID()
来查找并创建对象:
Type t = Type.GetTypeFromProgID(progId);
if (t == null)
{
Console.WriteLine("Couldn't create object.");
}
else
{
var obj = Activator.CreateInstance(t);
Console.WriteLine("Successfully created Object: Type is [{0}]", obj);
Console.WriteLine("Calling method [{0}]\n\n", methodName);
var result = t.InvokeMember(methodName, BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null);
Console.WriteLine("Result: {0}", result);
}
这工作正常。然而,尝试从 VBscript 创建对象仍然失败。
啊。
更新,第二次
运行 SysInternals ProcMon 后,我看到很多注册表查询在 HKCU\Software\Classes\...
下查找 progID 和 guid,其中有没有提及该对象(当我查看 RegEdit 时)。有不少 NAME NOT FOUND
错误。
我尝试注册 %windir%\microsoft.net\framework\v4...
和 framework64
版本的 regasm
,但没有影响。
I've created a C# COM object, and am trying to instantiate it from VBscript (under Windows Scripting Host).
The assembly builds correctly, etc, and RegAsm claims that it is successfully registered. However, whenever I try to instantiate it in a .vbs script, I get:
Error: Could not creawte object named
"MyProgId.blah" Code: 80040154
I'm running Win7 x64 Ultimate, object built for .NET 3.5 with VS2010.
I also tried copying the compiled DLL over to a Win Server 2003 machine, and I get the same results there.
Help.
Also, of note: I can register, but not instantiate, any of our old VB6 COM DLLs. (Yes, I am running the script as administrator.)
Update
Just for grins, I created a test application that uses Type.GetFromProgID()
to find and create the object:
Type t = Type.GetTypeFromProgID(progId);
if (t == null)
{
Console.WriteLine("Couldn't create object.");
}
else
{
var obj = Activator.CreateInstance(t);
Console.WriteLine("Successfully created Object: Type is [{0}]", obj);
Console.WriteLine("Calling method [{0}]\n\n", methodName);
var result = t.InvokeMember(methodName, BindingFlags.Default | BindingFlags.InvokeMethod, null, obj, null);
Console.WriteLine("Result: {0}", result);
}
This works correctly. Attempting to create the object from VBscript, however, still fails.
Argh.
Update, the 2nd
After running SysInternals ProcMon, I see quite a few registry queries looking for the progID and guid under HKCU\Software\Classes\...
, where there is no mention of the object (when I look in RegEdit). There are quite a few NAME NOT FOUND
errors.
I've tried registering with the %windir%\microsoft.net\framework\v4...
and framework64
versions of regasm
, with no effect.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这与此类 COM 问题非常相关。该错误消息意味着 COM 客户端无法找到 COM 服务器的注册表信息。 64 位版本的 Windows 有两个 VB 脚本解释器,一个 64 位版本和一个 32 位版本。不同位数的进程有不同的注册表视图,64 位客户端无法看到 32 位 COM 服务器。反之亦然。
重要的是您使用的 Regasm.exe 版本。有两个,一个在C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe,另一个在Framework64。默认情况下,您运行 32 位版本,该版本在注册表的 32 位视图中输入注册信息。您应该使用 Framework64 中的 64 位版本。或者同时使用两者,.NET 创建可以在两种位数下运行的 COM 服务器。
如果仍然遇到问题,请使用 SysInternals 的 ProcMon 工具查看脚本解释器在何处查找 CLSID 密钥。
That's very relevant to COM issues like these. The error message means that the COM client could not find the registry information for the COM server. The 64-bit version of Windows has two VB-script interpreters, a 64-bit and a 32-bit version. Processes with different bitness have a different view of the registry, a 64-bit client cannot see 32-bit COM servers. And the other way around.
What matters is what version of Regasm.exe you used. There are two, one in C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe, another in Framework64. You by default run the 32-bit version which enters registration info in the 32-bit view of the registry. You should use the 64-bit version from Framework64 instead. Or use both, .NET creates COM servers that can run in both bitnesses.
If you still have trouble then use SysInternals' ProcMon tool to see where the script interpreter is looking for the CLSID key.
如果您在 64 位操作系统下运行 32 位界面,则可以通过使用 \windows\syswow64 下的 wscript/cscript(而不是 \windows\system32 下的默认值)运行脚本来解决 VBScript 错误。这让我绊倒了一天。
If you're running a 32-bit interface under a 64-bit OS, you can get around that VBScript error by using the wscript/cscript under \windows\syswow64 (instead of the default under \windows\system32) to run your script. That tripped me up for a day.
我认为您可能正在考虑安全问题。
查看此 stackoverflow 帖子,看看这是否可以解决您的问题。
无法实例化 .Net COM 对象在经典 ASP/VBScript 页面中(错误 ASP 0177)
I think that it is possible you are looking at a security issue.
Check out this stackoverflow post and see if this solves your issue.
Cannot instanciate .Net COM object in classic ASP/VBScript page (Error ASP 0177)