使用Reflection,会引发安全性异常

时间:2010-11-11 17:58:29

标签: c# .net security exception reflection

所以我有以下代码:

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetDllDirectory(string dllPath);

在一个功能中:

            SetDllDirectory(@"G:\Sean\Debug\");

            Assembly loadedDLL = Assembly.LoadFrom(@"G:\Sean\Debug\BonderControlPanelSim.dll", AppDomain.CurrentDomain.Evidence);
            Type rtsObj = loadedDLL.GetType("Oe.Te.Ranorex.Instrument.BonderControlPanelSim");
            Object obj = Activator.CreateInstance(rtsObj);

            rtsObj.InvokeMember("Initialize", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, obj, new object[] { "COM3", 1, 2 });
            rtsObj.InvokeMember("PushStart", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, obj, new object[] { 3 });
            rtsObj.InvokeMember("Shutdown", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, obj, null);

然而,当我在与DLL相同的文件夹中运行只有这个函数的小应用程序时,没有问题。当我将可执行文件移动到另一台映射了G驱动器的计算机时,我得到一个安全例外。

<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="UnmanagedCode"/>

不确定如何处理此问题。在Assembly.LoadFrom中我传递证据。

在第一个rtsObj.InvokeMember抛出异常。

感谢您的帮助!

编辑:应用程序实际上无法在其他计算机上启动。如果我在我的机器上单独拥有可执行文件,它将启动。

2 个答案:

答案 0 :(得分:1)

默认的.NET安全策略认为驻留在远程网络共享上的.NET程序集不足以允许它们执行P / Invokes。您需要更改安全策略,将程序集复制到本地文件夹(而不是映射的网络驱动器),或完全删除SetDllDirectory P / Invoke调用。

答案 1 :(得分:1)

您可以更改安全策略以允许CLR从远程源打开。

http://blogs.msdn.com/b/shawnfa/archive/2009/06/08/more-implicit-uses-of-cas-policy-loadfromremotesources.aspx

// From the Article
// Since this application only trusts a handful of LoadFrom operations,
// we'll put them all into the same AppDomain which is a simple sandbox
// with a full trust grant set.  The application itself will not enable
// loadFromRemoteSources, but instead channel all of the trusted loads
// into this domain.
PermissionSet trustedLoadFromRemoteSourceGrantSet
    = new PermissionSet(PermissionState.Unrestricted);

AppDomainSetup trustedLoadFromRemoteSourcesSetup = new AppDomainSetup();
trustedLoadFromRemoteSourcesSetup.ApplicationBase =
    AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

AppDomain trustedRemoteLoadDomain =
    AppDomain.CreateDomain("Trusted LoadFromRemoteSources Domain",
                           null,
                           trustedLoadFromRemoteSourcesSetup,
                           trustedLoadFromRemoteSourcesGrantSet);

// Now all trusted remote LoadFroms can be done in the trustedRemoteLoadDomain,
// and communicated with via a MarshalByRefObject.