2

How can I verify if dll was wrote in .net? I'm using code as below:

Assembly assembly = null;
try
{    
   foreach (string fileName in Directory.GetFiles(Environment.CurrentDirectory.ToString(), "*.dll", SearchOption.TopDirectoryOnly))
   {
     try
     {
        assembly = Assembly.LoadFrom(fileName);
        Console.WriteLine(fileName);
     }
     catch (Exception ex)
     {
       ...               
     }
     finally
     {
       ...
     }
    }              
}
catch (ReflectionTypeLoadException ex)
{
  ..              
}

When I want to load assembly = Assembly.LoadFrom(fileName) non-.net dll, an exception will appear:

Could not load file or assembly 'file:///...' or one of its dependencies. The module was expected to contain an assembly manifest.

I want to use verify in if-else clause. Can you help me?

cuongle
  • 74,024
  • 28
  • 151
  • 206
Robert
  • 25,425
  • 8
  • 67
  • 81

3 Answers3

5

There's a helper function in the .NET bootstrapper DLL that you can use. Mscoree.dll exports GetFileVersion(), a helper that returns the CLR version that an assembly needs. That function is going to fail when the file isn't an assembly and does so without raising an exception.

It should look like this:

using System;
using System.Text;
using System.Runtime.InteropServices;

public class Utils {
    public static bool IsNetAssembly(string path) {
        var sb = new StringBuilder(256);
        int written;
        var hr = GetFileVersion(path, sb, sb.Capacity, out written);
        return hr == 0;
    }

    [DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
    private static extern int GetFileVersion(string path, StringBuilder buffer, int buflen, out int written);
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • This function has been deprecated in the .NET Framework 4. http://msdn.microsoft.com/en-us/library/ms232525%28v=vs.110%29.aspx what should be an actual API solution? – ElektroStudios Mar 07 '14 at 14:55
2

You can do the following trick :

try {
   Assembly assem = Assembly.LoadFile(filePath);
}
catch (BadImageFormatException e) {
      //NOT .NET ASSEMBLY
}

In practice if on assembly load you recieve BadImageFormatException , that means that assembly is not formatted in CLR assembly way.

Hine form MSDN link:

The exception that is thrown when the file image of a dynamic link library (DLL) or an executable program is invalid.

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • Yes, I can catch an exception as above. It's not problem for me and it works. I want to use verify in if-else clause. – Robert Sep 12 '12 at 17:37
  • @Tigran Why do you call it a "trick"? This is a perfectly valid, legal and intended way to deal with exactly this error. – Paul Michalik Sep 12 '12 at 17:41
  • @Palado: There is no built-in `verify` function, nor that I'm aware of. This is a way to go. Just include this call inside a function and on exception return `false`, otherwise return `true`. – Tigran Sep 12 '12 at 17:44
  • @PaulMichalik: I call trick, cause understand OP's concern, that there is no some function in `CLR` that checks against format. To him it looks wired use `try/catch` to check that, but this is a way to go actually. – Tigran Sep 12 '12 at 17:45
  • Yes, it is by no means weird (or did you really mean "wired")? :-) – Paul Michalik Sep 12 '12 at 17:48
  • I have read MSDN, so your proposition is interesting. I will leave the question open searching for other solution but I will accept if no one will have some other propositions. – Robert Sep 12 '12 at 18:01
  • BadImageFormatException have a problem, if your application is 32 bits and try to load a 64 bits dll, then this exception will be thrown also, the same applies in the opposite case. – Rafael Sep 12 '12 at 18:22
2

If you do not need to load the assembly in the current domain, I suggest to use:

using System.Reflection;

  public class AssemblyName_GetAssemblyName
{
   public static void Main()
   {
      // Replace the string "MyAssembly.exe" with the name of an assembly,
      // including a path if necessary. If you do not have another assembly
      // to use, you can use whatever name you give to this assembly.
      //
     try     
     {   
            AssemblyName myAssemblyName = AssemblyName.GetAssemblyName("MyAssembly.exe");
     }       
     catch (BadImageFormatException ex)       
     {       
       ...                      
     } 
   }
}

The best way to know it, without to throw an exception, is to parse the OptionalImageFileHeader of the PE and look at the DataDirectory for CLR Header.

Currently I working on it, because I had the same issue..

CodeTherapist
  • 2,776
  • 14
  • 24