Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在自动化服务器列表中安装并注册VB.NET中编写的COM Server for Excel? 版本_.net_Excel_Com_Installation - Fatal编程技术网

如何在自动化服务器列表中安装并注册VB.NET中编写的COM Server for Excel? 版本

如何在自动化服务器列表中安装并注册VB.NET中编写的COM Server for Excel? 版本,.net,excel,com,installation,.net,Excel,Com,Installation,Excel 2007、Windows Vista、VB.NET、Visual Studio 2008以及.NET 3.5 sp2、MSI安装程序包 我想做什么 我有一个用VB.NET编写的Excel自定义项。它作为COM服务器公开,因为您无法直接用.NET语言创建Excel UDF。安装是一个真正的痛苦,因为没有安装设置似乎得到它完全正确;它们都没有为您提供一个安装包,该安装包将COM服务器放在客户机上,服务器已注册,类型库已注册,组件在Excel2007的自动化服务器列表中可见 我试过的 以下

Excel 2007、Windows Vista、VB.NET、Visual Studio 2008以及.NET 3.5 sp2、MSI安装程序包

我想做什么 我有一个用VB.NET编写的Excel自定义项。它作为COM服务器公开,因为您无法直接用.NET语言创建Excel UDF。安装是一个真正的痛苦,因为没有安装设置似乎得到它完全正确;它们都没有为您提供一个安装包,该安装包将COM服务器放在客户机上,服务器已注册,类型库已注册,组件在Excel2007的自动化服务器列表中可见

我试过的 以下是类型库的安装设置,其缺陷在编译时和安装时很明显:

vsdrfComSelfReg

  • 编译安装项目期间没有警告
  • 模块xxx.tlb注册失败。HRESULT-2147024703
  • 组件的ProgID和GUID在注册表中设置,但该组件不显示在自动化服务器列表中
vsdrfDoNotregister

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

  • 编译时警告:警告:无法为名为“xxx.tlb”的文件创建注册信息
  • 安装期间未注册类型库
正确的设置应为vsdrfCOM,如下所述:

谁能告诉我你在做什么 vsdrfCOM是指安装项目中的 Visual Studio?我需要的时候可以用 检查属性“注册表”中的 设置中添加的文件的属性 项目

这意味着VisualStudio将 在生成时提取COM注册数据 时间并将其放入MSI文件中 (主要是MSI文件的注册表表, 而且还有班级表)。所以当你 安装它您的代码不需要 自注册,因为文件 复制到磁盘和注册表 创建条目。它还将 通过创建类型库注册 向MSI的TypeLib添加条目 桌子

许多困难似乎与Vista有关。特别是,使用从.TLB文件生成.REG文件在Vista中不起作用。如果不是因为这个,也许吧。相反,它在工作时会生成空的.REG文件

我把所有的建议都试过了。这篇文章对技术问题有很好的描述:

“引用”对话框中的条目 框来自HKCR\TypeLib 注册表项,不是来自HKCR\CLSID。如果 您的程序集未显示在中 引用对话框,但已编译的DLL 仍然可以使用您的COM程序集 表示类和接口是 正确注册您的 程序集,但类型库 事实并非如此

问题 有人知道如何让安装注册组件和类型库吗?我没有访问Windows XP计算机的权限


详细说明为什么这很糟糕

任何编译代码都不需要.TLB来调用它。我没有像您这样尝试部署Excel自动化外接程序,但我想UDF应该可以正常加载和运行

在Excel中不是这样的

  • 用户打开工作表并尝试引用自定义项。未找到,因为未加载DLL失败
  • 用户进入主页| Excel选项|加载项| Excel加载项+Go,COM服务器未在加载项对话框中列出失败
  • 然后,用户按下Automation Servers以获取可用自动化服务器的列表。DLL不在那里失败
  • 用户返回“加载项”对话框并选择“浏览”,导航到安装目录,然后选择DLL(“XXX不是有效的加载项”)或类型库(“您选择的文件不包含新的自动化服务器,或者您没有足够的权限…”)失败
据我所知,用户必须从命令行运行regasm.exe才能使Excel UDF/COM服务器可用。告诉人们从命令行运行regasm以将外接程序安装到Excel中,您会有什么感受


编辑2009-10-04


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

我在周末尝试部署一个自动化插件。事实证明,这是非常复杂的(你不感到惊讶!),我在互联网上完全找不到关于如何正确完成这项工作的资料。没有

有一些源代码描述了如何使用
RegAsm
,但没有一个源代码描述了如何正确使用安装项目来注册自动化加载项,这与标准COM加载项略有不同

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

如果您阅读了一些关于如何创建和注册C#automation外接程序的文章,您将看到需要在
HKEY\\U CLASSES\\U ROOT\CLSID\\{GUID}
处添加一个名为
Programmable
的注册表项,其中
{GUID}
是COM可见类的GUID

这通常是通过添加一对由和标记的方法来完成的。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;
}
转换为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
转换为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
”VB.NET:
_
公共共享子注册表函数(ByVal类型作为类型)
Registry.ClassesRoot.CreateSubKey(GetSubKeyName(类型,“可编程”))
调暗键为Regi
'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