What is the best way to check if a DLL file is a Win32 DLL or if it is a CLR assembly. At the moment I use this code
try
{
this.currentWorkingDirectory = Path.GetDirectoryName(assemblyPath);
//Try to load the assembly.
assembly = Assembly.LoadFile(assemblyPath);
return assembly != null;
}
catch (FileLoadException ex)
{
exception = ex;
}
catch (BadImageFormatException ex)
{
exception = ex;
}
catch (ArgumentException ex)
{
exception = ex;
}
catch (Exception ex)
{
exception = ex;
}
if (exception is BadImageFormatException)
{
return false;
}
But I like to check before loading because I do not want those exceptions (time).
Is there a better way?
You could use something like:
Please also check out: https://msdn.microsoft.com/en-us/library/ms173100.aspx
If an assembly gets loaded eg
Assembly.LoadFile(dotNetDllorExe)
and doesn’t throw any exception, it’s a valid .NET assembly. If it’s not then it’ll throw a “BadImageFormatException”.The idea of checking weather a file is assembly or not by loading it and checking if exception is thrown or not; doesn’t seem to be too clean. After all exceptions are supposed to be used exceptionally.
.NET assemblies are regular Win32 PE files, the operating System doesn’t differentiate between .NET assemblies and Win32 executable binaries, they are the same normal PE files. So how does the System work out if a DLL or EXE is a managed assembly in order to load the CLR?
It validates the file header to check if it’s a managed assembly or not. In the ECMA Specifications Partition II – Metadata which is shipped along with .NET SDK you see there is a separate CLI Header in the PE Format. It is the 15th data directory in the PE Optional Headers. So, in simple terms, if we have value in this data directory, then it means this is a valid .NET assembly, otherwise it's not.
ECMA Ref, Blog Ref
Check the PE header:
Ref.
UPDATE: there is a more '.NET' way of accomplishing this:
Use
Module.GetPEKind
method and check thePortableExecutableKinds
Enumeration:Faced with the same problem in the past, I resorted to using your reflection approach because the alternative is to manually read the PE header like this. Just seemed like overkill for my scenario, but it may be useful to you.
You didn't specify whether you have to do this in code, or if you just personally need to know if a file you're looking at on your system is a .NET assembly (which maybe you think requires you writing your own code to do so). If the latter, you can use Dependency Walker to see if it has a dependency on MSCOREE.dll, which is the .Net runtime engine.