可以在 C#.NET COM 组件中执行或加载程序集吗?

Posted

技术标签:

【中文标题】可以在 C#.NET COM 组件中执行或加载程序集吗?【英文标题】:Can an assembly be executed or loaded within C#.NET COM component? 【发布时间】:2009-12-07 08:12:20 【问题描述】:

我有一个 COM(用 .NET 编写),它需要创建一个 AppDomain 并在其中加载/执行 .NET 程序集。这样我就可以稍后卸载该 appDomain 以及所有加载的 dll。在正常(例如 WinForms).NET 应用程序中工作正常时,如果此代码在 COM 上下文中运行,我会收到安全异常。假设 COM 程序集被强命名并放置在 GAC 中,它具有完全信任策略。任何人都可以解释这是否可能,如果不能 - 为什么?

【问题讨论】:

您遇到了什么样的安全异常?我有一个运行良好的 .NET COM LocalServer 应用程序(虽然我不使用 GAC)。 请求“System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”类型的权限失败。当我尝试 AppDomain.executeAssembly() 时。当我尝试加载一个文件时,我得到 FileIOPermission(或类似的)异常。 我也切换到 GAC 的 COM 组件,因为在创建对象时,例如从 c++ 代码我得到了 fileNotFound Exeption。当我将 COM 程序集放入 GAC 时,它工作正常。然后我得到了安全异常,所以我签署了我使用的程序集并尝试将它们放入 GAC - 没有成功。 【参考方案1】:

是的,它可以。为了让 CAS 让你这样做,你应该包括

[assembly: System.Security.AllowPartiallyTrustedCallersAttribute()]

COM 程序集和加载的程序集中的属性。 此外,创建对象和执行程序集还需要向新的应用程序域添加适当的权限集,如下所示:

 AppDomainSetup setup = new AppDomainSetup();
 setup.ApplicationBase = Path.GetDirectoryName(path); 
 PermissionSet trustPermissionSet = new PermissionSet(PermissionState.Unrestricted);
 AppDomain newDomain = AppDomain.CreateDomain( "descriptive name", null, setup, trustPermissionSet);

然后您可以简单地通过CreateInstanceFromAndUnwrap()executeAssembly 创建对象。 这个问题还有一个解决方法——使用Activator

System.Runtime.Remoting.ObjectHandle objHandle = Activator.CreateInstanceFrom(_pluginStore[path], path, pluginClass);

if (objHandle != null)

    object unwrappedInstance = objHandle.Unwrap();
    result.Add(unwrappedInstance);

但在其执行后代码无权做任何“复杂的事情”。

您可以了解更多here。

【讨论】:

以上是关于可以在 C#.NET COM 组件中执行或加载程序集吗?的主要内容,如果未能解决你的问题,请参考以下文章

VB.NET显示程序的进度,该怎么做?

.Net中使用com组件后发生System.ArithmeticException异常的解决办法(Message=算术运算中发生溢出或下溢。)

正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码

未能加载的文件或程序集.怎么解决

在 asp.net 中使用 c++ dll - 异常:无法加载文件或程序集

.NET 3.5 未能加载文件或程序集“Microsoft.Web.Infrastructure”(解决后追加50-200悬赏)