How to tell if some file is managed assembly or not?

Another commonly asked question.

There are many ways to detect if a given file is a managed assembly or not. For example, in VS.Net 2002/2003, dumpbin has an option /clrheader. It will dump the CLR header for you if the file is a managed assembly. You can also run ildasm on the file. If it is not an assembly, it will complain.Other people suggest to inspect the PE header of the file.

What we are talking about here is API level detection.

First unmanaged API.

In .Net framework 1.1 mscoree.dll has an API GetFileVersion. Its definition is

STDAPI GetFileVersion(LPCWSTR szFilename, LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength);

Suzanne described what this API does here(https://blogs.gotdotnet.com/suzcook/commentview.aspx/48306e9f-df29-4ae1-8fe8-7bbdbffde140). Basically it tells which runtime this assembly is built against. If the given file is not a managed assembly, this API returns 0x8007000B (ERROR_BAD_IMAGE).

Now managed API.

Assembly.LoadFrom will throw BadImageFormatException if the given file is not a managed assembly.

This exception could be thrown for other reason as well. Suzanne kindly points out a more robust way. Once you catch the BadImageFormatException, look at its HResult field. If HResult is COR_E_ASSEMBLYEXPECTED, it means this is not a managed assembly.