.NET Framework Bookmark and Share   
 index > Common Language Runtime > Get clsid or ProgId for C# COM DLL Server
 

Get clsid or ProgId for C# COM DLL Server

Hi,

I have a COM server dll developed in C#. We create two copies of the dll and register them in Registry with two different ProgIds and CLSIDs.

For example, I will build my C# DLL project twice to generate ComServer1.dll and ComServer2.dll. Then I will add registry entries (manually) for the same (using CodeBase as the dlls are not placed in GAC).

From the COM client (managed or unmanaged), I can access the COM Servers using the progIds (COMServer1ProgId or COMServer2ProgId). In the C# dll (COM Server), I find the CodeBase of the assembly (this.GetType().Assembly.CodeBase) to know which of the ProgIds (if codebase is ComServer1, then progId is ComServer1ProgId as so on) has been used by the client to connect to the server (based on that I will do different things on the server).

Now the above mechanism works fine and everything.

I was thinking if there is a way in which I do not have to create/build multiple copies of C# dll. Say I have only one copy ComServer.dll. Then I create two registry entries (with different progIds and Clsids, but same codebase), then when COM Client invokes the Server, I need to know which ProgId or ClsId is used by the client. Basically I want to know this in the constructor of the C# COM server dll.

Kindly provide your inputs.

Regards.

Jayanta Dey
Asked and answered, you cannot get the progid nor the clsid. Why you would prefer maintaining a custom .reg file over 5 lines of code that declares the derived class is a mystery to me.

Hans Passant.
  • Marked As Answer byJayanta Dey Tuesday, September 22, 2009 1:16 PM
  •  
nobugz
The ProgID and CLSID are provided by an attributes in your class declaration. Just lookup the attribute with Type.GetCustomAttributes(). It is otherwise best to leave it up to the client to tell you explicitly what kind of operation mode is desired. Just add a property.

Hans Passant.
nobugz
Hello Hans,

I understand both your points, but unfortunately my scenario is bit different.

In my class declaration, I would have defined a progId (say MyComServerProgId), but I would have registered it with different progIds (say ComServer1ProgId and ComServer2ProgId) in the registry (both pointing to same assembly in codebase). So I want a know which progId client has used for CoCreateInstance. Is there a way to get the same in my server constructor?

Also I cannot add a new property as I have to conform to certain standard and I cannot add property/method on my own.

Regards.
Jayanta Dey
That violates COM rulez. When COM is asked to create a class instance with a ProgID, it uses CLSIDFromProgID to discover the required CLSID. Which lets it find your server. You cannot afterwards find out what ProgID was used, that info is lost inside ole32.dll. P/Invoking ProgIDFromCLSID() to map backwards will find a random ProgID if you have more than one ProgID mapping to the same CLSID.

There must be a unambiguous mapping from ProgID and CLSID. In other words, your second server must use a different CLSID. That's trivially done by just deriving another class from your original and giving it a different [Guid] and [ProgId]. Its constructor can internally note that another operation method is required.
Hans Passant.
nobugz
Hi, actually my second server does use a different clsid and progid, but i want to use same codebase.

Ok, let me re-frame my question. Say I have a managed COM server (DLL), in the C# code I define only progId (say MyProgId) for my server class. Then I register the COM Server info in the registry (by creating a .reg file). In the reg file I provide a different progid (say ProgId1) and a new clsid with codebase pointing to the location of the dll on physical drive.

Now, when i do CoCreateInstance from client, in the Server contructor, I want to get the progId (ProgId1 and not MyProgId) with which it is registered. I would help even if i get the clsid.

So kindly let me know if there any way of getting the same. (may be using some p/invoke or thru some Marshal class methods etc.)

Regards.
Jayanta Dey
Asked and answered, you cannot get the progid nor the clsid. Why you would prefer maintaining a custom .reg file over 5 lines of code that declares the derived class is a mystery to me.

Hans Passant.
  • Marked As Answer byJayanta Dey Tuesday, September 22, 2009 1:16 PM
  •  
nobugz
Ok, I was making sure that there exists no way of doing that.

I will try your idea of sub-classing the COM server class.

Thanks for your help.
Jayanta Dey

You can use google to search for other answers

Custom Search

More Threads

• .net question
• Configuration system failed to initialize, when try to consume a webservice on GINA
• Garbage Collector and Memory Release
• Re: Accessing SetStyle from Outside the Control
• Marshal.Copy
• The good, the bad and the ugly or C#, COM and C++/CLI
• WebClient.UploadData: interpret the response
• System.InvalidCastException: Unable to cast COM object of type 'System.__ComObject'
• Call to SetAppDomainManagerType fails w/unknown HRESULT
• FTP OutOfMemory