【问题标题】:How can I check if dll is .net library "The module was expected to contain an assembly manifest."如何检查 dll 是否为 .net 库“该模块应包含程序集清单。”
【发布时间】:2012-09-13 02:05:49
【问题描述】:

如何验证 dll 是否是在 .net 中编写的?我正在使用如下代码:

Assembly assembly = null;
try
{    
   foreach (string fileName in Directory.GetFiles(Environment.CurrentDirectory.ToString(), "*.dll", SearchOption.TopDirectoryOnly))
   {
     try
     {
        assembly = Assembly.LoadFrom(fileName);
        Console.WriteLine(fileName);
     }
     catch (Exception ex)
     {
       ...               
     }
     finally
     {
       ...
     }
    }              
}
catch (ReflectionTypeLoadException ex)
{
  ..              
}

当我要加载assembly = Assembly.LoadFrom(fileName)非.net dll时,会出现异常:

无法加载文件或程序集“file:///...”或其依赖项之一。 该模块应包含程序集清单。

我想在 if-else 子句中使用 verify。 你能帮助我吗?

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    .NET 引导程序 DLL 中有一个帮助函数可供您使用。 Mscoree.dll 导出 GetFileVersion(),这是一个帮助程序,它返回程序集所需的 CLR 版本。当文件不是程序集并且不会引发异常时,该函数将失败。

    应该是这样的:

    using System;
    using System.Text;
    using System.Runtime.InteropServices;
    
    public class Utils {
        public static bool IsNetAssembly(string path) {
            var sb = new StringBuilder(256);
            int written;
            var hr = GetFileVersion(path, sb, sb.Capacity, out written);
            return hr == 0;
        }
    
        [DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
        private static extern int GetFileVersion(string path, StringBuilder buffer, int buflen, out int written);
    }
    

    【讨论】:

    【解决方案2】:

    你可以做以下技巧:

    try {
       Assembly assem = Assembly.LoadFile(filePath);
    }
    catch (BadImageFormatException e) {
          //NOT .NET ASSEMBLY
    }
    

    实际上,如果在程序集加载时收到 BadImageFormatException ,这意味着程序集未以 CLR 程序集方式格式化。

    Hine 表单 MSDN 链接:

    动态链接的文件图片时抛出的异常 库 (DLL) 或可执行程序无效。

    【讨论】:

    • 是的,我可以捕捉到上面的异常。这对我来说不是问题,而且有效。我想在 if-else 子句中使用 verify。
    • @Tigran 为什么称其为“技巧”?这是处理此错误的一种完全有效、合法且有意的方法。
    • @Palado:没有内置的verify 函数,我也不知道。这是一条路。只需将此调用包含在函数中,异常返回false,否则返回true
    • @PaulMichalik:我称之为诡计,因为理解 OP 的担忧,CLR 中没有一些功能可以检查格式。在他看来,使用try/catch 进行检查似乎是有线的,但实际上这是一种方法。
    • 是的,这并不奇怪(或者您真的是指“有线”)? :-)
    【解决方案3】:

    如果不需要在当前域加载程序集,我建议使用:

    using System.Reflection;
    
      public class AssemblyName_GetAssemblyName
    {
       public static void Main()
       {
          // Replace the string "MyAssembly.exe" with the name of an assembly,
          // including a path if necessary. If you do not have another assembly
          // to use, you can use whatever name you give to this assembly.
          //
         try     
         {   
                AssemblyName myAssemblyName = AssemblyName.GetAssemblyName("MyAssembly.exe");
         }       
         catch (BadImageFormatException ex)       
         {       
           ...                      
         } 
       }
    }
    

    在不抛出异常的情况下,最好的方法是解析 PE 的 OptionalImageFileHeader 并查看 CLR Header 的 DataDirectory。

    目前我正在研究它,因为我遇到了同样的问题..

    【讨论】:

      猜你喜欢
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多