C# 确定部件类型的好方法?

C# 确定部件类型的好方法?,c#,.net,vb.net,reflection,portable-executable,C#,.net,Vb.net,Reflection,Portable Executable,在C#或VB.NET中,我想知道哪种方法是确定通过反射加载的程序集的最佳方法。换句话说,确定程序集是WinExe、控制台应用程序还是动态链接库 我找到了解决方案(该问题中提出的其他解决方案无效),但如果我没有错的话,我认为这意味着假设加载的文件是一个.NET程序集,手动解析PE头似乎有点整洁 我也找到了解决办法,但在某些情况下,阅读评论似乎并不有效 出于这些原因,我想知道是否存在一种真正安全、可管理的方法,最好是通过反射来确定加载程序集的PE文件类型 我确信System.Reflection.E

在C#或VB.NET中,我想知道哪种方法是确定通过反射加载的程序集的最佳方法。换句话说,确定程序集是WinExe、控制台应用程序还是动态链接库

我找到了解决方案(该问题中提出的其他解决方案无效),但如果我没有错的话,我认为这意味着假设加载的文件是一个.NET程序集,手动解析PE头似乎有点整洁

我也找到了解决办法,但在某些情况下,阅读评论似乎并不有效

出于这些原因,我想知道是否存在一种真正安全、可管理的方法,最好是通过反射来确定加载程序集的PE文件类型

我确信
System.Reflection.Emit.pefiletypes
枚举的存在不仅仅是为了装饰目的,如果该枚举存在,那么它的逻辑就是认为在反射名称空间中可能有一个成员/函数我错过了,该名称空间内部使用该枚举返回PE文件类型的
程序集
对象,我设法通过反射查看了
程序集
类和其他相关类的私有成员,但没有发现任何相关内容。

根据,pefiletypes
枚举仅用于
程序集生成器
模块生成器
(以及它们的非公共助手类型)。此枚举和类位于-中,例如,它们用于编写程序集,而不是读取

但是,将在程序集中公开程序集的PE标头的相关值。您可以使用这些标题对等效的
pefiletypes
值进行反向工程。下面是C#中的一个例子:

我在使用
System.Reflection.Emit
生成的程序集上运行了这段代码,以确保其准确性。完整的程序正在运行


您可能还可以通过第三方库(如Lex Li所述)获得此信息。

鉴于
pefiletypes
位于
System.Reflection.Emit
命名空间中,它可能仅在常规.NET Framework反射API中写入而非读取时使用。在我自己研究的时候,我可以回答,但是与此同时,你可以考虑查看<代码>系统。NuGet上的反射。元数据< /代码>(虽然它没有很好的文档化)或者第三方<代码>单塞西尔./Cux>库。如果你不想自己分析PE格式,使用像HI这样的现有库。首先我想说的是,我永远都不会明白有什么理由让一个人否决这样一个答案。其次,我的想法是避免使用第三方库,但是,由于您提到的库是微软的官方库,因此我对这个解决方案非常满意。它也能如预期的那样工作。感谢您的帮助。另外,似乎使用此库我还可以确定程序集是否具有强名称签名,因此我可以避免使用实现本机IClrStrongName接口的非托管代码来执行相同的操作。我知道这不是我问题的一部分但我对此很感兴趣,也许你能在评论框中给我一个简单的“是/否”回答,让我知道用这个代码我是否可以确定签名的强名称,或者可能我对这个标志的含义有错误:
bool isStrongNameSigned=peReader.PEHeaders.CorHeader.Flags.hasblag(CorFlags.StrongNameSigned)
@ElektroStudios我认为该标志指示程序集是否声明为强名称,但并不一定意味着签名有效。
using (var stream = File.OpenRead(filenameAndExtension))
{
    using (var peFile = new PEReader(stream))
    {
        var headers = peFile.PEHeaders;
        Console.WriteLine($"Reading {filenameAndExtension} with System.Reflection.Metadata");
        Console.WriteLine($"  IsDll: {headers.IsDll}");
        Console.WriteLine($"  IsExe: {headers.IsExe}");
        Console.WriteLine($"  IsConsoleApplication: {headers.IsConsoleApplication}");

        PEFileKinds reverseEngineeredKind;

        // NOTE: the header values cause IsConsoleApplication to return
        //       true for DLLs, so we need to check IsDll first
        if (headers.IsDll)
        {
            reverseEngineeredKind = PEFileKinds.Dll;
        }
        else if (headers.IsConsoleApplication)
        {
            reverseEngineeredKind = PEFileKinds.ConsoleApplication;
        }
        else
        {
            reverseEngineeredKind = PEFileKinds.WindowApplication;
        }
        Console.WriteLine($"  Reverse-engineered kind: {reverseEngineeredKind}");
    }
}