如何在 Visual Studio 2012 中创建 HelloWorld COM 互操作

Posted

技术标签:

【中文标题】如何在 Visual Studio 2012 中创建 HelloWorld COM 互操作【英文标题】:How to create a HelloWorld COM Interop in Visual Studio 2012 【发布时间】:2014-02-15 10:19:52 【问题描述】:

首先,我是 COM 新手,目前很困惑。我在 MSDN 和一般网络上阅读了很多关于 COM 的文档,但其中很多似乎已经过时且过于复杂。

这是我认为让它发挥作用所必需的。还没有,所以我确定我遗漏了一些东西,但是通过提供我的食谱,我希望有人能发现问题:

    创建一个 C# 控制台应用程序项目。我把它命名为 CSharpApp 创建一个 C++ ATL 项目。我称之为 ComLib.Interop。 添加类(模板:ATL Simple Object),我称之为“InteropDemo” 在类视图中,右键单击 IInteropDemo 并添加方法 HelloWorld。 (已删除,保留以保持答案中的编号正确。) 编译。 将 ComLib.Interop.dll 的引用添加到 CSharpApp。 在编译好的 COM dll 上调用 regsrv32.exe,然后在“添加引用...”的 COM 选项卡中选择 DLL 在 Program.cs 的 Main 中,创建一个 InteropDemo 类并调用 HelloWorld。 利润。

感谢答案,我更新了问题以反映综合解决方案。

【问题讨论】:

我认为您不需要步骤 3、4。尝试不使用它们。 你可以说COM本身已经过时并且过于复杂,因此它不再真正被开发了。如果您对使用 C++ 开发 COM 服务器/对象很认真,那么我建议您阅读 Don Box 的《Essential COM》一书。在 90 年代末和 2000 年代初,Don 是 COM 大师,之后他开始着手开发 WCF 的第一个版本。价值不菲。 @Noseratio 不起作用,我得到this error。但是,在 ComLib.Interop.dll 上手动调用 tlbimp 是可行的,我可以添加 tlbimp 生成的 ComLib.InteropLib.dll。但后来我又遇到了最初的注册问题。更新了问题。 【参考方案1】:

尝试以下步骤:

    确保两个项目(非托管 C++ 和托管 C#)具有相同的位数(x86 或 x64)。为了清楚起见,假设它是 x86。 打开 Admin 命令提示符并注册您的 COM DLL:C:\Windows\SysWOW64\regsvr32.exe c:\full-path\ComLib.Interop.dllAdmin 身份运行 Visual Studio。执行步骤 1、2、4、5、6。不要做3。

看看你能不能达到 7。我认为这应该可行。

请注意,您只需要在开发机器上进行注册。独立的 COM 应该可以在其他任何地方工作。

【讨论】:

成功了:我可以在注册的 COM dll 上调用我的开发机器上的 HelloWorld。但是如果我打开隔离,它会得到一个构建错误:Problem isolating COM reference 'ComLibInteropLib': No registered classes were detected for this component. @Wilbert,错误还是警告?您确定这两个项目也是 x86、.NET 吗?你不能使用AnyCPU 两个项目都是 x64 的(我从 x64 开始就使用它,并使用 System32\regsrv32.exe 而不是 wow64 注册 dll)。我可以使用注册的 dll 执行我的 CSharpApp.exe,它会从 com dll 方法中打印出正确的 hello world 字符串。 到此,我也没有什么想法了,还是看看this吧。 谢谢。我添加了一个后续问题here【参考方案2】:

您可能在第 2 步出错了,因为您没有收到构建错误。向导为您添加的类的种类提供了多个选择。默认选择“C++ 类”,您需要选择 ATL +“ATL 简单对象”。

类视图窗口现在显示两个 类型正在添加,IInteropDemo 接口和实现该接口的 CInteropDemo 类。接下来右键单击 interface 类型(不是类)并使用“添加方法”。您现在还可以查看项目中的 IDL 文件,它应该类似于:

import "oaidl.idl";
import "ocidl.idl";

[
    object,
    uuid(CBA0D899-2F4C-4F1D-A935-C80CB981C153),
    dual,
    nonextensible,
    pointer_default(unique)
]
interface IInteropDemo : IDispatch
    [id(1)] HRESULT Method();
;
[
    uuid(ED14ACED-4FF9-4144-B302-CC48C481F28B),
    version(1.0),
]
library ATLProject4Lib

    importlib("stdole2.tlb");
    [
        uuid(8543642F-9927-451C-9784-6A7774418299)      
    ]
    coclass InteropDemo
    
        [default] interface IInteropDemo;
    ;
;

这足以构建它。在任何现代 Windows 版本上都应该失败,UAC 会阻止 COM 服务器注册。这需要第 0 步:通过右键单击快捷方式并选择“以管理员身份运行”来启动 Visual Studio。

【讨论】:

我确实做到了这一点,并基于 ATL 简单对象生成了一个类,并且我确实将方法添加到了接口中。如果我单击其中一个 IInteropDemo 界面(带有悬停文本“struct IInterfaceDemo”的界面),我会在下面的小框中看到 HellowWorld 函数。 我还检查了.idl文件,HelloWorld方法添加到了界面中。 谢谢。我添加了一个后续问题here

以上是关于如何在 Visual Studio 2012 中创建 HelloWorld COM 互操作的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Visual Studio 中创建独立的 exe? [复制]

使用 Visual Studio 2012/Blend 在 C# 中创建类似 Windows 8 的窗口 [关闭]

无法在 Visual Studio 2012 Ultimate SP1 x64 中创建或打开网站

如何在 Microsoft Visual Studio Express 2012 for Web 中将文件夹添加到项目中?

如何创建 Visual Studio 加载项来生成文件?

在 Visual Studio 项目中创建包含文件夹和 Lib 文件夹