如何在VB.NET中安装并注册自动化服务器列表中的COM Server for Excel? [英] How to get COM Server for Excel written in VB.NET installed and registered in Automation Servers list?

查看:212
本文介绍了如何在VB.NET中安装并注册自动化服务器列表中的COM Server for Excel?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

版本



Excel 2007,Windows Vista,VB.NET,Visual Studio 2008 with .NET 3.5 sp2,MSI安装包。



我正在尝试做什么



我有一个用VB.NET编写的Excel UDF。它作为COM服务器公开,因为您无法直接在.NET语言中创建Excel UDF。安装是一个真正的痛苦,因为没有一个安装设置似乎是很正确的;没有一个给您一个安装包,它将COM Server放在客户端计算机上,注册了服务器,注册了类型库,并且组件在Excel 2007的自动化服务器列表中可见。



我尝试过的



以下是类型库的安装设置,在编译时和安装时间中都会出现缺陷:



vsdrfComSelfReg




  • 编译安装项目期间无警告

  • 模块xxx.tlb注册失败。 HRESULT -2147024703

  • 组件的ProgID和GUID在注册表中设置,但该组件不会显示在自动化服务器列表中



vsdrfDoNotregister




  • 在编译期间没有警告

  • 安装工作,但是当然TLB没有注册



