Reputation: 949
So I have the following code:
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetDllDirectory(string dllPath);
In a function:
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);
However, when I run a small app with just this function from the same folder as the DLLs, there is no issue. When I move the executable to another machine that has the G-drive mapped, I get a security exception.
<IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
version="1"
Flags="UnmanagedCode"/>
Not sure how to handle this. In Assembly.LoadFrom I pass evidence.
The exception is thrown at the first rtsObj.InvokeMember.
Appreciate your help!
EDIT: The application actually fails to launch on other machines. If I have the executable alone by itself on my machine, it will launch.
Upvotes: 0
Views: 1142
Reputation: 2882
You can change your security policy to allow the CLR to open from a remote source.
// 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.
Upvotes: 1
Reputation: 169008
.NET assemblies residing on remote network shares are not considered trusted enough by the default .NET security policy to allow them to execute P/Invokes. You will need to change your security policy, copy the assembly to a local folder (not a mapped network drive), or remove the SetDllDirectory
P/Invoke call entirely.
Upvotes: 1