如果这个问题不是最容易理解的,请提前道歉,我对 C# 和 Windows 窗体仍然很陌生。
我正在制作一个程序,允许用户在一个有组织的地方运行多个控制台应用程序(在我的例子中是 Discord 机器人)。我现在正在处理“打开文件”对话框,我想知道是否有办法确定所选的 .exe 文件是否是控制台应用程序?如果此检查未到位,如果用户选择的 .exe 文件不是控制台应用程序,我的程序将会崩溃。
如果有人能指出我正确的方向,我将不胜感激!谢谢!
针对 .NET Core 或 .NET 5+,您可以使用
System.Reflection.PortableExecutable
命名空间,它是 System.Reflection.Metadata
程序集的一部分。
其 PEReader 类(在 .NET Framework 中不可用)允许读取 PE Headers,无需 PInvoke,例如 ImageLoad() 或 MapAndLoad() 等。
使用起来非常简单。
使用您打开的 Stream 初始化
PEReader
类,例如 File.Open()
或初始化 FileStream
,传递图像文件的 完整路径,然后读取您返回的 PEHeaders 对象的内容.
最小实现(.NET 5+、C# 8.0+):
using System.Reflection.PortableExecutable;
string imagePath = @"[Full path of executable file]"
bool isConsoleApp = GetExeType(imagePath, out bool isDll) == Subsystem.WindowsCui;
// [...]
public Subsystem GetExeType(string imagePath, out bool isDll) {
using var stream = File.Open(imagePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
using var reader = new PEReader(stream);
isDll = reader.PEHeaders.IsDll;
return reader?.PEHeaders?.PEHeader != null ? reader.PEHeaders.PEHeader.Subsystem : Subsystem.Unknown;
}
当然,您可以返回一个
PEHeader
类对象并检查所有其他可用属性。大多数情况下,您拥有从 LOADED_IMAGE 结构 中获得的内容