Updating a com dll - com

We have an application which uses COM dll.Now, we are pushing updates of this dll.We copy the new dll ( overwriting the existing one) and register the dll. Is this a good practice.Or, should we first unregister the dll already on clients machine.

As long as your old COM dll implements the exact same interfaces, there's no reason to unregister/register

While updating the COM dll, we should not change the old interfaces i.e., IIDs (basic rule of the COM) so that it won't break the clients which are using the old interfaces.
So there is no need to un reg the old COM dll, just register the new DLL. Upon registering the new dll, as old interface uses same IID, it will not going to break the clients which are using the old interface.

Two things you have to consider if you want just to replace the Com Dll:
They old and new have the same GUID.
You haven't append any new interfaces to the updated com Dll.
otherwise you should unreg/reg your com dll

Well, supposing you're writting your COM server using VB6 (a common case a couple of years before) you'll need to set it binary compatible to make VB keep same GUIDs for the component.
As the objects for the classes in the DLLs most of the time are being created using the class factory built into the same dll, if GUIDs not match with the ones the Class Factory knows about it cannot create objects for the old GUIDs even if no changes were made to Interfaces.
That was a part of the DLL Hell, remember?

If you know all your client platforms are running Windows XP or later, you might consider using Registration Free COM, and thereby avoid the entire issue.
See my answer to "How to register COM libraries at runtime?" for details. The article "Registration-Free Activation of COM Components: A Walkthrough" on MSDN has a complete walkthrough of what to do.

Related

Register for COM Interop and ComVisible(true)

I have the common library which will be used by multiple projects. I have Signed it with Strong name in order to manage the multiple versions across the project. In this library, I have couple of classes with [ComVisble(true)] property. However, I don't want to register this library for COM interop. But I am getting compilation error which asks me to "Please register your assembly for COm Interop".
I am new to COM in .Net. I assume that only if I have [ComRegisterFunction] in my library, I need to register it for COM interop. Correct me if I am wrong.
If I register it with COM Interop, then Strong naming will not be helpful in maintaining the multiple versions across the project.
Any help in this would be greatly appreciated.
However, I don't want to register this library for COM interop.
You have to register it, that's the way the client program finds your DLL. The client code uses a number when it creates the object (the CLSID guid), the registry tells which DLL implements that number. Technically the client program can use a manifest and its own local copy of your DLL but that is not under your control.
I assume that only if I have [ComRegisterFunction] in my library,
It is very rarely required. Only necessary if additional registry keys need to be written beyond the standard ones that Regasm.exe writes. It does not in any way address a versioning problem.
then Strong naming will not be helpful
A strong name permits you to put the assembly in the GAC. That actually is helpful, it avoids a new version of a DLL file overwriting an old version and ensures that an old client program that was not recompiled can still find that old version of your DLL. It is not the only technique, you can also give new versions of the DLL a different file name so they can live together in a single directory without overwriting each other. Not a very solid way to do it, programmers tend to take shortcuts when they have to fight a build system. That's a very dangerous shortcut to take. The GAC is often needed anyway, the CLR will have trouble locating dependent assemblies.
Do keep in mind that the GAC only solves one of the DLL Hell problems associated with COM. Another very important rule in COM that interfaces and coclasses are immutable. If you make a change to one of them then you must give them a different number. This ensures that the client program cannot accidentally create an incompatible object. Very important, versioning problems are extraordinarily hard to diagnose when the client program uses early binding. Getting a different number is automatic in .NET if you don't explicitly use the [Guid] attribute on a [ComVisible] type.

Create VB6 application using a class in a DLL, then swap out that DLL after build?

