所以我有以下代码:
[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抛出异常。
感谢您的帮助!
编辑:应用程序实际上无法在其他计算机上启动。如果我在我的机器上单独拥有可执行文件,它将启动。
答案 0 :(得分:1)
默认的.NET安全策略认为驻留在远程网络共享上的.NET程序集不足以允许它们执行P / Invokes。您需要更改安全策略,将程序集复制到本地文件夹(而不是映射的网络驱动器),或完全删除SetDllDirectory
P / Invoke调用。
答案 1 :(得分:1)
您可以更改安全策略以允许CLR从远程源打开。
// 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.