在远程计算机上使用Assembly.LoadFrom()加载的程序集导致SecurityException

我正在使用Assembly.LoadFrom(fileName)加载程序集。 当fileName在本地机器上时,一切正常。 但是,当相同的文件(和依赖项)位于远程网络共享上时,我尝试从远程程序集创建新的SqlConnection会收到System.Security.SecurityException

System.Security.SecurityException:请求类型为’System.Data.SqlClient.SqlClientPermission,System.Data,Version = 2.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089’的权限失败。

什么是治愈方法?

您可以将程序集作为字节加载并使用Assembly.Load(bytes)加载它,也许这是有效的。

或者您向应用程序提供所请求的权限。

编辑:

我做了一点测试,它对我有用。 这是一些代码:

 static Dictionary _Paths = new Dictionary(); 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")); } 

重要的事情:

可能存在没有匹配名称和文件名的文件,但您可以通过使用AssemblyName.GetAssemblyName(file)检查文件夹中的所有文件来解决此问题。

程序集正在加载LocalIntranet权限集。 这限制了某些API。 看到:

http://msdn.microsoft.com/en-us/library/03kwzyfc.aspx和http://msdn.microsoft.com/en-us/library/0x4t63kb%28v=vs.80%29.aspx

好吧,我找到了一个解决方法。 我找不到任何方法来规避SecurityException问题 – 所以不是从远程文件夹加载程序集,而是简单地将远程文件夹内容在运行时复制到本地计算机并从那里运行。 简单,整洁,完美。 此外,它可以说是一种更好的工作方式,因此客户端运行本地副本而不是在服务器上加载,这使得部署更新版本的原始文件变得更加容易,而无需任何文件锁定。

警告任何试图跟随我的脚步的人:不要尝试复制到你的app目录的子文件夹; 由于某种原因,这会导致依赖性错误。 而是复制到’Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)`或您知道自己具有写访问权限的其他文件夹。