so my question is relatively simple, can I create VB6 application that references a class in a dll, and then substitute that dll for another at runtime?
Now my intial guess is... no chance in VB6.
So my thoughts turned to a VB.net interop dll. Could I do it in here, and then call the interop dll from the VB?
Again, my guess would be no.... but I'd be happy if someone knew differently.
The only thing that I think would actually work would be DI in .Net, but I'm limited to .net 2, or 3.5 at a big push, so I dont know if that is possible.
So for the background....
I have a dll that a specific site uses, but we dont want to ship that out to everyone. Instead, we want to build a clone dll which just has the interfaces setup so that the VB6 build will complete.
When it gets to the site that needs it, they want to replace the dummy dll, and drop in their version instead.
Note: We do use RegFreeCOM when its gets installed, so I do have the manifest files that I could play around with if needed.
Any ideas would be much appreciated.
Nick
Its a COM dll so its not statically linked to the VB6 exe, so long as the clsids and interface ids are the same in the type library for both DLLs, you can swap them around as you see fit. (If its a VB6 dll this is trivial to do with the 'binary compatibility' build option)
You could also use late binding instead and instead of making a reference directly in your VB6 code, you would create an object and then set that object to an instance.
Examples and information:
MVPS
Microsoft

.NET out-of-process COM objects sharing static instances in API calls

