从.NET注册自由激活本机COM(activex)组件 [英] Registration free activation of native COM (activex) component from .NET

查看:475
本文介绍了从.NET注册自由激活本机COM(activex)组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个本机dll(这是一个activex控件),我需要使用我的.NET应用程序,而不必在注册表中注册DLL。



已阅读几篇关于免注册激活的深入的帖子,一些更好的是



来自史蒂夫·怀特和莱斯利·穆勒的长篇一篇



这个来自samuel jack



另一位来自Mike Makarov

从我可以看到它是可能的。但是几个小时和几百个测试后,我只是不能得到它的工作。我在我的职业生涯中做了一些PInvoking,甚至更少的.NET中的ActiveX控件,所以将感谢任何人可能已经踢了目标之前的任何输入。



到目前为止,我遵循Steves建议,在建立一个工作的应用程序,然后尝试通过重复运行regsvr32命令添加和删除注册表中的非托管dll的制定获胜的清单文件语法。只是一个简单的.Net控制台应用程序,大约10行代码...



我困惑的一个部分是interop。本地dll我也有陪同托管运行时可调用包装器(RCW的)。在我的.NET应用程序中,我添加对这些RCW的引用,然后可以使用非托管DLL提供的各自的类和功能。我不是PInvoking通过 dllimport



在创建清单文件我不确定如果我需要担心关于这些RCW和它们如何在无注册的情况下工作,或者甚至如果他们需要在编译的输出?



我也试过了几个工具,如(OLE / COM对象查看器,Mt.exe从Windows sdk和regsvr42从codeproject)。



当前状态是我收到一个 InvalidCastException 无法将类型为System .__ ComObject的COM对象转换为接口类型MyFunkyDllLib.FunkyDllControl此操作失败,因为由于以下错误,COM组件上的QueryInterface调用与IID'{some guid}'的接口失败:图书馆未注册。



任何人都可以确认应用程序和dll清单文件的正确语法?在线文章甚至有所不同,有些使用sxs在name ....



Update1:​​
虽然Joe的答案以下不起作用,但它给了我一些更好的洞察reg COM。在Interop dll的属性(从dev机器上安装的COM组件列表中添加到项目引用的属性)中,我将Isolated属性更改为True,这使得VS转储一个副本的COM dll(不是interop,它嵌入在exe中)到bin \debug文件夹。 VS然后创建一个myapplication.exe.manifest。



在这个清单文件应该是reg free com的足够的信息。我发现其他帖子指示成功与此方法,但在我的情况下,我仍然最终与相同的 InvalidCastException



阅读Samuel Jacks的帖子,我试着他的方法创建一个清单的EXE和COM DLL使用来自VStudio输出清单中的clsid信息,当 Isolated = true 。 (我也删除了由VS从exe.manifest创建的<文件/> 部分)。注销COM注册表后,我现在已经成功!应用程序启动,不会报错。
为什么这种方法工作,而不是 Isolated = true 我不知道,因为它是我不知道的清单和程序集。



但我们还没有在向导的城堡还Toto。



现在我回到了同一个问题,我张贴在这是SO 线程。然而在这种情况下,不涉及单元测试。只是一个简单的控制台应用程序,有10行代码。在正常注册的COM模式下工作正常,但在reg自由模式下不工作。

解决方案

经过多个小时的试验和错误,我终于得到了一个解决方案,如何成功实现RegFree COM。


  1. 我在VS中创建了一个新的.NET类库

  2. 右键单击引用并选择感兴趣的COM组件。
    (注意:为了使COM在列表中可见,它们必须在开发机器上注册
    ,这可以通过使用Windows中包含的
    Regsvr32.exe工具来实现,调用 regsvr32
    mycomdll.dll注册它在Windows注册表中)

  3. 右键单击COM引用,goto属性,然后设置Isolated = True。这有效果导致VS输出一个.manifest文件,应该包含所有的注册表详细信息,消耗的.exe知道加载哪些资源,而不是查询注册表所必需的。但在我的情况下,它是不完整的。调用Interop方法会工作,但COM组件中的事件不会。请参阅我的解决方案的步骤5)

  4. 创建项目。 .manifest应显示在构建输出中。

  5. 在记事本或类似文件中打开清单。在< assembly /> 标记中,我需要添加一个< comInterfaceExternalProxyStub /> code> IID , tlbid proxyStubClsid32 GUID元素。素材资源的元素 on msdn 。在我的情况下,proxy / stub是 proxyStubClsid32 ={00020424-0000-0000-C000-000000000046}/> 这是内置的windows代理。 iid和tlbid我最初通过调用regsvr32时通过进程监视器发现。后来发现的一个更简单,更可靠的选项是使用 SxS清单制作工具等工具,因为它添加了第二个 c $ < comInterfaceExternalProxyStub />

  6. 在VS中创建一个exe项目并引用之前构建的库。

  7. 建立exe专案。

  8. 执行regsvr32 / u mycomdll.dll。删除所有注册表关联。

  9. 运行exe。在我的情况下,类库中的COM组件的调用和事件完美地工作。

注意:我不知道为什么VS不在.manifest中自动包含< comInterfaceExternalProxyStub /> 元素。在编写时,自动更新清单的唯一方法是在VS中添加一个后期构建任务。在我的例子中,我将整个XML清单复制到类库项目中的一个XML中,然后在构建输出中覆盖了.manifest文件。