vsdrfCOM




  • 编译时警告:警告:无法为名为xxx.tlb的文件创建注册信息

  • 安装过程中未注册类型库



    • 正确设置应该是vsdrfCOM,如 here


      问:任何人都可以告诉,
      vsdrfCOM是什么意思在
      Visual Studio的安装项目中?当我
      检查在$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $

      $ b

      A。这意味着Visual Studio将
      在build
      时间提取COM注册数据,并将其放在MSI文件
      中(主要是MSI文件的注册表,
      ,也是类表) 。所以当你
      安装它的代码不需要
      自我注册,因为该文件获取
      复制到磁盘和注册表
      条目被创建。它也将$ b​​ $ b创建类型库注册
      添加一个条目到MSI的TypeLib
      表。


      许多困难似乎是Vista特有的。特别是使用 REGCAP实用程序在.TLB文件中生成.REG文件在Vista中不起作用。如果不是这样,可能此建议将是有用的。相反,它完全可以生成空的.REG文件。



      我已经尝试了这个StackOverflow文章。该帖子对技术问题有一个很好的描述:


      引用对话框
      框中的条目来自HKCR\\ \\TypeLib
      注册表项,而不是HKCR\CLSID。如果
      ,您的程序集不会显示在
      引用对话框中,但编译的DLL的
      仍然可以使用您的COM程序集,它
      表示类和接口是
      正确注册对于您的
      程序集,但类型库
      本身不是。




      问题



      任何人都有了如何使安装注册组件和类型库的想法?我无法访问Windows XP机器。






      详细说明为什么这会吸引


      .TLB对于任何编译代码都不需要调用。我没有尝试部署一个Excel自动化加载项,就像你在做,但我的猜测是,UDF应该加载和运行很好。


      它不像Excel那样。




      • 用户打开工作表并尝试引用UDF。没有找到因为没有加载DLL。 失败

      • 用户进入主页| Excel选项|加载项| Excel加载项+转,COM服务器未列在加载项中对话。 失败

      • 然后,用户按自动化服务器获取可用的自动化服务器列表。该DLL不在那里。 失败

      • 用户返回加载项对话框并选择浏览,导航到安装目录,并选择DLL(XXX不是有效的加载项)或类型库(您选择的文件不包含新的自动化服务器,或者您没有足够的权限...)。 失败



      据我所知,用户必须从命令行运行regasm.exe使Excel UDF / COM服务器可用。你觉得告诉人们从命令行运行regasm来安装Excel的加载项?






      <强>编辑2009-10-04



      下面的Mike的评论和说明很棒。我不知道的关键是安装程序有一个内置的注册表编辑器,用于添加注册表项。呵呵,安装函数ComRegisterFunctionAttribute属性没有被Microsoft安装程序调用。我已经从他引用的消息来源了解了安装程序的功能。

      解决方案

      在周末。事实证明,这是非常复杂的(对你而言并不意外),我可以在互联网上找到绝对没有资料,如何正确地做到这一点。没有。



      有些来源描述如何使用 RegAsm ,但没有如何正确使用安装程序注册自动化加载项,这与您的标准COM加载项略有不同。



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



      如果您阅读了关于如何创建和注册C#自动化加载项的一些文章,您将看到您需要添加$ code> HKEY\_CLASSES\_ROOT\CLSID\\ {GUID} 中的可编程的注册表项,其中 {GUID} 是COM可见类的GUID。



      这通常是通过添加一个的 ComRegisterFunctionAttribute ComUnregisterFunctionAttribute 。一个很好的例子来自于文章由Gabhan Berry编写C#中的自定义Excel工作表函数:

        // 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()+ @ }\可编程的;
      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

      私有共享函数GetSubKeyName (ByVal Type As Type)As String
      Dim s As String =(CLSID\ {_
      +(type.GUID.ToString.ToUpper +} \Programmable))
      返回s
      结束函数

      ComRegisterFunctionAttribute标记的方法当该类的程序集被注册时, RegAsm 自动调用。通过 ComUnregisterFunctionAttribute 标记的方法由 RegAsm 自动调用,当此类的程序集通过 / u switch。



      问题是, ComRegisterFunctionAttribute

      这似乎是在 c> cnc code code $ c $令人惊讶的是,由于Visual Studio安装程序运行 RegAsm 使用 / regfile 开关,以生成.REG包含所有必需的注册表项的文件。正是这个.REG文件然后被使用,然后.MSI包在客户端站点运行。



      由Phil Wilson构建和部署.NET COM组件


      Visual Studio如何处理
      COM类注册条目?那么
      如果您已经配置了Fusion Log
      Viewer(.NET 2.0
      SDK中的Fuslogvw.exe)来记录程序集加载,则在安装程序生成后运行

      你会注意到Regasm.exe实际上
      运行在你的安装
      项目的构建期间。但是,它不执行
      任何注册。发生什么是
      Visual Studio运行Regasm与
      / regfile 选项来创建.reg文件
      包含注册表项
      需要获取
      步骤1的信息,而.reg文件是
      内部导入到
      项目中。所以如果你想看看
      类注册条目Visual
      Studio将在MSI设置中创建
      ,您可以使用
      / regfile运行Regasm 选项


      自己运行RegAsm使用 / regfile 开关,但是,我注意到可编程开关是不是。然后我将日志记录放在我的方法标记为 ComRegisterFunctionAttribute ComUnregisterFunctionAttribute 中,发现它们在运行 RegAsm 没有 / regfile 切换,但是当<$ c $运行时调用 c> / regfile switch,也不是通过Visual Studio安装项目创建的.MSI包运行时调用。



      Regasm.exe的帮助文件确认(强调添加):


      您可以使用 / regfile 选项
      生成包含
      注册表项的.reg文件,而不是将
      直接更改为注册表。您可以通过
      注册表编辑器工具(Regedit.exe)导入.reg文件来更新计算机上的注册表

      请注意.reg文件不包含用户定义的寄存器
      函数
      的任何注册表更新。


      然后,解决方案是自己添加可编程键。这可以如下进行:


      1. 在安装项目中打开注册表编辑器。在 HKEY_CLASSES_ROOT 下通过右键单击 HKEY_CLASSES_ROOT CLSID 的新密钥c $ c>文件夹,然后选择'New',然后选择'Key'。

      2. CLSID 键下,添加一个新的

      3. 在您添加的新GUID键下,添加一个名为可编程的键。您不需要在此密钥中放置任何值;但是,我们确实需要强制它创建。因此,右键单击可编程键,然后选择属性窗口。然后将 AlwaysCreate 属性更改为 True

      完成后,您不再需要标记有ComRegisterFunctionAttribute和ComUnregisterFunctionAttribute的方法,但是当您通过RegAsm而不是通过安装项目进行安装时,我仍然会将它们留在这些场合。 p>

      此时您可以部署。构建您的解决方案,然后右键单击安装项目并选择生成。然后,您可以使用创建的Setup.exe和.MSI文件部署到客户端计算机。



      然而,需要考虑的是,在添加自动添加 - 在Excel的加载项对话框中,将显示一条错误消息,指出无法找到Mscoree.dll,是否要删除加载项?或者非常相似的东西。此错误消息可以被忽略,您的加载项无论您应答什么都可以运行,但是对于安装加载项的客户端可能会令人震惊。



      情况以及如何解决它的解释,在文章由Eric Carter为Excel编写用户定义的函数



      问题是,的默认值InprocServer32 键只是简单的 mscorree.dll ,这足以让.NET找到它,但导致Excel抱怨。解决方案是确保InprocServer32密钥的默认值包含系统目录的完整路径。例如,在32位窗口中,应该读取 C:\Windows\system32\mscoree.dll 。然而,这个路径需要改变,这取决于它所安装的系统。所以这个路径不应该被硬编码。



      Eric Carter通过修改标记为 ComRegisterFunctionAttribute ComUnregisterFunctionAttribute 成为以下内容:

        // 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(类型,可编程),false);
      }

      私有静态字符串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键As RegistryKey = Registry.ClassesRoot.OpenSubKey(GetSubKeyName (类型,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

      私有共享函数GetSubKeyName(ByVal类型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)
      返回s.ToString
      结束功能

      这样做有效,但是在程序集正确注册时具有相同的确切问题在本地计算机上运行 RegAsm ,但在Visual Studio安装项目中尝试使用它时失败。



      解决方案,再次,是添加我们自己的注册表项。但是,这一次,我们必须创建一个使用 [SystemFolder] 属性的默认值,这相当于 System。



      为此,添加一个名为的密钥InprocServer32 / code>在您以前创建的 CLSID\\ {GUID} 键下。然后右键单击新的 InprocServer32 键,然后选择新建,然后选择字符串值。结果将是一个名为新值#1 的新值,但您将处于编辑模式,允许您重命名。你想在这里做的是删除所有的字符,然后点击输入。通过删除名称中的所有字符,您将创建一个默认值,注册表值的图标将自动重命名为(默认)。然后右键单击此默认值图标,然后选择属性窗口。在属性窗口中,将Value属性设置为SystemFolder mscoree.dll(不带引号)



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



      只需要最后一件事。如果要安装到Excel 2007或以上版本,上述内容将会工作100%。但是,如果要在Excel 2003或更低版本上进行安装,则需要包含以下内容:



      FIX:使用Microsoft Visual Studio 2005创建的加载项,智能文档或智能标记不能在Office中运行



      详细解释如何部署它由Divo 此处



      如果您不应用此修复程序,一切都将正确注册,甚至可以成功添加自动化加载项 - 一切似乎都可以,但是您的工作表函数会失败,你还会得到#NAME?结果是错误。 (但是,再次,您不需要Excel 2007及以上版本。)



      所以,最后,TLB没关系。在我所有的测试中,我使用了RegAsm和/ TLB开关,并且在通过安装项目注册时不包括任何TLB。所以我没有办法从Vista这样做,当尝试将TLB文件添加到安装程序时出现问题



      我希望这有助于Hugh,并希望任何人否则可能会在将来绊倒这个线程...



      Mike


      Versions

      Excel 2007, Windows Vista, VB.NET, Visual Studio 2008 with .NET 3.5 sp2, MSI setup package.

      What I am trying to do

      I have an Excel UDF that is written in VB.NET. It is exposed as a COM Server because you cannot create Excel UDFs in .NET languages directly. Installation is a real pain because none of the installation settings seem to get it quite right; none of them gives you an installation package that puts the COM Server on the client machine with the server registered, the type library registered, and the component visible in the Excel 2007's list of Automation Servers.

      What I've tried

      Here are the installation settings for type libraries, with their defects apparent at compile-time and install-time:

      vsdrfComSelfReg

      • no warning during the compilation of the setup project
      • Module xxx.tlb failed to register. HRESULT -2147024703
      • Component's ProgID and GUID are set in registry, but the component does not appear in the list of Automation Servers

      vsdrfDoNotregister

      • no warning during compilation
      • installation works but of course the TLB is not registered

      vsdrfCOM

      • Compile-time warning: WARNING: Unable to create registration information for file named 'xxx.tlb'
      • type library is not registered during installation

      The correct setting should be vsdrfCOM, as explained here:

      Q. Can anyone please tell what does vsdrfCOM mean in a setup project of Visual Studio? It is available when I check the property "Register" among properties of added files in a Setup project.

      A. It means that Visual Studio will extract COM registration data at build time and put it in the MSI file (mostly the MSI file's registry table, but also the class table). So when you install it your code doesn't need to self-register because the file gets copied to disk and the registry entries get created. It will also create type library registration by adding an entry to the MSI's TypeLib table.

      Many of the difficulties appear to be Vista-specific. In particular, using the REGCAP utility to produce a .REG file from a .TLB file does not work in Vista. If not for that, perhaps this advice would be useful. Instead, it produces empty .REG files when it works at all.

      I've tried all of the advice in this StackOverflow post. That post has a pretty good description of the technical problem:

      The entries in the References dialog box come from the HKCR\TypeLib registry key, not from HKCR\CLSID. If your assembly does not show up in the References dialog but compiled DLL's can still use your COM assembly, it means the classes and interfaces were correctly registered for your assembly, but that the type library itself was not.

      The question

      Anyone have an idea of how to make the installation register the component and the type library? I don't have access to a Windows XP machine.


      Elaboration on why this sucks

      The .TLB is not necessary for any compiled code to call it. I've not tried deploying an Excel Automation add-in, as you are doing, but my guess is that the UDFs should load and run just fine.

      It's not quite like that in Excel.

      • The user opens a worksheet and tries to reference the UDF. It isn't found because the DLL is not loaded. FAIL
      • The user goes to Home|Excel Options|Add-Ins|Excel Add-Ins+Go and the COM Server is not listed in the Add-Ins dialog. FAIL
      • The user then presses Automation Servers to get a list of available automation servers. The DLL is not there. FAIL
      • The user returns to the Add-Ins dialog and selects Browse, navigates to the installation directory, and selects either the DLL ("XXX is not a valid add-in") or the type library ("The file you selected does not contain a new Automation Server, or you do not have sufficient rights..."). FAIL

      As far as I can tell, the user has to run regasm.exe from the command line to make the Excel UDF/COM server available. How would you feel about telling people to run regasm from the command line to install an add-in to Excel?


      Edit 2009-10-04

      Mike's comments and directions below are awesome. The key thing I did not know was that the setup program has a built-in registry editor for adding registry keys. Oh, and that the installation function with attribute ComRegisterFunctionAttribute was not being called by the Microsoft installer. I already had the directions about writing installer functions from the sources he cited.

      解决方案

      I took a shot at deploying an automation add-in over the weekend. It turns out that it is enormously complicated (not a surprise to you!) and I could find absolutely no sources on the internet on how to do this properly. None.

      There are sources that describe how to use RegAsm, but none how to correctly use a Setup Project to register an automation add-in, which is a little different from your standard COM add-in.

      Fortunately, I was able to solve it. Here's what I found out:

      If you read some of the articles on how to create and register your C# automation add-in, you'll see that you need to add a registry key named Programmable at HKEY\_CLASSES\_ROOT\CLSID\\{GUID}, where {GUID} is the GUID of your COM-visible class.

      This is generally done by adding a pair of methods marked by the ComRegisterFunctionAttribute and the ComUnregisterFunctionAttribute. A good example of this comes from the article Writing Custom Excel Worksheet Functions in C# by Gabhan Berry:

      // 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;
      }
      

      Translated to VB.NET, this works out to:

      '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
      

      The method marked by the ComRegisterFunctionAttribute is automatically called by RegAsm when the assembly for this class is registered. The method marked by the ComUnregisterFunctionAttribute is automatically called by RegAsm when the assembly for this class is being unregistered via the /u switch.

      The problem is that the ComRegisterFunctionAttribute and ComUnregisterFunctionAttribute are completely ignored when installing via a Visual Studio Setup Project.

      This seems surprising at first, because the Visual Studio Setup Project runs RegAsm using the /regfile switch in order to generate a .REG file containing all of the required registry keys. It is this .REG file that is then utilized then the .MSI package is run at the client site.

      From Build and Deploy a .NET COM Assembly by Phil Wilson:

      How does Visual Studio work out the COM class registration entries? Well, if you have configured the Fusion Log Viewer (Fuslogvw.exe in the .NET 2.0 SDK) to record assembly loading, run it after the build of your setup and you'll notice that Regasm.exe actually runs during the build of your setup project. However, it doesn't perform any registration. What happens is that Visual Studio runs Regasm with the /regfile option to create a .reg file containing the registry entries required to get the information for step 1, and this .reg file is internally imported into the setup project. So if you want to see what class registration entries Visual Studio will create in the MSI setup, you can run Regasm yourself with the /regfile option

      Upon running RegAsm myself using the /regfile switch, however, I noticed that the Programmable switch was not being included. I then put logging within my methods marked by the ComRegisterFunctionAttribute and ComUnregisterFunctionAttribute and found that they are both called when running RegAsm without the /regfile switch, but are not called when run with the /regfile switch, nor are they called when run via the .MSI package created by the Visual Studio Setup Project.

      The help files for Regasm.exe confirm this (emphasis added):

      You can use the /regfile option to generate a .reg file that contains the registry entries instead of making the changes directly to the registry. You can update the registry on a computer by importing the .reg file with the Registry Editor tool (Regedit.exe). Note that the .reg file does not contain any registry updates that can be made by user-defined register functions.

      The solution, then, is to add the Programmable key ourselves. This can be done as follows:

      1. Within the Setup Project, open up the Registry Editor. Create a new Key named CLSID under HKEY_CLASSES_ROOT by right-clicking on the HKEY_CLASSES_ROOT folder, then choosing 'New', and then 'Key'.
      2. Under the CLSID key, add a new key named for your GUID, including the curly braces.
      3. Under the new GUID key you added, add a key named Programmable. You don't need to put any value within this key; however, we do need to force it to be created. Therefore, right-click on the Programmable key and choose 'Properties Window'. Then change the AlwaysCreate property to True.

      Once you've done this, you no longer need the methods marked with ComRegisterFunctionAttribute and ComUnregisterFunctionAttribute, but I would still leave them in for those occasions when you intall via RegAsm and not via the Setup Project.

      At this point you are ready to deploy. Build your solution and then right click on your Setup Project and choose 'Build'. You can then use the created Setup.exe and .MSI files to deploy to a client machine.

      Something else to consider, however, is that when adding the automation add-in via Excel's add-ins dialog box, an error message will be shown stating that "Mscoree.dll cannot be found, would you like to delete the add-in?" or something very similar. This error message can be ignored, and your add-in will run no matter what you answer, but it can be alarming to a client installing your add-in.

      This situation, and the explanation of how to solve it, is well described in the article Writing user defined functions for Excel in .NET by Eric Carter.

      The problem is that the default value for the InprocServer32 key is simply mscorree.dll, which is sufficient for .NET to find it, but causes Excel to complain. The solution is to make sure that the default value for the InprocServer32 key includes the full path to your system directory. For example, on 32 bit windows, it should read C:\Windows\system32\mscoree.dll. This path needs to vary, however, depending on the system it is installed on. So this path should not be hard-coded.

      Eric Carter handles this by modifying the methods marked by the ComRegisterFunctionAttribute and ComUnregisterFunctionAttribute to be the following:

      // 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();
      }  
      

      Translated to VB.NET, this is equivalent to:

      '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
      

      This works, but has the same exact problem where the assembly is properly registered when running RegAsm on the local machine, but fails when attempting to use this within a Visual Studio Setup Project.

      The solution, again, is to add our own registry keys. This time, however, we'll have to create a default value that makes use of the [SystemFolder] property, which is equivalent to the System.Environment.SystemDirectory call used within Eric Carter's code, above.

      To do this, add a Key named InprocServer32 under your CLSID\\{GUID} key that we created previously. Then right-click on the new InprocServer32 key and choose 'New' then 'String Value'. The result will be a new Value named New Value #1, but you will be in edit mode allowing you to re-name it. What you want to do here is delete all the characters and then hit enter. By deleting all the characters from the name, you are creating a default value and the icon for the registry value will be automatically renamed "(Default)". Then right-click on this Default Value icon and choose 'Properties Window'. Within the properties window, set the Value property to "[SystemFolder]mscoree.dll" (without the quotes).

      You can then right-click on your Setup Project and choose 'Build' and then you are ready to deploy.

      There is just one last thing to worry about. If you are installing to Excel 2007 or above, the foregoing will work 100%. If you are installing on Excel 2003 or below, however, you will need to include the following:

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

      A detailed explaination of how to deploy it is given by Divo here.

      If you do not apply this fix, everything will register correctly, and you can even add your automation add-in successfully -- everything seems fine -- but your worksheet functions will fail and you'll still get #NAME? errors as a result. (But, again, you don't need this for Excel 2007 and above.)

      So, in the end, the TLB does not matter. In all my testing I used RegAsm witout the /TLB switch and did not include any TLB when registering via the Setup Project. So I had no trouble doing this from Vista, which has issues when attempting to add a TLB file to a Setup Project.

      I hope this helps, Hugh, and hopefully anyone else who might stumble onto this thread in the future...

      Mike

      这篇关于如何在VB.NET中安装并注册自动化服务器列表中的COM Server for Excel?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