In un'applicazione C#, vorrei determinare se un'altra applicazione .NET è un'applicazione Console o meno.Come è possibile determinare il sottosistema utilizzato da un determinato assembly .NET?
È possibile farlo utilizzando le API di riflessione?
MODIFICA: OK, non sembra che avrò una buona risposta a questa domanda perché non sembra che il framework esponga la funzionalità che voglio. Ho scavato intorno nel PE/COFF spec e arrivato fino a questo:
/// <summary>
/// Parses the PE header and determines whether the given assembly is a console application.
/// </summary>
/// <param name="assemblyPath">The path of the assembly to check.</param>
/// <returns>True if the given assembly is a console application; false otherwise.</returns>
/// <remarks>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
/// </remarks>
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*/
}
}
Sì, nel codice nativo di solito utilizzo gli apis dbghelp per questo, ma non sono nel codice nativo :( –
@Billy ONeal la struttura delle intestazioni è molto semplice e ben conosciuta. Richiede poche righe di codice in C++ (+ headers) per trovare il sottosistema, credo che in C# non dovrei prendere molto di più – Andrey