如果这个问题不是最容易理解的,请提前道歉,我仍然是C#和Windows窗体的新手.
我正在编写一个程序,允许用户在一个有组织的地方运行多个控制台应用程序(在我的情况下,是discord机器人).我现在正在"打开文件"对话框中工作,我想知道是否有方法可以确定所选的.exe文件是否是控制台应用程序?如果没有进行此判断,如果用户 Select 了不是控制台应用程序的.exe文件,我的程序将崩溃.
如果有人能为我指明正确的方向,我将不胜感激!谢谢!
如果这个问题不是最容易理解的,请提前道歉,我仍然是C#和Windows窗体的新手.
我正在编写一个程序,允许用户在一个有组织的地方运行多个控制台应用程序(在我的情况下,是discord机器人).我现在正在"打开文件"对话框中工作,我想知道是否有方法可以确定所选的.exe文件是否是控制台应用程序?如果没有进行此判断,如果用户 Select 了不是控制台应用程序的.exe文件,我的程序将崩溃.
如果有人能为我指明正确的方向,我将不胜感激!谢谢!
针对.NET Core或.NET 5+,您可以利用System.Reflection.PortableExecutable
命名空间,这是System.Reflection.Metadata
程序集的一部分.
它的PEReader类(在.NET框架中不可用)允许读取PE Headers而不需要PInvoke,例如ImageLoad()或MapAndLoad()等.
It's quite simple to use.
Initialize a PEReader
class using a Stream you have opened using, e.g., File.Open()
or initializing a FileStream
, passing the full path of an image file, then read the content of the PEHeaders object you get back.
最小实现(.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 struct 中获得的东西