首页 > 解决方案 > 如何访问合并的 DLL 中的嵌入式资源?

问题描述

我已经设法使用 AssemblyResolve 事件将 DLL 文件作为嵌入式资源合并到一个 DLL 中,但是当我尝试在另一个控制台应用程序中使用该 Dll 时,我无法访问这个合并的 Dll 所具有的嵌入式资源。例如,这个合并的 Dll 包含我需要使用的类库的另一个 Dll,并且我想访问这个类库具有的公共方法/接口等,但似乎我无法从这个合并的 Dll 访问它们。如何解决这个问题?


static Dictionary<string, Assembly> dic = null;

static void Main(string[] args)
{
    var filesList = Directory.EnumerateFiles( //path to Resources folder inside console application, which holds all DLLs that are set as embedded resources );

      foreach (var file in filesList)
      {
           var fname = Path.GetFileNameWithoutExtension(file);
           var embRes = "ConsoleAppTest.Resources." + fname + ".dll";
           Console.WriteLine(embRes);
           Load(embRes, fname + ".dll");
       }
       AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
       Console.ReadKey();
 }

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
     return GetAssembly(args.Name);
}

static void Load(string embeddedResource, string fileName)
 {
            if (dic == null)
                dic = new Dictionary<string, Assembly>();

            byte[] assemblyData = null;
            Assembly asm = null;
            Assembly curAsm = Assembly.GetExecutingAssembly();

            using (Stream stream = curAsm.GetManifestResourceStream(embeddedResource))
            {
                // Either the file is not existed or it is not mark as embedded resource
                if (stream == null)
                    throw new Exception(embeddedResource + " is not found in Embedded Resources.");

                // Get byte[] from the file from embedded resource
                assemblyData = new byte[(int)stream.Length];
                stream.Read(assemblyData, 0, (int)stream.Length);
                try
                {
                    asm = Assembly.Load(assemblyData);

                    // Add the assembly/dll into dictionary
                    dic.Add(asm.FullName, asm);
                    Console.WriteLine(asm.FullName);
                    return;
                }
                catch
                {
                    // Purposely do nothing
                    // Unmanaged dll or assembly cannot be loaded directly from byte[]
                    // Let the process fall through for next part
                }
            }

            bool fileOk = false;
            string tempFile = "";

            //load unmanaged assemblies
            using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
            {
                string fileHash = BitConverter.ToString(sha1.ComputeHash(assemblyData)).Replace("-", string.Empty); ;

                tempFile = Path.GetTempPath() + fileName;

                if (File.Exists(tempFile))
                {
                    byte[] bb = File.ReadAllBytes(tempFile);
                    string fileHash2 = BitConverter.ToString(sha1.ComputeHash(bb)).Replace("-", string.Empty);

                    if (fileHash == fileHash2)
                    {
                        fileOk = true;
                    }
                    else
                    {
                        fileOk = false;
                    }
                }
                else
                {
                    fileOk = false;
                }
            }

            if (!fileOk)
            {
                System.IO.File.WriteAllBytes(tempFile, assemblyData);
            }

            asm = Assembly.LoadFile(tempFile);

            dic.Add(asm.FullName, asm);
            Console.WriteLine(asm.FullName);
}

static Assembly GetAssembly(string assemblyFullName)
{
    if (dic == null || dic.Count == 0)
         return null;

    if (dic.ContainsKey(assemblyFullName))
         return dic[assemblyFullName];

            return null;
}        

        

此控制台应用程序位于 .NET Framework 4.5.1 中,当我构建解决方案时,它会生成一个 .exe 文件。然后我将项目的输出类型更改为类库,以获取 Dll 而不是 exe 并再次构建它。在我得到这个合并的 Dll ConsoleAppTest.dll 后,我在另一个测试项目中添加了对它的引用,但我无法访问 ConsoleAppTest 内部的 dll。例如,如果它里面有 ClientLibrary.dll,我想访问这个 ClientLibrary.dll 的公共方法/接口

using ConsoleAppTest;

//code to access public methods/interfaces of a dll that is inside ConsoleAppTest.dll included in using statement above

标签: c#.netdll.net-assembly

解决方案


推荐阅读