8

I have an updater program, the pulled files from server has mixed vb6 dll and .net DLLs in one directory.

How to determine if a dll is a COM one? (so i can invoke regsvr32 to it from the updater program)

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
Hao
  • 8,047
  • 18
  • 63
  • 92
  • Why not do the right thing and register the ones you know are COM servers and skip those that are not? You should have that information and you can code it in your installer. – Tim Jun 10 '10 at 03:47
  • 1
    @Tim - I guess there could be a situation where the publishers of the code are not the same organization as the consumers - otherwise I agree - control the process explicitly. – AJ. Jun 10 '10 at 14:17
  • @AJ - that still doe not mean one can't figure it out and test it. My point is that if it is part of your install process you should KNOW what has to be registered. Not doing so is sloppy and unprofessional. It is a simple test to do so beforehand. Why would you want to add code when all you need to do is determine beforehand? – Tim Jun 10 '10 at 16:08
  • @Tim - as I said, I agree with you. I was just postulating a scenario where it might be relevant. From experience, sometimes even in the same company people don't communicate (and are discouraged from doing so) - this may be a "get it done" scenario. – AJ. Jun 13 '10 at 01:12
  • @Tim: Two word(make that three): plugins-based system – Hao Jul 15 '10 at 07:07
  • @Hao - I have no idea what that means. If you are making a plugin system you should have a dedicated directory for it or other way of identifying them. Where are these DLLs coming from? – Tim Jul 15 '10 at 14:14
  • Possible duplicate of [How can I detect the type of a dll? (COM, .NET, WIN32)](https://stackoverflow.com/questions/1420726/how-can-i-detect-the-type-of-a-dll-com-net-win32) – StayOnTarget Mar 18 '19 at 14:50

4 Answers4

6

I guess one way to do it would be to try load the file with System.Reflection.Assembly.LoadFile() (more info). If you get a BadImageFormatException, it's not a valid .NET assembly. There's probably a neater way of doing this, but this should work.

Daniel Lo Nigro
  • 3,346
  • 27
  • 29
  • This seems like a lot of work to write an installer that does this rather than carefully tracking which DLLs need to be registered. But +1 anyway – Tim Jun 10 '10 at 03:46
5

To do this formally you could inspect the PE to find out more about what type of stuff each dll is exporting. There is a pretty interesting article on MSDN which talks about the structure. If you understand the setup, you can identify links to .Net (and thereby the lack indicating a pure COM dll).

AJ.
  • 3,062
  • 2
  • 24
  • 32
  • I ran out of votes today. I will come back and vote this one up. It is a good technical answer. – Tim Jun 10 '10 at 03:45
  • @ [Tim](http://stackoverflow.com/users/26177/tim) - thanks :) This is not for the faint of heart, but with a bit of effort it could provide a pretty solid solution. If the scenario is anything higher level than assembly this approach should be reliable (read: not too many "optimized" PE's to deal with). – AJ. Jun 10 '10 at 03:49
3

Why not just call regsvr on all of them. If they register then ok, if not no big deal.

It is probably best though to write an installer that has the knowledge of which ones are which and does the right thing for each.

EDIT

If you are worried about "emitting errors", don't fret.

See this usage

You can suppress messages. (/s)

Tim
  • 20,184
  • 24
  • 117
  • 214
  • [@Hao](http://stackoverflow.com/users/55327/hao) - despite my alternative answer, I agree with Tim. – AJ. Jun 10 '10 at 03:23
  • @AJ: the problem with blindly regsvring them, if the DLL is of .NET type, the regsvr32 emits an error – Hao Jun 10 '10 at 03:34
  • i already use /S. it suppress error messages on XP, but on Vista it shows the error – Hao Jun 10 '10 at 04:31
  • 1
    @Hao - check to make sure you are running the command as an administrator. If the UAC permissions are not correct the /s flag will not work because the OS will never let you get that far. – AJ. Jun 10 '10 at 14:16
0

You can turn it around and figure out all .NET assemblies very quickly by doing the following:

private bool IsDotNetAssembly(string path)
{
  var sb = new StringBuilder(256);
  var hr = NativeMethods.GetFileVersion(path, sb, sb.Capacity, out var _);
  return hr == 0;
}

private static class NativeMethods
{
  [DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
  public static extern int GetFileVersion(string path, StringBuilder buffer, int buflen, out int written);
}

With that solution you dont have to load the assembly itself, which has some advantages (speed, no exceptions).

You can simply just skip the .NET assemblies for COM registration.