C#中判断DLL文件是否为CLR程序集的最佳方法CheckifaDLLfileisaWin32DLLoraCLR程序集执行此操作的最佳方法是什么?目前我使用这段代码尝试{this.currentWorkingDirectory=Path.GetDirectoryName(assemblyPath);//尝试加载assembly.assembly=Assembly.LoadFile(assemblyPath);返回程序集!=null;}catch(FileLoadExceptionex){exception=ex;}catch(BadImageFormatExceptionex){exception=ex;}catch(ArgumentExceptionex){exception=ex;}catch(Exceptionex){exception=ex;}if(异常是BadImageFormatException){returnfalse;但我喜欢加载前检查,因为我不想要那些异常(时间)。有没有更好的办法?检查PE头:DOS头从0x0开始,0x3c的DWORD包含指向PE签名的指针(通常为0x80),为4个字节,接下来的20个字节为COFF头,然后是PE头(在0x9处。PE头为224)字节并包含数据目录(96字节到PE标头=0xf。第15个条目(在0x16处是CLR标头描述符(有时称为COM描述符,但这与COM无关)。如果这是空的(即0x168的8个字节中的0到0x16f)则该文件不是.NET程序集。如果要检查它是否是COMDLL,则应查看它是否导出GetClassObject。请参阅。更新:有一种更“.NET”的方法可以做到这一点:使用Module.GetPEKind方法并检查PortableExecutableKinds枚举:NotAPortableExecutableImage该文件不是可移植可执行(PE)文件格式。ILOnly可执行文件仅包含Microsoft中间语言(MSIL),因此对于32位或64位平台是中性的。Required32Bit可执行文件可以在32位平台上运行,或在64位平台上的32位WindowsonWindows(WOW)环境中运行。PE32Plus可执行文件需要64位平台。Unmanaged32Bit可执行文件包含纯非托管代码。如果程序集已加载,例如Assembly.LoadFile(dotNetDllorExe)并且没有抛出异常,则它是一个有效的.NET程序集。如果不是那么它将抛出“BadImageFormatException”。通过加载并检查是否抛出异常来检查一个文件的weather程序集的思路;看起来不是很干净。异常后使用所有异常。.NET程序集是常规的Win32PE文件,操作系统不区分.NET程序集和Win32可执行二进制文件,它们是相同的普通PE文件。那么如果DLL或EXE是加载CLR的托管程序集,系统是如何工作的呢?它验证文件头以检查它是否是托管程序集。在ECMA规范第II部分-.NETSDK附带的元数据中,您将看到一个单独的PE格式的CLI标头。它是PE可选标头中的第15个数据目录。因此,简单来说,如果我们在此数据目录中有值,则意味着这是一个有效的.NET程序集,否则就不是。内部静态类PortableExecutableHelper{内部静态布尔IsDotNetAssembly(字符串peFile){uintpeHeader;uintpeHeaderSignature;短机;短节;单位时间戳;uintpSymbolTable;uint无符号;ushortoptionalHeaderSize;短特性;ushortdataDictionaryStart;uint[]dataDictionaryRVA=newuint[16];uint[]dataDictionarySize=newuint[16];Streamfs=newFileStream(peFile,FileMode.Open,FileAccess.Read);BinaryReaderreader=newBinaryReader(fs);//PE标头从@0x3C(60)开始。它是一个4字节的标头。fs.Position=0x3C;peHeader=reader.ReadUInt32();//移动到PEHeader起始位置...fs.Position=peHeader;peHeaderSignature=reader.ReadUInt32();//我们也可以显示所有这些值,但我们将//限制为CLI标头测试。机器=reader.ReadUInt16();sections=reader.ReadUInt16();时间戳=reader.ReadUInt32();pSymbolTable=reader.ReadUInt32();noOfSymbol=reader.ReadUInt32();optionalHeaderSize=reader.ReadUInt16();特征=reader.ReadUInt16();/*现在我们在PE标头的末尾,从这里开始,PE可选标头开始...要直接转到数据字典,我们将流的当前位置增加到96(0x60)。96因为,28个用于标准字段68个用于NT特定字段从这里DataDictionary开始......及其总共128个字节。DataDictionay总共有16个目录,做简单的数学运算128/16=8。所以每个目录有8个字节。在这8个字节中,4个字节是RVA,4个字节是Size。顺便说一句,第15个目录由CLR头文件组成!CLR文件:)*/dataDictionaryStart=Convert.ToUInt16(Convert.ToUInt16(fs.Position)+0x60);fs.Position=dataDictionaryStart;for(inti=0;iECMAReference,BlogReference过去面对同样的问题,我采用了你的反思方法,因为手动读取此类PE标头的替代方法对我的场景来说似乎有点过分了,但它可能对你有用。你没有不要指定您是否必须在代码中执行此操作,或者您只是个人需要知道您在系统上查看的文件是否是.NET程序集(也许您认为您需要编写自己的代码来这样做).如果是后者,您可以使用DependencyWalker查看它是否依赖于.Net运行时引擎MSCOREE.dll。您可以使用类似:AssemblyNameassemblyName=null;试试{assemblyName=AssemblyName.GetAssemblyName(文件名);}catch(System.IO.FileNotFoundExceptionex){thrownewException("找不到文件!",ex);}catch(System.BadImageFormatExceptionex){thrownewException("Fileisnotan.NetAssembly.",ex);另见:https://msdn.microsoft.com/en-us/library/ms173100.aspx你可以从文件中读取前两个字节,如果字节是“MZ”,则尝试读取程序集名称以确定(微软慢速方式)程序集的有效性。以上就是C#学习教程:C#中检查DLL文件是否为CLR程序集的最佳方法所有内容分享,如果对大家有用还需要详细了解C#学习教程,希望大家多多支持更多关注---publicstaticboolisValidAssembly(stringsFileName){try{using(FileStreamfs=File.OpenRead(sFileName)){if((fs.ReadByte()!='M')||(fs.ReadByte()!='Z')){fs.Close();返回假;}fs.Close();}//http://msdn.microsoft.com/en-us/library/ms173100.aspxobjectfoo=SR.AssemblyName.GetAssemblyName(sFileName);返回真;}赶上{返回假;}}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
