Как получить доступ к встроенным библиотекам Fody / Costura во время выполнения из другого домена приложения - PullRequest
0 голосов
/ 31 октября 2019

Мне нужно создать новый домен приложения для моего решения, чтобы я мог вызывать метод из его собственного домена приложения. Все зависимые DLL-файлы для моего решения были встроены в my.exe с помощью Fody / Costura. Я создал класс Loader : MarshalByRefObject для вызова моего метода, но когда я запускаю загрузчик во время выполнения, я получаю исключение:

Не удалось загрузить файл или сборку 'my.Assembly, Version = 19.1.7242.23931, Culture= нейтральный, PublicKeyToken = null 'или одна из его зависимостей. Система не может найти указанный файл.

Код ищет файлы .dll в моем AppDomain.CurrentDomain.BaseDirectory для выполнения моего метода через загрузчик, но их нет, но они встроены в исполняемый файл. Есть ли способ для моего нового AppDomain узнать о сборках, которые были встроены в мой исполняемый файл, без необходимости загружать их из BaseDirectory?

Я искал способы загрузить другие сборки в мой новый AppDomain, ноне нашел способ сделать это. Я также подозреваю, что для этого может быть Fody / Costura API, но я не нашел ничего подходящего для этого сценария.

        internal class Loader : MarshalByRefObject
        {
            object CallInternal(string dll, string typename, string method, object[] parameters)
            {

                Assembly a = Assembly.LoadFile(dll);
                Type t = a.GetType(typename);
                MethodInfo m = t.GetMethod(method);
                Console.WriteLine("Invoking " + m.Name);
                return m.Invoke(null, parameters);
            }

            public static object Call(string dll, string typename, string method, params object[] parameters)
            {
                object result = null;
                try
                {
                    AppDomain newAppDomain = AppDomain.CreateDomain("myNewDomain", AppDomain.CurrentDomain.Evidence, AppDomain.CurrentDomain.SetupInformation);
                    Loader ld = (Loader)newAppDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(Loader).FullName);  //DLL file not found exception thrown from here
                    result = (Loader)ld.CallInternal(dll, typename, method, parameters);
                    AppDomain.Unload(newAppDomain);
                }
                catch (Exception ee)
                {
                    Console.WriteLine("Exception Message [" + ee.Message + "]");
                    PDFUtil.Report.ErrSilent(ee);
                }
                return result;
            }
        }

Я хочу создать экземпляр класса Loader без необходимости загружать.dll с диска во время выполнения. Возможно ли это с помощью встроенных DLL-файлов Fody / Costura?

1 Ответ

0 голосов
/ 31 октября 2019

Я добавил свои .dll в проект Visual Studio и установил для Build-Action значение Embedded Resource

Я запускаю этот фрагмент кода, чтобы получить сборку в мой новый домен приложений:

string resName = null;
foreach (string resourceName in Assembly.GetExecutingAssembly().GetManifestResourceNames())
{
   Console.WriteLine("Assembly.GetExecutingAssembly().GetManifestResourceNames() [" + resourceName + "] ");
   if (resourceName.Contains("my.Assembly"))
   {
      resName = resourceName;
      Console.WriteLine("CurrentDomain Assembly my.Assembly [" +  "] Resource name [" + resName + "]");
    }

}
Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resName);
if (s != null)
{
    byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);
    Assembly a = Assembly.Load(data);
    newAppDomain.Load(data);

     foreach (Assembly cdAssem in newAppDomain.GetAssemblies())
     {
        Console.WriteLine("newAppDomain Assembly 2 [" + cdAssem.GetName().FullName + "]");
      }
}

Я вижу, что сборка является частью моего нового домена приложений:

newAppDomain Assembly 2 [mscorlib, версия = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089]

newAppDomain Assembly 2 my.Assembly Version = 19.1.7243.19014, Culture = нейтральный, PublicKeyToken = null]

Но использование CreateInstanceAndUnwrap () по-прежнему завершается ошибкой, говоря, что он не может найти my.Assembly.dll. Мне интересно, может ли единственный способ загрузить сборку в домен приложений, загрузив ее из базового каталога?

...