Naga Sindhura Ответов: 1

Об ошибке при загрузке библиотеки DLL в отдельном домене приложения


ПРИВЕТ,

Я создал один домен приложения и хотел бы загрузить и запустить в нем одну библиотеку dll вместе с некоторым набором разрешений ввода-вывода. Я мог бы создать экземпляр create the, но мне не удалось загрузить сборку. Я не мог распознать ошибку,которую я делаю, однако следующее сообщение об ошибке при загрузке сборки. Не могли бы вы помочь / поправить меня в этом вопросе:

сообщение об ошибке:

"
Additional information: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
"

трассировка стека:

at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
at System.Security.CodeAccessPermission.Demand()
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadFrom(String assemblyFile, Evidence securityEvidence, Byte[] hashValue, AssemblyHashAlgorithm hashAlgorithm, Boolean forIntrospection, Boolean suppressSecurityChecks, StackCrawlMark& stackMark)
at System.Reflection.Assembly.LoadFrom(String assemblyFile)
at AppDomainSample.AppDomainSample.ThrirdPartyDomainLoader.LoadAssembly(String dllPath)
at AppDomainSample.AppDomainSample.ThrirdPartyDomainLoader.LoadAssembly(String dllPath)
at AppDomainSample.AppDomainSample.Main() in D:\DotNetTraining0504\AppDomainSample\AppDomainSample\AppDomainSample.cs:line 34
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()


Что я уже пробовал:

using System;
using System.Reflection;
using System.Configuration;

namespace AppDomainSample
{
    public class AppDomainSample 
    {
        public static void Main()
        {
            var generateFilesPluginPath = ConfigurationManager.AppSettings["GenerateFilesPlugin"];
            var generateFilesPluginPathName = ConfigurationManager.AppSettings["GenerateFilesPluginName"];

            var appDomainSetup = new AppDomainSetup
            {
                ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase
            };


            var permissionSet = AppDomainPermissionSets.GetFileIOPermissionset();

            var generateFilesAppDomain = AppDomain.CreateDomain(
                generateFilesPluginPathName,
                null,
                appDomainSetup,
                permissionSet);

            var thrirdPartyDomainLoader =
                (ThrirdPartyDomainLoader)
                generateFilesAppDomain.CreateInstanceAndUnwrap(
                    typeof(ThrirdPartyDomainLoader).Assembly.FullName,
                    typeof(ThrirdPartyDomainLoader).FullName);

            thrirdPartyDomainLoader.LoadAssembly(@"D:\EpamDotNetTraining0504\AppDomainSample\GenerateFilesPlugin\bin\Debug\GenerateFilesPlugin.dll");

            thrirdPartyDomainLoader.MethodInvoker(
                ApplicationBase(generateFilesPluginPath),
                "GenerateFilesPlugin.GenerateFiles",
                "CreateFile",
                 @"D:\",
                "temp.text");

            AppDomain.Unload(generateFilesAppDomain);

            Console.ReadLine();
        }

        public class ThrirdPartyDomainLoader : MarshalByRefObject
        {
            private Assembly _assembly;

            public void LoadAssembly(string dllPath)
            {
               var  _assembly = Assembly.LoadFrom(dllPath);
            }

            public void MethodInvoker(string dllpath, string className, string methodName, params object[] parameters)
            {
                var assm = Assembly.LoadFile(dllpath);

                var type1 = assm.GetType(className);

                var genericInstance = Activator.CreateInstance(type1);

                var method = type1.GetMethod(methodName);

                object obje = null;
                try
                {
                    obje = method.Invoke(genericInstance, new object[] { 1, 2 });
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                }

                Console.WriteLine(obje);
            }
        }

        public static string ApplicationBase(string path)
        {
            var appDomainSetup = new AppDomainSetup { ApplicationBase = path };

            return appDomainSetup.ApplicationBase;
        }
    }
}



Наборы разрешений, применяемые для домена приложения
public static class AppDomainPermissionSets
{
    public static PermissionSet GetFileIOPermissionset()
    {
        var permissionSet = new PermissionSet(PermissionState.None);
        permissionSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

        permissionSet.AddPermission(
            new FileIOPermission(
                FileIOPermissionAccess.Write,
                ConfigurationManager.AppSettings["GenerateFilesPluginRestrictedPath"]));

        return permissionSet;
    }

}


Логика в 3-й партии Dll:

using System;
using System.IO;

