c# - 无法创建 C# COM DLL。是代码吗?项目属性?安装程序属性? 32-64 位?什么?

标签 c# visual-studio-2010 dll com installation

目标:创建一个名为 TestDLL.dll 的 C# 程序集,它可以安装到任何计算机上,以便 MS Access VBA 可以通过 COM 使用它。

环境: Windows 7 64 位。
MS Office Professional Plus 2010 版本:14.0.1753.5000(64 位)。
Visual Studio 2010 专业版。

TestDLL.dll汇编代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace TestDLL
{
    [ComVisible(true)]
    [Guid("7CAAEF3F-F867-445B-B078-5837A833620A")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface IGreeting
    {
        string SayHello();
    }

    [ComVisible(true)]
    [ProgId("TestDLL.Greeting")]
    [Guid("73D4187A-F71D-4E45-832A-6DD9F88CC59B")]
    [ClassInterface(ClassInterfaceType.None)]
    public class Greeting : IGreeting
    {
        [ComVisible(true)]
        public string SayHello()
        {
            return "Hello, World!";
        }
    }
}

添加到解决方案的 WinForms 项目成功调用了 SayHello() 方法。

TestDLL项目属性:
应用程序/目标框架 - .NET Framework 4
应用程序/程序集信息/使程序集 COM 可见:false(我只希望程序集中的某些公共(public)类对 COM 可见,而不是所有公共(public)类。即使对于这个演示只有一个类,我确实希望它是 COM -可见。上面的代码应该已经解决了这一点。)
Application/Assembly Information/Title and Description and Company and Product 都是“TestDLL”。
构建/平台:事件(任何 CPU)
构建/平台目标:x86
为 COM 互操作构建/注册:false(我不希望它只在我的计算机上工作,而是在所有计算机上工作。因此我想在安装时注册程序集,而不是在构建时注册。)
对程序集签名/签名:false(我希望程序集位于安装文件夹中,而不是 GAC 中。)

看一眼 AssemblyInfo.cs 就会发现:

[assembly: ComVisible(false)]
[assembly: Guid("6bf701f9-3953-43bb-a8af-1bdf7818af3c")]

程序集已构建。 然后使用 Visual Studio 命令提示符(以管理员身份运行)和以下命令创建类型库:

tlbexp "C:\(path)\bin\Release\TestDLL.dll" /win32 /out:"C:\(path)\bin\Release\TestDLL.tlb"

名为 SetupTestDLL 的 Visual Studio 安装程序项目已添加到解决方案中。
在其文件系统选项卡上,应用程序文件夹中添加了 TestDLL.dll。这也会自动添加 TestDLL.tlb。
右键单击该应用程序文件夹中的 TestDLL.dll 允许打开属性窗口。 在那里,注册:vsdraCOM
右键单击该应用程序文件夹中的 TestDLL.tlb 以获取属性窗口时:
注册:vsdrfCOM
(我猜 vsdraCOM 意味着注册程序集,而 vsdrfCOM 意味着为 COM 注册一个文件。)
Application 文件夹中又添加了一个文件:TestDLL.pdb。

SetupTestDLL 已构建。 浏览到其输出文件夹,显示 setup.exe 和 setupTestDLL.msi。 右键单击 setup.exe 并以管理员身份运行。 一个对话框显示正确的安装路径和正确的“为所有人安装”选项。 安装成功完成。

在控制面板/程序和功能中,现在列出了 TestDLL。它的出版商被列为“XYZ”。那个是从哪里来的?从 SetupTestDLL 项目属性窗口的“Manufacturer”属性可以看出。我只在整个解决方案中创造了那个值(value)。

在 C:\Program Files (x86) 中现在有一个“XYZ”文件夹,在该文件夹下是一个 TestDLL 文件夹,里面是三个文件。

启动 MS Access。打开现有数据库及其现有代码模块。 从访问代码窗口工具栏中,选择工具/引用。 TestDLL 位于可用引用列表框中。单击其复选框并单击确定。

单击代码窗口工具栏上的“对象浏览器”按钮。 在下拉列表中选择。将其更改为 TestDLL。 类“Greeting”与其方法“SayHello”一起显示。到目前为止,还不错。
关闭对象浏览器。
在代码模块中创建此过程并尝试运行它。

Public Sub Test2()
    '    Dim o As New TestDLL.Greeting 
    ' The above is early binding. It should also work 
    ' since we set a reference.
    Dim o As Variant
    Set o = CreateObject("TestDLL.Greeting")
    ' The above is late binding.
    Debug.Print o.SayHello()
    Set o = Nothing
End Sub

结果: 无论是早绑定(bind)还是晚绑定(bind), ActiveX 组件无法创建对象。

怎么了?

最佳答案

我只是想添加评论,但我没有足够的声誉点数,所以我只是将其发布为答案并在必要时将其删除。

我不熟悉 Visual Studio 安装程序项目,所以我不确定它是否正确注册了程序集。您是否尝试过使用 regasm 注册 TestDLL?像这样的东西:

regasm /codebase TestDLL.dll /tlb:TestDLL.tlb

关于c# - 无法创建 C# COM DLL。是代码吗?项目属性?安装程序属性? 32-64 位?什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32339928/

相关文章:

c# - 如何让 View 模型的属性设置所有关联子控件的高度/宽度

c# - 字典与数据库(Mysql)

.net - 从挂起的更改中忽略某些文件

在 DLL 中使用 TTask 时 Delphi FreeLibrary 卡住

从 VB.net 调用 DLL 导致堆异常

c# - DllImport 在 Windows XP SP3 上失败,但在 Windows 7 上有效

c# - 为什么在 DataTable 上调用 AsEnumerable() 会阻止 GridView 绑定(bind)到它?

c++ - 没有 IDE 的 Visual Studio 2010

c++ - Unresolved inclusion : <thread>

windows - 如何检查哪个应用程序正在使用msvcr80.dll?