代码之家  ›  专栏  ›  技术社区  ›  hughdbrown

如何在自动化服务器列表中安装并注册用vb.net编写的com服务器for excel?

  •  10
  • hughdbrown  · 技术社区  · 16 年前

    版本

    excel 2007、windows vista、vb.net、visual studio 2008和.net 3.5sp2、msi安装包。

    我要做的是

    我有一个用vb.net编写的excel自定义项。它作为COM服务器公开,因为不能直接用.NET语言创建Excel UDF。安装是一件很痛苦的事,因为没有一个安装设置看起来很正确;它们都没有提供一个安装包,将COM服务器放在已注册服务器、已注册类型库和在Excel 2007列表中可见的组件的客户端计算机上自动化服务器。

    我试过的

    下面是类型库的安装设置,它们的缺陷在编译时和安装时很明显:

    vsdrfcomselfreg

    • 在编译安装项目期间没有警告
    • 模块xxx.tlb注册失败。hresult-2147024703号
    • 组件的progid和guid在注册表中设置,但该组件不出现在自动化服务器列表中

    vsdrfdonoteregister

    • 编译期间无警告
    • 安装工程,但TLB当然没有注册

    VSDRFCOM

    • 编译时警告:警告:无法为名为“xxx.tlb”的文件创建注册信息
    • 安装期间未注册类型库

    正确的设置 应该 如前所述,是vsdrfcom here :

    有人能告诉我什么吗? vsdrfcom是指 视觉工作室?当我 检查“注册”属性 设置中添加的文件的属性 项目。

    它意味着visual studio将 在生成时提取COM注册数据 时间并将其放入msi文件中 (主要是msi文件的注册表, 还有班级表)。所以当你 安装它你的代码不需要 自注册,因为文件 复制到磁盘和注册表 创建条目。它也会 创建类型库注册 向msi的typelib添加条目 表。

    许多困难似乎是vista特有的。特别是,使用 REGCAP utility 从.tlb文件生成.reg文件在vista中不起作用。如果不是因为这个,也许 this advice would be useful . 相反,它会在工作时生成空的.reg文件。

    我试过所有的建议 this StackOverflow post . 那篇文章对技术问题有很好的描述:

    “引用”对话框中的条目 方框来自hkcr\typelib 注册表项,不是来自hkcr\clsid。如果 您的程序集未出现在 引用对话框,但编译的dll 仍然可以使用COM组件,它 意味着类和接口 正确注册 程序集,但类型库 本身不是。

    问题

    有人知道如何使安装注册组件和类型库吗?我无法访问Windows XP计算机。


    解释为什么这很糟糕

    .tlb不需要任何编译代码来调用它。我没有像您所做的那样尝试部署一个excel自动化插件,但我的猜测是udf应该加载并运行得很好。

    在excel中不是这样的。

    • 用户打开工作表并尝试引用自定义项。找不到它,因为未加载dll。 失败
    • 用户转到主页Excel选项加载项Excel加载项+转到,COM服务器未在加载项对话框中列出。 失败
    • 然后,用户按Automation Servers以获取可用自动化服务器的列表。dll不在那里。 失败
    • 用户返回到“加载项”对话框,选择“浏览”,导航到安装目录,然后选择dll(“xxx不是有效的加载项”)或类型库(“您选择的文件不包含新的自动化服务器,或者您没有足够的权限…”)。 失败

    据我所知,用户必须从命令行运行Reasas.EXE,以使Excel UDF/COM服务器可用。告诉人们从命令行运行regasm以将外接程序安装到excel中,您会有什么感觉?


    编辑2009-10-04

    迈克在下面的评论和指导非常棒。我不知道的关键是安装程序有一个 用于添加注册表项的内置注册表编辑器 . 哦,还有那个 微软安装程序没有调用具有COMRealStestFalm属性的安装函数 . 我已经从他引用的源代码中得到了编写安装程序函数的指导。

    1 回复  |  直到 10 年前
        1
  •  28
  •   Community Mohan Dere    8 年前

    我在周末尝试部署了一个自动化插件。结果发现它非常复杂(对你来说并不奇怪!)我在网上找不到任何关于如何正确处理的资料。一个也没有。

    有些资料描述了如何使用 RegAsm ,但是没有如何正确使用安装项目来注册自动化外接程序,这与您的标准COM外接程序略有不同。

    幸运的是,我能够解决它。我发现:

    如果您阅读了一些关于如何创建和注册c automation外接程序的文章,您将看到您需要添加一个名为 Programmable HKEY\_CLASSES\_ROOT\CLSID\\{GUID} 在哪里 {GUID} 是COM可见类的guid。

    这通常是通过添加一对由 ComRegisterFunctionAttribute 以及 ComUnregisterFunctionAttribute . 一个很好的例子来自于这篇文章 Writing Custom Excel Worksheet Functions in C# 加班贝里:

    // C#:
    
    [ComRegisterFunctionAttribute]
    public static void RegisterFunction(Type type) {
      Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type));
    }
    
    [ComUnregisterFunctionAttribute]
    public static void UnregisterFunction(Type type) {
      Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type), false);
    }
    
    private static string GetSubKeyName(Type type) {
      string s = @"CLSID\{" + type.GUID.ToString().ToUpper() + @"}\Programmable";
      return s;
    }
    

    翻译成vb.net,结果是:

    'VB.NET:
    
    <ComRegisterFunctionAttribute()> _
    Public Shared Sub RegisterFunction(ByVal type As Type)
        Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type))
    End Sub
    
    <ComUnregisterFunctionAttribute()> _
    Public Shared Sub UnregisterFunction(ByVal type As Type)
        Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type), false)
    End Sub
    
    Private Shared Function GetSubKeyName(ByVal type As Type) As String
        Dim s As String = ("CLSID\{" _
                    + (type.GUID.ToString.ToUpper + "}\Programmable"))
        Return s
    End Function
    

    ComRegisterFunctionAttribute 由自动调用 复律 注册此类的程序集时。以 ComUnregisterFunctionAttribute 由自动调用 复律 当通过 /u 开关。

    问题是 ComRegisterFunction属性 ComUnregisterFunctionary属性 通过Visual Studio安装项目安装时完全忽略。

    一开始这似乎很奇怪,因为visual studio安装项目运行 复律 使用 /regfile 切换以生成包含所有必需注册表项的.reg文件。然后使用这个.reg文件,然后在客户端站点上运行.msi包。

    Build and Deploy a .NET COM Assembly 菲尔·威尔逊:

    visual studio如何计算 COM类注册条目?好, 如果您已经配置了fusion日志 查看器(在.NET 2.0中为fuslogvw.exe sdk)记录程序集加载,运行 在你的设置和 你会注意到regasm.exe实际上 在构建安装程序期间运行 项目。但是,它不执行 任何登记。发生了什么事 visual studio使用 /ReFr档 创建.reg文件的选项 包含注册表项 需要获取的信息 步骤1,这个.reg文件是 内部导入到设置中 项目。如果你想看看 类注册项可视化 工作室将在MSI设置中创建, 你可以自己用 /ReFr档 选项

    当我自己使用 /ReFr档 不过,我注意到 可编程 开关是 包括在内。然后我将日志记录放在我的方法中,标记为 ComRegisterFunction属性 ComUnregisterFunctionary属性 发现它们在运行时都被调用 复律 没有 /ReFr档 切换,但是 在运行时调用 /ReFr档 切换,也不会在通过Visual Studio安装项目创建的.msi包运行时调用它们。

    这个 help files for Regasm.exe 确认(增加重点):

    你可以使用 /ReFr档 选择权 生成包含 注册表项而不是 直接更改到注册表。你 可以更新计算机上的注册表 通过使用 注册表编辑器工具(regedit.exe)。 注意,.Reg文件不包含任何可以注册的注册表更新。 由用户自定义寄存器生成 功能。

    然后,解决方案是添加 可编程 关键是我们自己。可以这样做:

    1. 在安装项目中,打开注册表编辑器。创建名为 CLSID 在下面 HKEY_CLASSES_ROOT 右键单击 香港大学根课程 文件夹,然后选择“新建”,然后选择“键”。
    2. CLSID key,为guid添加一个新的key,包括花括号。
    3. 在您添加的新guid密钥下,添加一个名为 可编程 . 您不需要将任何值放入这个键中;但是,我们确实需要强制创建它。因此,右键单击 可编程 键并选择“属性窗口”。然后改变 AlwaysCreate 属性到 True .

    完成此操作后,您不再需要标记为comRegisterFunctionattribute和comUnregisterFunctionattribute的方法,但在您通过regasm而不是通过安装项目进行安装时,我仍会保留这些方法。

    现在你已经准备好部署了。构建解决方案,然后右键单击安装项目并选择“构建”。然后,可以使用创建的StupU.EXE和.MSI文件部署到客户端机器。

    但是,还需要考虑的是,通过Excel的“加载项”对话框添加自动化加载项时,将显示一条错误消息,指出“找不到mscoree.dll,是否删除该加载项?”或者类似的东西。这个错误消息可以被忽略,并且你的外接程序将运行不管你回答什么,但是它可能会对安装你的外接程序的客户端造成警告。

    这篇文章很好地描述了这种情况,并解释了如何解决它 Writing user defined functions for Excel in .NET 作者:埃里克·卡特。

    问题是 InprocServer32 关键是 mscorree.dll ,这足以让.NET找到它,但会导致Excel抱怨。解决方案是确保inprocserver32键的默认值包含到系统目录的完整路径。例如,在32位窗口上,它应该读取 C:\Windows\system32\mscoree.dll . 但是,此路径需要根据安装它的系统而有所不同。所以这个路径不应该硬编码。

    Eric Carter通过修改 ComRegisterFunction属性 ComUnregisterFunctionary属性 如下:

    // C#: 
    
    [ComRegisterFunctionAttribute]
    public static void RegisterFunction(Type type)
    {
    
      Registry.ClassesRoot.CreateSubKey(
        GetSubKeyName(type, "Programmable"));
      RegistryKey key = Registry.ClassesRoot.OpenSubKey(
        GetSubKeyName(type, "InprocServer32"), true);
      key.SetValue("",
        System.Environment.SystemDirectory + @"\mscoree.dll",
        RegistryValueKind.String);
    }
    
    [ComUnregisterFunctionAttribute]
    public static void UnregisterFunction(Type type)
    {
    
      Registry.ClassesRoot.DeleteSubKey(
        GetSubKeyName(type, "Programmable"), false);
    }
    
    private static string GetSubKeyName(Type type,
      string subKeyName)
    {
      System.Text.StringBuilder s =
        new System.Text.StringBuilder();
      s.Append(@"CLSID\{");
      s.Append(type.GUID.ToString().ToUpper());
      s.Append(@"}\");
      s.Append(subKeyName);
      return s.ToString();
    }  
    

    翻译成vb.net,相当于:

    'VB.NET:
    
    <ComRegisterFunctionAttribute()> _
    Public Shared Sub RegisterFunction(ByVal type As Type)
        Registry.ClassesRoot.CreateSubKey(GetSubKeyName(type, "Programmable"))
        Dim key As RegistryKey = Registry.ClassesRoot.OpenSubKey(GetSubKeyName(type, "InprocServer32"), true)
        key.SetValue("", (System.Environment.SystemDirectory + "\mscoree.dll"), RegistryValueKind.String)
    End Sub
    
    <ComUnregisterFunctionAttribute()> _
    Public Shared Sub UnregisterFunction(ByVal type As Type)
        Registry.ClassesRoot.DeleteSubKey(GetSubKeyName(type, "Programmable"), false)
    End Sub
    
    Private Shared Function GetSubKeyName(ByVal type As Type, ByVal subKeyName As String) As String
        Dim s As System.Text.StringBuilder = New System.Text.StringBuilder
        s.Append ("CLSID\{")
        s.Append(type.GUID.ToString.ToUpper)
        s.Append ("}\")
        s.Append (subKeyName)
        Return s.ToString
    End Function
    

    这是可行的,但在运行时正确注册程序集的地方也有同样的问题 复律 在本地计算机上,但在尝试在Visual Studio安装项目中使用时失败。

    同样,解决方案是添加我们自己的注册表项。但是,这次我们必须创建一个默认值,它使用 [SystemFolder] 属性,相当于 System.Environment.SystemDirectory 上面Eric Carter代码中使用的调用。

    为此,请添加名为 进程服务器32 在你的下面 CLSID\\{GUID} 我们之前创建的密钥。然后右键单击新的 进程服务器32 键并选择“新建”,然后选择“字符串值”。结果将是一个名为 New Value #1 ,但您将处于编辑模式,允许您重新命名它。你想做的是 删除所有字符,然后按回车键 . 通过删除名称中的所有字符,您将创建一个默认值,注册表值的图标将自动重命名为“(默认)”。然后右键单击此默认值图标并选择“属性窗口”。在“属性”窗口中,将“值”属性设置为 "[SystemFolder]mscoree.dll" (没有引号)。

    然后您可以右键单击安装项目并选择“生成”,然后准备部署。

    还有最后一件事要担心。如果您要安装到excel 2007或更高版本,上述操作将100%有效。但是,如果要在Excel 2003或更低版本上安装,则需要包括以下内容:

    FIX: Add-ins, smart documents, or smart tags that you create by using Microsoft Visual Studio 2005 do not run in Office

    Divo详细解释了如何部署它 here .

    如果不应用此修复,所有的内容都会正确注册,甚至可以成功地添加您的自动化加载项——一切看起来都很好,但是您的工作表函数会失败,您仍然可以获得名称吗?结果是错误。(但是,同样,对于Excel2007及更高版本,您不需要这个。)

    所以,最终,tlb并不重要。在我的所有测试中,我使用了regasm,其中包含/tlb开关,并且在通过安装项目注册时不包含任何tlb。所以我在vista做这个没问题, which has issues when attempting to add a TLB file to a Setup Project .

    我希望这能帮上忙,休,希望将来有人会偶然发现这条线索…

    迈克