单元的COM不一致。目前在我的case调用Interop方法工作,但事件不。它与事实有关,测试运行器不是编译的依赖的知识,因此这样不存在于激活上下文。


I have a native dll (which is an activex control) that I need use with my .NET application without having to register the dll in the registry.

I have read several in depth posts about registration free activation, some of the better ones are

A lengthy one from Steve White and Leslie Muller

This one from samuel jack

And another from Mike Makarov

and from what I can see it is possible. However several hours and hundreds of tests later I just cant get it to work. I've done a bit of PInvoking and even less with ActiveX controls in .NET in my career, so would appreciate any input from anyone whom might have kicked goals on this before.

So far I'm following Steves advice, in terms of building an application that works and then trying to formulate the winning manifest file syntax via repeatedly running the regsvr32 command to add and remove the unmanaged dll's from the registry. Just a bog simple .Net console application with about 10 lines of code...

One part that I am confused about is the interop. The native dll's I have are also accompanied with managed runtime callable wrappers (RCW's). In my .NET application I add reference to these RCW's and then can consume the respective classes and functionality provided for by the unmanaged dll's. I'm not PInvoking via dllimport.

In creating the manifest files I'm unsure if I need to worry about these RCW's and how they work in a registration free scenario, or even if if they need to be in the compiled output?

I've also tried several tools such as (OLE/COM object viewer, Mt.exe from the windows sdk, and regsvr42 from codeproject). But the manifest structure and necessary GUID's all vary between tools and posts.

Current status is that I receive a InvalidCastException "Unable to cast COM object of type System.__ComObject to interface type MyFunkyDllLib.FunkyDllControl. This operation failed because the QueryInterface call on the COM component for the interface with IID '{some guid}' failed due to the following error: Library not registered.

Can anyone confirm the correct syntax for the application and dll manifest files ? Online posts even vary on the name with some using sxs in the name....

Update1: Whilst Joe's answer below did not work it did give me some better insights into reg free COM. In the properties of the Interop dll (the one that that is added to the project reference from the list of installed COM components on the dev machine) I changed the Isolated Property to True. This has the effect of making VS dump a copy of the COM dll (not the interop, it is embeded in the exe) to the bin\debug folder. VS also then creates a myapplication.exe.manifest.

In this manifest file is supposedly sufficent information for reg free com. I found other posts indicating success with this method but in my case I still ended up with the same InvalidCastException.

Reading over Samuel Jacks post again, I tried his method of creating both a manifest for the exe and the COM dll using the clsid information from the VStudio output manifest when Isolated=true. (I also deleted the <file/> section created by VS from the exe.manifest). After unregistering the COM from the registry I now have success ! The application starts and does not error. Why this approach works and not the Isolated=true I have no idea because it is beyond my knowledge of manifests and assemblies.

However we are still not at the wizards castle yet Toto.

Now I'm back at the same issue I posted on this SO thread. However in this scenario unit tests are not involved. Just a plain console application with 10 lines of code. Works fine when in normal registered COM mode, but not in reg free mode.

解决方案

After many hours of trial and error I finally got a solution to how to successfully implement RegFree COM. Here is a full explanation incase it helps someone else.

  1. I create a new .NET class library in VS
  2. Right click references and select the COM components of interest. (Note: for the COM to be visible in the list they must be registered on the development machine. This can be acheived by using the Regsvr32.exe tool included with windows. Calling "regsvr32 mycomdll.dll" registers it in the windows registry)
  3. Right click the COM reference, goto properties, and then set Isolated=True. This has the effect of causing VS to output a .manifest file supposedly containing all the registry details necessary for a consuming .exe to know what resources to load instead of querying the registry. However in my case it was incomplete. Calls to Interop methods would work, but events from the COM component would not. See step 5 for my solution)
  4. Build the project. The .manifest should appear in the build output.
  5. Open the manifest in notepad or similar. Within the <assembly /> tag I needed to add a <comInterfaceExternalProxyStub /> tag with appropriate IID, tlbid and proxyStubClsid32 GUID elements. Elements of the manifest are documented on msdn. In my case the proxy/stub was proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"/> which is the built in windows proxy. The iid and tlbid I originally discovered via Process Monitor whilst calling regsvr32. An easier and more reliable option I later discovered was to use a tool like SxS manifest maker as it added a second <comInterfaceExternalProxyStub /> that I originally did not have.
  6. Create an exe project in VS and reference the previously built library.
  7. Build the exe project.
  8. Run regsvr32 /u mycomdll.dll. To remove all registry associations.
  9. Run the exe. In my case calls to and events from the COM component in the class library worked perfectly.

Caveats: I dont know why VS does not include the <comInterfaceExternalProxyStub /> element automatically in the .manifest. At the time of writing the only way to automatically update the manifest was to add a post build Task in VS. In my case I copied the entire XML manifest into an XML in the class library project and then just overwrote the .manifest file in the build output.

Unit (integration) testing of the COM is inconsistent. Currently in my case calls to Interop methods work, but events do not. It has something to do with the fact that the Test Runner is not compiled with knowledge of the dependencies and therefore such are not present in the activation context.

这篇关于从.NET注册自由激活本机COM(activex)组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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