It's hard to explain our situaction.
We have a 3-tier application. The engine is a DLL coded in C++, then we have a VB6 ActiveX EXE that access to the engine via API calls, and at the top level we have a Excel Addin (in C# using VSTO framework) calling the middle layer with an interop DLL. At this time, each "connection" from the Addin to the engine creates a new EXE (VB6 uses API calls to access to the engine) and all works fine.
Now we are moving the middle layer to .NET, it works 'presumably' fine (it pass all our Unit test) but, we found an error when we open 2 "connections" at same time (ups, no unit test check this situation because it's a new behavour). The DLL have static objects that it's shared over all instances in the same process and we have interactions between "connections". In our old version each "connection" creates a new EXE with no memory sharing between processes, now it's the same process and they share memory and the static objects.
Following the tips from this question. We tried to build a COM EXE in C# to do an out-of-process objects in the middle layer but we have the same result. They share the static objects, at the end, each connection not creates a independent process.
It's clear, but not affordable at this time, moving API calls to ATL or changing the static objects to instanciable references with a handle and change all the API calls to get/set this handlers. I reviewed all examples in MS All-in-one but I didn't find any solution. Neither it's possible to keep only one connection at time, each workbook can have one connection and in the future we want to explore a Web application with multiple connections at same time.
Any suggestion?
Thanks in advance,
Whether COM starts new EXE per each COM object, or uses single EXE to instantiate all the object is controlled by flags parameters passed to CoRegisterClassObject. See
http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx, and
http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx
You need to pass REGCLS_SINGLEUSE or REGCLS_MULTI_SEPARATE flags.
Now, the trick is to pass this flag, as you might not call this method directly - the details depend on how you implemented the COM EXE.
it's not clear from the question, but it sounds like the "middle layer" you have was built as a VB6 EXE, and you're trying to replace it with a .net DLL. If that's the case, you'll definitely get the behavior you describe.
With a VB6 EXE com project, instantiating a new object starts a new process. With a .net dll (or a Vb6 dll really) you +won't+ get a new process.
You'd either need to create a .net EXE that exposes COM objects just like your VB6 exe does, or (sounds like you've already investigated this) you'll need to refactor your EXE objects to properly handle multiple instances within a single process.
Honestly, it'd probably be better to do that latter, since relying on singletons like this is generally a bad code smell. But it a pinch, you should be able to replicate the behavior of the VB6 exe with a .net project. You just can't do it in a dll.
Was your middle layer created in .Net? If it was, you might be facing the issue that your COM class is been created as a native .net object instead of a COM object. The solution usually involve using Primary Interop Assemblies. Take a look on this SO question to see if it matches your problem.

How to check whether a PE file (DLL,EXE) is a COM component?

I need to write a stub module which, when given a PE (DLL/EXE) as input, will determine whether it is a normal Win32 DLL/EXE or COM DLL/EXE. I need to determine this programatically.
Are there any Windows APIs for this purpose?
I suspect that this is something that would be very hard to do with near 100% accuracy. Some thoughts though:
A COM DLL will export functions like DllRegisterServer and DllUnregisterServer. You could use LoadLibrary() to load the Dll, and then GetProcAddress() to check for the presence of these functions. If they're there then its highly likely that its a COM dll.
A plain win32 Dll will export DllMain. You could use the same technique to check for that. If you find it then its very likely that its win32.
I'm not aware of a way to discover if an exe is a COM server. Servers written using ATL often have a registration script embedded in their resource table, but they don't have to. And you don't need to use ATL to write a COM server. Services using "registry-less com" will similarly have an embedded manifest. You could scan the registry (below HKLM/Classes/Software/) to see if the exe is registered, but it may be that the exe is using registry-less com or just hasn't been regisered yet.
Hope that helps.
For traditional COM DLL, you can look for the wellknown exported methods (search on msdn for these methods)
DllGetClassObject
DllRegisterServer
DllUnregisterServer
DllCanUnloadNow
I am not sure about EXE COM servers though because they generally use command line parameters for registration/unregistration and for class object usually calls CoRegisterClassObject when the EXE starts.
Most of the COM servers traditionally also registered in the Registry but you can create registration free servers now.
Are you also looking for a .NET assembly with some COM visible classes?

Using VS 2008 (vb.net) I need to create an object I can use in Classic ASP with CreateObject

I am very new to VB.net. I have written these objects in VB6 before. I'm just lost in VB.net, but (kicking and screaming) I have to learn how to do this. I've been googling for hours with only minor steps forward. Can anyone post a link that explains start to finish how to do this?
I have managed to write the class object, What I can not tell is how to register it and where the name1 and name2 in the CreateObject("Name1.Name2") come from.
Regsrv32 will not work. It says "Entry Point not found" and will not register it. Also, I can not drop it into the Assemblies directory. I read something about a regasm command one uses, but I can't seem to make this work either.
Thanks in advance for any assistance.
I am going to assume you are not trying to write a COM DLL but rather a complete project that call various sub assemblies like a VB6 EXE call a ActiveX DLL. If you can be more specific about what you are trying to do it would help me better.
Several points about VB.NET versus VB6.
1) For .NET only projects there is no registration. If a EXE or DLL references another .NET DLL the only requirement is that the DLLs be present in the parent's directory.
2) You can do a COM style registration for .NET apps only by registering the .NET assembly in the GAC. However there are several requirements for doing this. Do a search on the .NET GAC and it will give you the scoop on how to do this.
3) You can setup the .NET assembly to use COM in which case it will operate by the rules of COM including registration with regsvr.
You will find for .NET only project that #2, or #3 only come in rare instances. #1 will apply for 90% of your DLL assemblies. Of This is dependent on your project.
A common use for CreateObject is allow for plug-ins or installable libraries. .NET handles this through the Reflection API. With the reflection API you can look in a directory, go through each .NET DLL and see what them and create objects from what you find. Search for .NET Reflection to read up on this.
If your project is .NET only then I recommend that you create a Assembly that is reference by both the master assembly and the individual sub assembly that define the interfaces of the objects you are creating. This when you use the reflection API and determine the Object type you can assign it to a variable of that interface and code it noramlly with intellisense and other aids.
if you have old COM ActiveX Controls or DLLs .NET will generate a wrapper class that exposes the ActiveX Objects to .NET. I would spend some time learning how .NET does this. What I do create a dummy project and have .NET reference the ActiveX stuff I need. I then find the wrapper projects and DLL it made and move them into a central area. That why when I work on subsquent projects using the same ActiveX stuff I know where all the wrappers are.
You have to go to your class library properties and select the option "Register for COM interop". This will make your assembly available to COM.
You want to create what's called a COM Callable Wrapper (aka CCW) for your .NET component. This basically entails setting up some COM interfaces with some GUIDs and either enabling "Register for COM Interop" in the project properties (as mentioned) or using regasm.exe.