namespace GenerateFilesPlugin
{
    public class GenerateFiles
    {
        public bool CreateFile(string path, string file)
        {
            if (path == null || file == null)
            {
                Console.WriteLine("Invalid Input");

                return false;
            }

            try
            {
                File.Create(Path.Combine(path, file));

                return true;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

            return false;
        }
    }
}

1 Ответов

Рейтинг:
0

Kornfeld Eliyahu Peter

Похоже, что пользователь, запускающий сайт под управлением IIS, не имеет на это никаких разрешений (для загрузки внешних сборок)...
Попробуйте один из них:
1. переключите usr (это хорошо для тестирования, но, возможно, неправильно для реальной среды)
2. установите уровень доверия на полный: Установите уровень доверия (IIS 7)[^]


Naga Sindhura

Привет Корнфельд Элияху Петерб

Да, вы правы, у меня нет прав локального администратора, и даже переключение пользователя также невозможно. Тем не менее, я добавил следующие строки в свой файл app.config, но я мог видеть аналогичное сообщение об ошибке, как и ранее.
&ЛТ;система.веб&ГТ;
< уровень доверия= "полный"/>

Kornfeld Eliyahu Peter

Проверьте журнал событий - у вас нет разрешения на переопределение уровня доверия...
(также читайте это - просто для удовольствия : -) ... https://msdn.microsoft.com/en-us/library/ms998326.aspx)

Naga Sindhura

Конечно, спасибо, я разберусь. Я попытался загрузить dll в метод AppDomainSample -> Main (), используя следующий код, и работает без каких-либо проблем, но я не смог загрузить его через экземпляр thrirdPartyDomainLoader. Как вы думаете, все еще ли это проблема с разрешением или неправильный код?

ВАР РТМ =
Собрание.Командами(
@"D:\DotNetTraining0504\AppDomainSample\GenerateFilesPlugin\bin\Debug\GenerateFilesPlugin.dll")
.GetType ("GenerateFilesPlugin.GenerateFiles");

Kornfeld Eliyahu Peter

Это может быть способ, которым вы создаете свой новый домен приложения...
Попробуйте самую простую форму: AppDomain.CreateDomain ('name-for-new-domain);
Кроме того, CreateInstanceAndUnwrap кажется неправильным...
Попробуйте сделать так: CreateInstanceAndUnwrap (Assembly.GetAssembly(typeof(ThrirdPartyDomainLoader)).Полное имя, typeof(ThrirdPartyDomainLoader).ToString ()) как ThrirdPartyDomainLoader
(Он основан на коде, который я написал в одном из своих советов, и оказался работающим :-))

Naga Sindhura

Я изменил свой код с var generateFilesAppDomain = AppDomain.Метода createdomain(
generateFilesPluginPathName, null, appDomainSetup, permissionSet); to generateFilesAppDomain = AppDomain.CreateDomain(generateFilesPluginPathName), однако мне нужно ограничить выполнение домена каким-то разрешением, например, не иметь доступа с диском C или какими-то чувствительными путями. Как я мог это сделать один? любое предложение.

Kornfeld Eliyahu Peter

Вы хотите ограничить доступ третьей стороны к некоторым ресурсам (например, c: drive)?

Naga Sindhura

да, например, c: drive или какой-нибудь другой.

Kornfeld Eliyahu Peter

Теперь это работает? После перемены?

Naga Sindhura

Нет, это не так. Я не смог бы ограничить того, кого хочу.

Kornfeld Eliyahu Peter

Я имею в виду-без каких-либо ограничений, это работает?

Naga Sindhura

после удаления appDomainSetup, permissionSetup из AppDomain.CreateDomain, dll может создавать файлы, где бы я ни упоминал, например, включая C:\Users\UserName\Desktop\, он не ограничивает никаких путей моей локальной машины.

Kornfeld Eliyahu Peter

Это означает, что ваши разрешения слишком жесткие...
Попробуйте создать набор разрешений с помощью PermissionState.Неограниченный, а затем удалить IO для C: drive...
RemovePermission(новое разрешение fileiopermission(в разделе fileiopermissionaccess.AllAccess, "c:\\"))

Naga Sindhura

Я применил следующие наборы разрешений, но все равно получаю аналогичное сообщение об ошибке.
var newPer = new PermissionSet(PermissionState.Неограниченный);
ньюпер.RemovePermission(typeof(FileIOPermission));

Kornfeld Eliyahu Peter

Удаление всех разрешений ввода-вывода не будет делать...