我正在用C#编写一个类库(IE BHO),目前正在与我认为来自REGASM生成的注册表键的大量垃圾输出进行争论.
简短的版本是这样的:我只想向IE(以及COM的其余部分)公开一些类(目前:ONE类).只有一个类具有ClassInterfaceAttribute和GUID设置,我可以测试该加载项只需要此类的COM注册表项 - 然而,REGASM为整个项目中的每个类生成GUID和注册表项.
这很烦人,有点令人不安,因为我不希望我的班级名字坐在用户的注册表中,除非他们绝对必须在那里.
公平地说,许多其他类都被标记为公共,因为我在同一解决方案中的另一个项目的驱动程序应用程序中使用它们来解决IE的调试黑洞......
一般来说我对COM仍然非常环保(特别是与.Net有关),我想知道隐藏所有其他类的最佳方式是什么?或者,至少,为什么这些类 - 即使它们被标记为公共 - 在我没有为它们设置任何COM标志时出现?
谢谢!
我正在尝试评估Excel DNA,以便在我的一个excel加载项中使用它.我使用C#函数(.NET 4.0)并希望从Excel调用这些函数.我感兴趣的原因是,我的插件的用户是非管理员,因此如果我能找到一个解决方案,不要在我的.NET dll上做一个regasm,让我的插件工作,那将是一个突破.
我理解,如果它就像一个工作表函数(具有简单的返回类型和参数),如:private string Add (int a, double b)
我可以使用excel dna轻松地展开它们.另外,据我所知,我也可以使用VBA中的Application.Run调用这些简单的函数.
但是,如果我有一个涉及API的复杂类型并希望从VBA使用它,那么我是否需要重新组合该程序集和类型?示例如下:
private MyType AddLogic (myType1 A, myType2 B)
Run Code Online (Sandbox Code Playgroud)
或者Excel Excel中是否有任何方法,我还可以在VBA中使用这类函数而不需要任何regasm或regsvr32?
谢谢Mani
编辑5/11/2013:这个问题最初询问如何使用.NET中的代码以编程方式注册COM对象,而不必使用REGASM.Yahia的答案涵盖了如何以编程方式注册DLL和EXE.
原始问题:目前,我们有一个批处理脚本,我们从UI调用,在设置默认版本(使用regasm和添加注册表项)时在COM中注册/取消注册我们的软件.我们不再希望使用批处理脚本,因为我们遇到了一个问题,如果脚本失败,程序就不会意识到失败.有几种方法可以解决这个问题,但我不喜欢从代码调用批处理脚本的概念,如果我不需要,所以我想切换到使用托管代码向COM注册我们的软件.
假设它是可能的,你如何从C#注册/注销COM对象?谷歌搜索只能找到从安装程序包中执行此操作的方法,或者告诉我使用regasm,但我无法找到有关如何以编程方式执行此操作的任何信息,或者甚至是否可能.
在此先感谢任何帮助.
编辑5/10/2013:将EXE注册为COM对象看起来与注册DLL不同..NET中是否有一种编程方式(PInvoke很好)将EXE注册为COM对象(在32位注册表中)?这是我们目前在脚本中的做法,app和REGCMD变量只是简写:
set app=%PathToTheExecutable%
set REGCMD=%PathTo32BitRegExe%
"C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\regasm" /tlb /codebase %app%
%REGCMD% ADD HKCR\CLSID\{app-guid}\LocalServer32 /ve /t REG_SZ /d %app% /f
%REGCMD% DELETE HKCR\CLSID\{app-guid}\InprocServer32 /f
Run Code Online (Sandbox Code Playgroud)
基本上我们在可执行文件上运行regasm,然后将我们的exe作为LocalServer32添加并删除将我们关联为InprocServer的条目.是否有可能以编程方式执行此操作而无需从代码中调用regasm?
所有问题都与.net Framework 2.0中的.net项目dll有关,该dll将自身公开为COM。
1)如果我们在源代码(typelib,类,接口)中未指定任何GUID,那么谁在生成GUID?编译还是高潮?
2)GUID值存在于dll,tlb或两个文件中吗?
3)任何具有相同源代码的开发人员都会在其生成或运行重装的机器上独立生成非常相同的GUID?
4)如果我通过现有的dll和tlb文件运行regasm,如果dll和tlb不匹配怎么办?Regasm使用最新元素和GUID重新生成tlb文件吗?还是将TypeLib注册到当前的tlb文件?
5)使用dll和tlb参数设置运行regasm有什么意义?Tlb文件是部署内容的一部分,还是最佳做法是仅部署dll,让regasm快速生成tlb?
6)最后一个问题,真的需要tlb吗?拥有tlb文件的意义是什么?并非所有信息都已在注册表中?它提供了什么额外的信息?
7)在注销时,我们需要提供什么?dll文件?Tlb?都?如果dll(或tlb)与现有的reg条目不匹配怎么办?如果已经用tlb选项注册,但是我只运行dll的regasm unregister,它也会删除TypeLyb条目吗?
8)关于位,再充气也总是在SysWow64下生成条目吗?Framework64下的重制与Framework下的重制相同吗?
我有一个包含几个类的托管程序集,这些类有重载方法.我将程序集暴露给COM/IDispatch调用者
[ComVisible(true)]
Run Code Online (Sandbox Code Playgroud)
..还要在装配本身上设置合适的Guid.我没有为COM互操作定义显式接口.这一切都是动态完成的.我运行regasm.exe /codebase托管DLL并将其注册为COM互操作.
当我运行OleView时,我可以看到程序集中各种类的ProgId.但是,浏览这些ProgId并扩展IDispatch节点,这些类没有TypeLib信息.
即便如此,从脚本中,我可以调用接受零参数的方法或接受一个参数的方法.如果还有一个接受多个参数的重载,我不能按名称调用该方法.我得到的错误一直是
Microsoft VBScript runtime error: Wrong number of arguments or invalid property assignment: <methodname>
Run Code Online (Sandbox Code Playgroud)
由此我了解到COM/IDispatch客户端无法正确解析通过COM互操作公开的对象上的重载方法.
然后我补充说
[ClassInterface(ClassInterfaceType.AutoDual)]
Run Code Online (Sandbox Code Playgroud)
......对每个有关的课程.在regasm.exeDLL之后,我可以在IDispatch节点下看到每个方法的typelib信息.
我发现重载方法会自动获得包含附加后缀的名称.MethodX将在自动生成的类型库组件中公开重载,如MethodX,MethodX_2,MethodX_3等.
我发现通过引用具有这些后缀的方法名称,我可以调用重载方法,尽管不是通用名称.
更有趣的是,如果我然后[ClassInterface(ClassInterfaceType.AutoDual)]从类中删除了,我仍然可以通过这种方式调用重载方法,从而避免 Wrong number of arguments or invalid property assignment错误.
我的问题是:这种行为 - 将数字后缀附加到成员名称 - 稳定吗?记录?可信?
我输入这个:
regasm COMTest.dll /tlb:COMTest.tlb/codebase COMTest
我收到以下错误:
注册导出的类型库时发生错误:访问OLE注册表时出错.(来自HRESULT的异常:0x8002801C(TYPE_E_REGISTRYACCESS))
这是什么意思,我该如何解决?
.Net Excel.dll在另一台计算机上部署和注册 aCan't add a reference to the specified file时,尝试DLL在VBA编辑器中添加引用时出现错误。
我已经创造了Excel.dll在C#中Visual Studio与运行正常我的机器上Windows 7和Office 2010。Excel VBA在我的计算机上的编辑器中添加对 dll 的引用没问题。我的问题是部署在另一台正在运行的机器上,Vista并且Excel 2007. 我把dll复制到这台电脑上,用来regasm注册dll。
任何人都可以指出我正确的方向吗?这里是代码和 regasm:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe excelDll.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestDll
{
[ClassInterface(ClassInterfaceType.AutoDual)]
public class Test
{
public string HelloWorld
{
get
{
return "Hello World";
}
}
public …Run Code Online (Sandbox Code Playgroud) 我有一个 .NET COM 可见的进程外服务器,我们将其称为 Server.exe。我需要能够在可能安装了不同版本的 .NET 框架的系统上注册它,因此我想避免通过其全名(通常包含 .NET 框架的版本号)调用 RegAsm。
我一直在尝试通过导出注册表补丁并使用以下命令导入它来使其工作:
regasm /regfile:foo.reg Server.exe
reg import foo.reg
Run Code Online (Sandbox Code Playgroud)
但是,应用补丁并不能正确注册组件。我可以直接使用 regasm 注册它。我是管理员。regasm 正在做什么而不写入注册表补丁?
我已经开发了一个自定义代码生成器并通过VSIX进行部署,问题是我应该在安装VSIX后通过regasm.exe注册程序集,但我看到一些项目,如DSLTool,自定义代码生成,自动注册,任何机构都知道如何我可以在我的VSIX项目中自动注册吗?
对于在Web中注册.NET COM对象的每个示例,我都看到了用于完成工作的工具"regasm".每个人都这样做!
但它从来没有对我有用!我厌倦了试图克服它!我唯一的解决方案是regsvr32,它需要一个我只能在C++中定义的函数.
请告诉我为什么不能正常工作!
考虑到它不能在我的所有4台计算机上运行,再加上3台虚拟机,将Windows 7运行到2000,是否可以有人向我展示一个关于regasm呼叫的工作示例?我想我是个白痴.