我有一个本机dll(这是一个activex控件),我需要使用我的.NET应用程序,而无需在注册表中注册dll。
我已经阅读了几篇关于注册免费激活的深度帖子,其中一些更好的是
A lengthy one from Steve White and Leslie Muller
从我可以看到它是可能的。然而,几个小时和几百个测试后来我不能让它工作。在我的职业生涯中,我已经完成了一些PInvoking,甚至更少使用.NET中的ActiveX控件,所以非常感谢任何可能在此之前就已经踢过目标的人的任何意见。
到目前为止,我正在遵循Steves的建议,在构建一个有效的应用程序方面,然后通过重复运行regsvr32命令来添加和删除非托管的dll,从而尝试制定获胜的清单文件语法。注册表。只是一个简单的.Net控制台应用程序,有大约10行代码......
我很困惑的一个部分是互操作。我拥有的原生dll还附带了托管运行时可调用包装器(RCW' s)。在我的.NET应用程序中,我添加对这些RCW的引用,然后可以使用非托管dll提供的相应类和功能。我不是通过dllimport
进行PINvoking。
在创建清单文件时,我不确定是否需要担心这些RCW以及它们如何在无注册场景中工作,或者即使它们是否需要在编译输出中?< / p>
我还尝试过多种工具,例如(OLE / COM对象查看器,Windows sdk中的Mt.exe和codeproject中的regsvr42)。但是清单结构和必要的GUID在工具和帖子之间都有所不同。
当前状态是我收到InvalidCastException
&#34;无法将System .__ ComObject类型的COM对象强制转换为接口类型MyFunkyDllLib.FunkyDllControl。此操作失败,因为QueryInterface调用COM组件上的接口与IID&#39; {some guid}&#39;由于以下错误而失败:库未注册。
任何人都可以确认应用程序和dll清单文件的正确语法吗?在线帖子甚至在名称上有所不同,有些人在名称中使用sx ....
UPDATE1: 虽然Joe的回答不起作用,但确实给了我一些关于免费COM的更好的见解。在Interop dll的属性(从开发机器上已安装的COM组件列表中添加到项目引用的属性)中,我将Isolated Property更改为True。这具有使VS转储到DLL \ debug文件夹的COM转储(不是互操作,它嵌入在exe中)的副本的效果。然后VS也会创建一个myapplication.exe.manifest。
在这个清单文件中可以说是reg free com的足够信息。我发现其他帖子表明此方法取得了成功,但在我的情况下,我仍然使用相同的InvalidCastException
。
再次阅读塞缪尔杰克的帖子,我尝试了在Isolated=true
时使用来自VStudio输出清单的clsid信息为exe和COM dll创建清单的方法。 (我还从exe.manifest中删除了VS创建的<file/>
部分)。从注册表中取消注册COM后,我现在已经成功了!应用程序启动并且不会出错。
为什么这种方法有效而不是Isolated=true
我不知道,因为它超出了我对清单和汇编的了解。
然而,我们仍然没有在Toto的巫师城堡。
现在我回到我在this SO帖子上发布的同一个问题。但是在这种情况下,不涉及单元测试。只是一个包含10行代码的普通控制台应用程序。在正常注册的COM模式下工作正常,但在免注册模式下不工作。
答案 0 :(得分:1)
经过数小时的反复试验后,我终于找到了如何成功实施RegFree COM的解决方案。 这是一个完整的解释,因为它可以帮助其他人。
<assembly />
代码中,我需要添加<comInterfaceExternalProxyStub />
代码,其中包含相应的IID
,tlbid
和proxyStubClsid32
GUID元素。清单的元素记录在案on msdn。在我的例子中,代理/存根是proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/>
,它是内置的Windows代理。我最初通过调用regsvr32时通过Process Monitor发现的iid和tlbid。我后来发现的一个更简单,更可靠的选项是使用像SxS manifest maker这样的工具,因为它添加了我原本没有的第二个<comInterfaceExternalProxyStub />
。警告:我不知道为什么VS不会在.manifest中自动包含<comInterfaceExternalProxyStub />
元素。在撰写本文时,自动更新清单的唯一方法是在VS中添加post build任务。在我的例子中,我将整个XML清单复制到类库项目中的XML中,然后在构建输出中覆盖.manifest文件。
COM的单元(集成)测试不一致。目前在我的情况下调用Interop方法工作,但事件没有。它与Test Runner未编译时具有依赖关系的知识有关,因此在激活上下文中不存在。
答案 1 :(得分:0)
你可能错过了一个类型库声明......但现在忽略它......相反,请执行以下操作......
在打开和关闭一段时间之后,我认为最简单的方法是使用MSBuild和GenerateApplicationManifest任务。我一直在使用非托管应用,但我不明白为什么它不适用于托管应用。我说&#34; app&#34; ...因为我的应用程序是托管的,但我有COM库和.NET程序集,其中包含ComVisible类。
从您的描述中可以看出您正在处理COM并且不必担心从COM使用.NET程序集。您可以谷歌搜索MSBUILD和GenerateApplicationManifest以获取示例MSBuild文件。
所以,我认为你不需要填充&#34;依赖关系&#34;任务的属性。您将需要填充&#34; IsolatedComReferences&#34;带有COM DLL列表的属性。它们可以是一个简单的以分号分隔的列表,但通常它们位于&#34; ItemGroup&#34; MSBuild项目文件中的声明。需要在生成清单时注册COM DLL。
至于你的RCW,你没有什么特别需要做的。 IMO,他们不需要在清单中。只要它们与app / DLL位于同一目录中,.NET就可以找到它们。
如果您使用MSBuild,您将不必为您的COM DLL生成清单...它们可能已经有清单...通常,向导会自动生成清单并嵌入它们。唯一需要COM类型信息的清单是使用MSBuild生成的清单。
以这种方式使用的清单的重点是使用注册表中的所有COM信息填充清单空间。