Reputation: 38003
I am loading an assembly using Assembly.LoadFrom(fileName)
. When fileName
is on the local machine, everything works fine. When, however, the identical file (and dependencies) are on a remote network share, I get a System.Security.SecurityException
the moment I try to create a new SqlConnection
from the remote assembly:
System.Security.SecurityException: Request for the permission of type 'System.Data.SqlClient.SqlClientPermission, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
What's the cure?
Upvotes: 1
Views: 4969
Reputation: 6281
You could load the assembly as bytes and load it with Assembly.Load(bytes)
, maybe this works.
Or you give the application the requested permission.
I made a little test and it worked for me. Here is some code:
static Dictionary<Assembly, String> _Paths = new Dictionary<Assembly, String>();
static void Main(string[] args)
{
AppDomain current = AppDomain.CurrentDomain;
current.AssemblyResolve += new ResolveEventHandler(HandleAssemblyResolve);
// This line loads a assembly and retrieves all types of it. Only when
// calling "GetTypes" the 'AssemblyResolve'-event occurs and loads the dependency
Type[] types = LoadAssembly("Assemblies\\MyDLL.dll").GetTypes();
// The next line is used to test permissions, i tested the IO-Permissions
// and the Reflection permissions ( which should be denied when using remote assemblies )
// Also this test includes the creation of a Form
Object instance = Activator.CreateInstance(types[0]);
}
private static Assembly LoadAssembly(string file)
{
// Load the assembly
Assembly result = Assembly.Load(File.ReadAllBytes(file));
// Add the path of the assembly to the dictionary
_Paths.Add(result, Path.GetDirectoryName(file));
return result;
}
static Assembly HandleAssemblyResolve(object sender, ResolveEventArgs args)
{
// Extract file name from the full-quallified name
String name = args.Name;
name = name.Substring(0, name.IndexOf(','));
// Load the assembly
return LoadAssembly(Path.Combine(_Paths[args.RequestingAssembly], name + ".dll"));
}
There may be files which do not have a matching name and file name, but you can resolve this by checking all files in folder with AssemblyName.GetAssemblyName(file)
.
Upvotes: 4
Reputation: 38003
Well, I found a workaround. I could not find any way to circumvent the SecurityException
problem - so instead of loading the assembly from the remote folder, I simply copied the remote folder contents at runtime to the local computer and ran from there. Simple, neat and works perfectly. Plus, it's arguably a better way of working, so that the clients are running off their local copy instead of putting load on the server, and it makes it much easier to deploy an updated version of the original, without any file locking.
Caveat to anyone who tries to follow in my footsteps: don't try and copy to a subfolder of your app directory; for some reason this causes errors with dependencies. Rather copy to 'Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)` or some other folder to which you know you have write access.
Upvotes: 2
Reputation: 120450
The assembly is being loaded with LocalIntranet permission set. This restricts certain APIs. See:
http://msdn.microsoft.com/en-us/library/03kwzyfc.aspx and http://msdn.microsoft.com/en-us/library/0x4t63kb%28v=vs.80%29.aspx
Upvotes: 1