views:

351

answers:

2

I have a .NET DLL (that happens to be written in C++/CLI). Parts of it I want to expose via COM. I do this and register it using "regasm my.dll /codebase". So far so good. But then I change some things and the version number of the assembly changes plus I move the dll to a different folder. I register it again and look at my COM object in OLE/COM Viewer. I see something like this

InprocServer32 [Codebase] = file://c://foo/bar/my.dll
7.0.0.0 [Class] = My.Blah.Class
7.0.0.0 [Assembly] = Sync, Version=7.0.0.0, Culture=neutral, PublicKeyToken=1dd19234234
7.0.0.0 [RuntimeVersion] = v2.0.50727
7.0.0.0 [CodeBase] = file://c:/dooby/do/my.dll
7.0.0.27397 [Class] = My.Blah.Class
7.0.0.27397 [Assembly] = Sync, Version=7.0.0.27397, Culture=neutral, PublicKeyToken=1dd19234234
7.0.0.27397 [RuntimeVersion] = v2.0.50727
7.0.0.27397 [CodeBase] = file://c://foo/bar/my.dll

Questions about multiple versions:

  1. So I think that the last COM object that was registered wins. It doesn't matter if I have my old 7.0.0.0 COM object registered, the 7.0.0.27397 is the one that will be created when I instantiate my COM object because I registered it last. Is that correct?

  2. Oops I didn't keep around the 7.0.0.0 object. Is there any way to get rid of it? Is there any way to remove all versions of a COM object other than going into the registry and whacking it by hand?

  3. Just out of curiosity, if I specifically wanted to instantiate a particular version of my COM object is there any way to do that? (I'm using C++ if you wanted to give a code example).

  4. Is there any way I can just tell regasm to not store the version number because it just seems to be cluttering things up and I can't see what the benefit is. If my COM object went through significant API change I'd just change the GUID and progid, right? What if I don't want to register multiple versions (I don't).

A: 

Components with the same CLSID should be compatible, especially if you've only changed the build number between assemblies. Here's the only relevant thing I found to confirm this by googling quickly.

To answer your questions directly:

  1. Correct.
  2. regasm /unregister
  3. Look into Binding redirects.
  4. Probably not.
Mike Atlas
+1  A: 

I always set my COM visible assemblies up with a static AssemblyVersion for just this reason. If you want to have binaries tagged with a version, use AssemblyFileVersion instead.

  1. Last registered object wins: yep
  2. Not really. You can put stuff in your assembly's ComRegisterFunction/ComUnregisterFunction attributed methods to automate the cleanup, but if you leave old version droppings around, this is about the only way.
  3. You'd do it with a different coclass GUID and/or ProgID (eg, MyCoClass.1, .2, etc). CoCreateInstance doesn't know anything about the version values- they're used by the CLR's activator to ensure it loaded the right assembly.
  4. No- best thing to do is never change your assembly version (see above).
nitzmahone