如何确定给定.NET程序集使用的子系统?

在C#应用程序中,我想确定另一个.NET应用程序是否是控制台应用程序。

可以使用reflectionAPI完成吗?

编辑:好的,看起来我不会得到这个问题的好答案,因为它看起来不像框架暴露我想要的function。 我在PE / COFF规范中挖掘并想出了这个:

///  /// Parses the PE header and determines whether the given assembly is a console application. ///  /// The path of the assembly to check. /// True if the given assembly is a console application; false otherwise. /// The magic numbers in this method are extracted from the PE/COFF file /// format specification available from http://www.microsoft.com/whdc/system/platform/firmware/pecoff.mspx ///  bool AssemblyUsesConsoleSubsystem(string assemblyPath) { using (var s = new FileStream(assemblyPath, FileMode.Open, FileAccess.Read)) { var rawPeSignatureOffset = new byte[4]; s.Seek(0x3c, SeekOrigin.Begin); s.Read(rawPeSignatureOffset, 0, 4); int peSignatureOffset = rawPeSignatureOffset[0]; peSignatureOffset |= rawPeSignatureOffset[1] << 8; peSignatureOffset |= rawPeSignatureOffset[2] << 16; peSignatureOffset |= rawPeSignatureOffset[3] << 24; var coffHeader = new byte[24]; s.Seek(peSignatureOffset, SeekOrigin.Begin); s.Read(coffHeader, 0, 24); byte[] signature = {(byte)'P', (byte)'E', (byte)'\0', (byte)'\0'}; for (int index = 0; index < 4; index++) { Assert.That(coffHeader[index], Is.EqualTo(signature[index]), "Attempted to check a non PE file for the console subsystem!"); } var subsystemBytes = new byte[2]; s.Seek(68, SeekOrigin.Current); s.Read(subsystemBytes, 0, 2); int subSystem = subsystemBytes[0] | subsystemBytes[1] << 8; return subSystem == 3; /*IMAGE_SUBSYSTEM_WINDOWS_CUI*/ } } 

这超出了托管代码的范围。 从.net视图控制台和win应用程序是相同的,你必须查看PE文件头。 在此页面上搜索工作“子系统” http://msdn.microsoft.com/en-us/magazine/bb985997.aspx

我认为它应该与本机应用程序相同,因此您可以将本文从C ++改编为C#以读取PE头: 如何确定应用程序是控制台还是GUI

SHGetFileInfo函数可以这样做:

 [DllImport("shell32.dll", CharSet=CharSet.Auto, EntryPoint="SHGetFileInfo")] public static extern ExeType GetExeType(string pszPath, uint dwFileAttributes = 0, IntPtr psfi = default(IntPtr), uint cbFileInfo = 0, uint uFlags = 0x2000); [Flags] public enum ExeType { None = 0, WinNT = 0x04000000, PE = ((int)'P') | ((int)'E' << 8), NE = ((int)'N') | ((int)'E' << 8), MZ = ((int)'M') | ((int)'Z' << 8), } 

然后,根据规范,如果它只是MZ或PE,它在控制台中打开,否则(如果指定了版本),它在窗口中打开。

 ExeType type = GetExeType("program.exe"); if(type == ExeType.PE || type == ExeType.MZ) return "console"; else return "window"; 

我不认为有一种科学的方法来确定它,我想到的最接近的解决方法是使用reflection来检查应用程序是否引用并加载WinForms程序集,但我不完全确定。 可能试一试。