Сборка, загруженная с помощью Assembly.LoadFrom () на удаленной машине, вызывает исключение SecurityException - PullRequest
1 голос
/ 29 ноября 2011

Я загружаю сборку, используя Assembly.LoadFrom(fileName). Когда fileName находится на локальной машине, все работает нормально. Однако когда идентичный файл (и зависимости) находятся на удаленном сетевом ресурсе, я получаю System.Security.SecurityException в тот момент, когда пытаюсь создать новый SqlConnection из удаленной сборки:

System.Security.SecurityException: запрос на разрешение типа 'System.Data.SqlClient.SqlClientPermission, System.Data, Версия = 2.0.0.0, Культура = нейтральная, PublicKeyToken = b77a5c561934e089 ' не удалось.

Что за лекарство?

Ответы [ 3 ]

4 голосов
/ 29 ноября 2011

Вы можете загрузить сборку в байтах и ​​загрузить ее с Assembly.Load(bytes), возможно, это сработает.

Или вы даете приложению запрошенное разрешение.

Редактировать:

Я сделал небольшой тест, и это сработало для меня.Вот некоторый код:

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"));
}

Что-то важное:

Могут быть файлы, которые не имеют совпадающего имени и имени файла, но это можно решить, проверив все файлы в папке с помощьюAssemblyName.GetAssemblyName(file).

1 голос
/ 29 ноября 2011

Ну, я нашел обходной путь. Я не смог найти способа обойти проблему SecurityException - поэтому вместо загрузки сборки из удаленной папки я просто скопировал содержимое удаленной папки во время выполнения на локальный компьютер и запустил оттуда. Просто, аккуратно и отлично работает. Кроме того, это, возможно, лучший способ работы, так что клиенты запускают свою локальную копию вместо того, чтобы загружать сервер, и это упрощает развертывание обновленной версии оригинала намного , без любая блокировка файла.

Предостережение любому, кто пытается следовать по моим стопам: не пытайтесь копировать в подпапку каталога вашего приложения; по какой-то причине это вызывает ошибки с зависимостями. Скорее скопируйте в «Environment.GetFolderPath (Environment.SpecialFolder.CommonApplicationData)» или в другую папку, в которую, как вы знаете, у вас есть права на запись.

1 голос
/ 29 ноября 2011

Сборка загружается с набором разрешений LocalIntranet.Это ограничивает определенные API.См .:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...