简体   繁体   English

从.Net程序卸载COM dll

[英]Unload COM dll from .Net program

We have a .Net application from which a C++ COM component is being instantiated. 我们有一个.Net应用程序,正在从中实例化一个C ++ COM组件。 We load the COM component from a child form window. 我们从子窗体窗口加载COM组件。 There is a common resource that is being edited by the .Net application, which inturn is being used by the COM dll to start up. .Net应用程序正在编辑一个公共资源,而COM dll则使用该资源来启动。

When the following sequence of steps are performed: 当执行以下步骤序列时:
1. Instantiate COM component in the new child window The COM component is instantiated, and is used by the child form , and after being used, it is being set to NULL , hoping that the COM component would be unloaded. 1.在新的子窗口中实例化COM组件该COM组件已实例化,并由子窗体使用,并且在使用后将其设置为NULL,希望将COM组件卸载。
2. Keep child window open, and then edit the resource 2.保持子窗口打开,然后编辑资源
3. Now, go and "refresh" the form, to create a new COM instance, to see the refelection of the changed resource - but the resource is not refreshed. 3.现在,转到并“刷新”表单,以创建新的COM实例,以查看更改后的资源的重现-但不会刷新资源。

We also used Marshal.ReleaseComObject method, but to no success. 我们还使用了Marshal.ReleaseComObject方法,但没有成功。 Please advice. 请指教。

Once a DLL is loaded into a .Net AppDomain, it is not possble to force a DLL to be unloaded. 一旦将DLL加载到.Net AppDomain中,就无法强制将DLL卸载。 It's an unfortunate limitation of the CLR. 这是CLR的不幸限制。 If you absolutely need the DLL to unload you can do the following. 如果您绝对需要DLL来卸载,则可以执行以下操作。

  1. Create a new AppDomain 创建一个新的AppDomain
  2. Load the DLL into the new DLL 将DLL加载到新的DLL中
  3. Do the work in the new AppDomain 在新的AppDomain中完成工作
  4. Unload the new AppDomain 卸载新的AppDomain

If a DLL is only loaded in one AppDomain, unloading the AppDomain will unload the DLL as well. 如果仅在一个AppDomain中加载DLL,则卸载AppDomain也会同时卸载DLL。 So this will get the DLL unloaded. 因此,这将使DLL卸载。 However it is a pretty heavyweight answer. 但是,这是一个非常重要的答案。

A discussion on clrInterop page describes very close what you outlined in your question. 在clrInterop页面上讨论非常接近地描述了您在问题中概述的内容。 The garbage collector does not unload the native dll. 垃圾收集器不会卸载本机dll。 I quote: " It could be very dangerous for clr to do this because there might be other code (even native code) which depends on that dll. If you do assure that dll is not used any more, calling a windows API like FreeLibrary may be easiest way to unload the dll." 我引用:“ clr这样做可能非常危险,因为可能还有其他代码(甚至是本机代码)依赖于该dll。如果您确保不再使用该dll,则调用Windows API(例如FreeLibrary)可能是卸载dll的最简单方法。”

So you'll need to interop FreeLibrary and use that to unload the native dll. 因此,您需要互操作FreeLibrary并使用它来卸载本机dll。 Although I might add: don't if you can try to find a solution where you don't need to unload the dll. 尽管我可能会补充:如果您可以尝试找到不需要卸载dll的解决方案,请不要这样做。

COM object and DLL are two different things, even if one resides in another. 即使一个对象驻留在另一个对象中,COM对象和DLL也是两个不同的事物。 Certain hacks are possible, but much better solution is to rewrite this part in a more sensible way which doesn't rely on DLL unloading. 某些骇客是可能的,但是更好的解决方案是以更明智的方式重写此部分,而不依赖于DLL的卸载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM