我有一个.NET DLL(碰巧用C++/CLI编写).它的一部分我想通过COM公开.我这样做并使用"regasm my.dll/codebase"注册它.到现在为止还挺好.但后来我更改了一些东西和程序集更改的版本号加上我将dll移动到另一个文件夹.我再次注册它,并在OLE/COM查看器中查看我的COM对象.我看到这样的事情
InprocServer32 [Codebase] = file://c://foo/bar/my.dll 7.0.0.0 [Class] = My.Blah.Class 7.0.0.0 [Assembly] = Sync, Version=7.0.0.0, Culture=neutral, PublicKeyToken=1dd19234234 7.0.0.0 [RuntimeVersion] = v2.0.50727 7.0.0.0 [CodeBase] = file://c:/dooby/do/my.dll 7.0.0.27397 [Class] = My.Blah.Class 7.0.0.27397 [Assembly] = Sync, Version=7.0.0.27397, Culture=neutral, PublicKeyToken=1dd19234234 7.0.0.27397 [RuntimeVersion] = v2.0.50727 7.0.0.27397 [CodeBase] = file://c://foo/bar/my.dll
有关多个版本的问题:
所以我认为注册的最后一个COM对象获胜.如果我注册了旧的7.0.0.0 COM对象并不重要,7.0.0.27397是我在实例化COM对象时创建的,因为我最后注册了它.那是对的吗?
哎呀我没有留在7.0.0.0对象.有没有办法摆脱它?有没有办法删除所有版本的COM对象,而不是进入注册表并手动打击它?
出于好奇,如果我特意想要实例化我的COM对象的特定版本,有没有办法做到这一点?(如果你想给出代码示例,我正在使用C++).
有什么方法我可以告诉regasm不存储版本号,因为它似乎是混乱的东西,我看不出有什么好处.如果我的COM对象经历了重大的API更改,我只需更改GUID和progid,对吧?如果我不想注册多个版本(我没有),该怎么办?
尝试在Win2008 Server中运行regasm时:
regasm "C:\Program Files\FooProg\Bar.dll" /tlb:"C:\Program Files\FooProg\Bar.tlb"
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
RegAsm:错误RA0000:保存导出的类型库时发生错误:拒绝访问.(HRESULT异常:0x80070005(E_ACCESSDENIED))
这是什么意思
如果我想使.NET程序集可用作COM服务器,我必须添加一组属性,然后使用regasm它将其注册为COM服务器.
如果在regasm使用/codebasekey 运行时未使用强名称对程序集进行签名,则会显示一条RA0000警告,指出程序集可能会干扰同一台计算机上的其他程序集,并且我应该使用强名称对其进行签名,但是注册成功,它甚至可以正常工作.
AFAIK强名称旨在防止所谓的DLL地狱.但COM也是为了防止DLL地狱.如果我更改任何暴露给COM的接口,我必须更改GUID或至少保持二进制兼容性.因此,使用强名称进行签名似乎没有添加任何有用的东西 - 没有什么能阻止我破坏COM接口,然后用相同的密钥对签名并拥有完整的DLL地狱.
在COM暴露的.NET程序集中,使用强名称签名有什么用?
我有一个我在C#中编写的DLL,我想在我的VB6应用程序中使用它.
在VS2008中,检查项目属性"Register for COM interop",当我编译DLL并尝试在我的开发机器上使用它时 - 它运行正常.
我需要在没有VS2008的计算机上运行它,所以我试着像这样注册这个DLL:
C:\WINDOWS\system32>..\Microsoft.NET\Framework\v2.0.50727\regasm myDLL.dll /tlb: myDLL.tlb /codebase
Run Code Online (Sandbox Code Playgroud)
但是当我尝试运行它时,我收到此错误:
自动化错误.该系统找不到指定的文件.
谁能告诉我我做错了什么?
我们有一个基于spicIE的IE插件,目的是连接到一些外部设备.
为了连接这些外部设备,另一家公司开发了他们的令牌和DLL.我们需要有一些ActiveX和DLL来通过令牌进行身份验证.
问题是我们为IE开发的插件,最后一部分有一个install.bat文件,它运行一个RegAsm并注册DLL,然后在IE中查看该插件(或其更改).
从IE运行插件时,我们的代码找不到一些身份验证所需的DLL(将其命名为x.dll).注册的DLL在哪里复制?真的被复制了吗?我需要在我的插件的DLL存在的文件夹中有x.dll.
这个问题让我头疼了几天,我找不到理由.我很确定这是我的机器特有的环境问题,但它仍然导致我的测试问题.
我正在使用Visual Studio 2010 Professional在C#中创建一个DLL.第一版是下面的;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestCOM
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ProgId("TestCOM.Class1")]
[System.Runtime.InteropServices.Guid("803A1B2F-1CDA-4571-9084-87500388693B")]
public class Class1
{
public void showMessage()
{
MessageBox.Show("Hello from TextCom");
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个程序集很好,一切都很好.我运行以下脚本将其注册为COM对象(首先是32位,然后是64位);
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm.exe TestCOM.dll /codebase /nologo /tlb:TestCOM32.tlb
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe TestCOM.dll /codebase /nologo /tlb:TestCOM64.tlb
Run Code Online (Sandbox Code Playgroud)
然后使用以下脚本进行测试;
dim tc
set tc = CreateObject("TestCOM.Class1")
tc.showMessage()
Run Code Online (Sandbox Code Playgroud)
我使用csript来测试脚本,所以我可以控制它使用的位深度 - 我用32位测试一次,用64位测试一次.到目前为止一切都很好.
现在,当我修改原始程序集添加一个函数时,如下所示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace TestCOM
{
[ClassInterface(ClassInterfaceType.AutoDual)]
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ProgId("TestCOM.Class1")]
[System.Runtime.InteropServices.Guid("803A1B2F-1CDA-4571-9084-87500388693B")] …Run Code Online (Sandbox Code Playgroud) 我有一个有很多旧注册版本的程序集.
我唯一的dll是最后一个.
如何取消注册程序集的所有版本?
谢谢.
编辑:我想在运行时这样做,所以我想要像regasm -u ...或其他一些脚本解决方案.
我想将.net程序集注册为COM.
事实上,据我所知,这意味着HKEY_CLASSES_ROOT我不想写入条目HKEY_CURRENT_USER/Software/Classes,因此不需要UAC/Admin权限.
找到了这个问题的两个解决方案,我正在努力:
1)以编程方式,使用以下代码:
IntPtr key;
var openKeyresult = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Classes", 0, (int)RegistrySecurity.KEY_WOW64_64KEY, out key);
var overrideKeyResult = RegOverridePredefKey(HKEY_CLASSES_ROOT, key);
var registerResult = Registrar.RegisterAssembly(GetAssembly(), AssemblyRegistrationFlags.SetCodeBase);
Run Code Online (Sandbox Code Playgroud)
在这种方法中,overrideKeyResult6是对应于ERROR_INVALID_HANDLE,因此,RegisterAssembly抛出"访问被拒绝"异常,因为它试图写入HKEY_CLASSES_ROOT.
旁注:每次我运行RegOpenKeyEx的键值都不同,是吗?
2)与regasm
通过使用regasm.exe与所述/regfile标志,然后在生成的替换.reg文件中的所有HKEY_CLASSES_ROOT与出现次数HKEY_CURRENT_USER/Software/Classes
我觉得应该可行,但是当我不想卸载我的Outlook AddIn时,如何取消注册这样的程序集呢?
因为我看到我无法以与注册相同的方式制作它,因为:
var openKeyresult = RegOpenKeyEx(HKEY_CURRENT_USER, "SOFTWARE\\Classes", 0, (int)RegistrySecurity.KEY_WOW64_64KEY, out key);
我正在创建一个使用 regasm 将 .NET 程序集注册到 COM 的安装程序。不同的客户端将在其计算机上安装不同的 Microsoft.Net 版本。我需要提前知道高潮位置才能使用它。
我应该只在以下位置寻找它还是还有其他可能的位置?
C:\Windows\Microsoft.NET\Framework\v2.0.50727\ C:\Windows\Microsoft.NET\Framework\v1.0.xxx\ C:\Windows\Microsoft.NET\Framework\v4.0.xxxx\
它可以出现在以下位置吗?
C:\Windows\Microsoft.NET**Framework64**\vx.xx
我想知道是否可以在不使用RegAsm工具的情况下注册类型库.这是我的情况,希望能解释我为什么要这样做:
我正在开发.NET中的程序集,它将为我们的旧VB6应用程序提供一些现代功能.我使用RegAsm在我的开发机器上成功注册了程序集和类型库,如下所示:
regasm.exe MyAssembly.dll /tlb /codebase
Run Code Online (Sandbox Code Playgroud)
上面的命令生成类型库(MyAssembly.tlb)并注册它以及注册程序集.我需要注册的类型库,以便我可以在VB6中使用Intellisense.
这个方法的问题 在于,在生成类型库文件时,我没有像使用TlbExp.exe那样具有相同级别的控制.特别是,我需要使用TlbExp的/ names标志来指定我的属性名称的正确情况(RegAsm屠宰它们).因此,如果我使用TlbExp生成我的tlb文件,是否有任何方法可以将其与程序集注册过程分开注册?
编辑: da_m_n的回答对我问的问题是正确的.但是,我错误的假设是因为RegAsm可以注册一个类型库,必须注册tlb以便在VB6中引用它.所以现在我正在注册程序集并使用固定名称引用未注册的TlbExp生成的tlb.
regasm ×10
.net ×6
com ×5
c# ×3
assemblies ×1
com-interop ×1
dll ×1
ie-plugins ×1
registry ×1
snk ×1
tlbexp ×1
vb6 ×1
versions ×1