0

我需要为我的解决方案创建一个新的 AppDomain,以便我可以从它自己的 AppDomain 调用该方法。我的解决方案的所有依赖 .dll 文件都已使用 Fody/Costura 嵌入到 my.exe 中。我创建了一个Loader : MarshalByRefObject类来调用我的方法,但是当我在运行时执行加载器时,我得到一个异常:

无法加载文件或程序集“my.Assembly,Version=19.1.7242.23931,Culture=neutral,PublicKeyToken=null”或其依赖项之一。该系统找不到指定的文件。

该代码正在我的 AppDomain.CurrentDomain.BaseDirectory 中查找 .dll 文件以通过加载程序执行我的方法,但它们不存在但嵌入在可执行文件中。有没有办法让我的新 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。使用 Fody/Costura 嵌入式 .dll 可以做到这一点吗?

4

1 回答 1

1

我将我的 .dll 添加到我的 Visual Studio 项目中,并将 Build-Action 设置为 Embedded Resource

我正在运行这段代码以将程序集放入我的新 AppDomain:

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

我可以看到该程序集是我的新 AppDomain 的一部分:

newAppDomain 程序集 2 [mscorlib,版本=4.0.0.0,文化=中性,PublicKeyToken=b77a5c561934e089]

newAppDomain 程序集 2 my.Assembly 版本=19.1.7243.19014,Culture=neutral,PublicKeyToken=null]

但是使用 CreateInstanceAndUnwrap() 仍然失败,说它找不到 my.Assembly.dll。我想知道是否可以将程序集加载到 AppDomain 的唯一方法是从基本目录加载它?

于 2019-10-31T19:18:10.947 回答