|
Hello Vertig0,
My post here is written with due respect to my fellow developers including "Anonymous". However, I do seriously beg to differ with "Anonymous"'s answers to you which, in my sincere and humble opinion, are incorrect.
I'll go through his answers first to set the record straight and then I'll go through the original questions that you posted. Finally, I'll provide some of my own extra inputs. I have also written a set of sample codes to illustrate my points and would be glad to email it to you. My email address will be provided below.
OK, let's go through "Anonymous"'s answers :
Anonymous wrote : "If your two separate people are both implementing COM servers, which have the same interface as defined in the IDL, then you need to register one or the other DLL and which ever DLL is the last one registered will be used."
My comments : This is not correct. Two or more (multiple, in fact) COM objects housed in separate (or even the same) DLL(s) may implement the same interface AND they can ALL be registered on the same machine, live side by side and be used separately or simultaneously by a client application.
Just imagine this, vertig0 : ALL COM objects must implement IUnknown. If what Anonymous said was true, then only one object can be registered and used at one time. What kind of a COM world would we be living in ?
Anonymous wrote : "If however the two implementations do different things, despite having the same interface, then you need to use two IDL files with different GUIDs. In the client program, when you call CoCreateInstance(), specify the appropriate CLSID."
My comments : what else is the purpose of providing two or more implementations of one published interface but to treat them as providing two or more versions of the same expected functionality ? Still, vertig0, the central idea is to maintain ONE interface (with a constant IID) coded in ONE IDL file.
Anonymous wrote : "In the client program, when you call CoCreateInstance(), specify the appropriate CLSID.".
My comments : this is exactly how a client would get hold of a specific interface implemented by one particular COM object. However, the IID of the interface -must- remain the same. It is the CLSID that is different.
OK, vertig0, now onto your questions :
vertig0 wrote : " However, I've been having trouble finding help for what I'm trying to do next - making my IDL file support multiple server implementations."
My comments : my sample codes will show you how to achieve this.
vertig0 wrote : "Looking at the client's perspective, what is the best way to support multiple server implementations of the same IDL on a given system? In other words, I'm considering a situation where my client needs to distinguish between more than one registered "server.dll," while sticking with just one IDL file..."
My comments : The CLSID of the specific COM server (which implements the interface) is what you would use to distingusish between more than one registered "server.dll".
The central point is to enable your client code to create instances (via CoCreateInstance(), etc) of the various COM objects that implement your interface. You differentiate between the versions of the interface implementation by the CLSID. My sample codes will illustrate this.
Finally :
vertig0 wrote : "Perhaps I'm thinking about this the wrong way... In any case, suggestions would be much appreciated!"
My comments : you are thinking about this the right way, vertig0. It is most intuitive and is very much in line with Object-Oriented development principles.
Send an email to me, vertig0, and I'll email you the sample codes. Here is my email address :
bio_lim_2004@yahoo.com
Again, my assurance of full respect to Anonymous.
Best Regards,
Bio.
|
|
|
|
|
Hi There,
I have similar kind of question, that with one IDL file.
I need to create different implementation, but I am wondering is there a way to implement a server using C# for same IDL.
Thanks,
Akth
|
|
|
|
|
Hello Akth,
I do believe this is possible. COM and the .NET platform do interoperate well and I believe this extends to COM interfaces being implementable in C#. Let me do some research and experimentation and get back to you on this.
Best Regards,
Bio.
|
|
|
|
|
Hello Akth,
Thanks very much for the research and knowledge sharing. For the benefit of other readers, I'm summarizing our findings :
1. A COM interface defined in an IDL can be implemented by a .NET component. In order to implement the COM interface in a .NET language, C# say, the COM definitions contained in the IDL must be converted to compatible C# definitions.
This is achieved by creating a Primary Interop Assembly for the TYPE LIBRARY of the COM IDL and then referencing this PIA inside the C# project. The following are specific steps required for this :
1.1 First creating a strong name key (.snk) file. The PIA will need to be installed into the Global Assembly Cache (GAC). Hence, it needs to be signed. A .snk file is needed for the signing process. Use the sn.exe .NET utility to generate a .snk file. For example :
sn -k ObjectInterfaces.snk
1.2 Once a strong name key file is generated, we can proceed to create the PIA. This is achieved by using the tlbimp.exe .NET utility. Use the /keyfile option (to specify the .snk file we just created) and the /primary option to specify that we want to create a PIA. For example :
tlbimp ObjectInterfaces.tlb /sysarray /out:Interop.ObjectInterfaces.dll /keyfile:ObjectInterfaces.snk /primary
The above command line will generate a PIA with filename Interop.ObjectInterfaces.dll.
1.3 Now that the PIA is created, we will need to install the PIA into the Global Assembly Cache (GAC). This is accomplished by using the gacutil.exe .NET utility. For example :
gacutil -i Interop.ObjectInterfaces.dll
2. With a GAC-installed PIA in hand, we can now reference it inside our C# project. Use the Project|Add Reference menu to do this.
2.1 Once this is done, the various COM interface and other IDL definitions will be translated into C# types. You can see this inside the Object Browser.
2.2 You will now need to define a C# class that implements the intended COM interface. Let's say your C# class is Class1 and it is defined inside the CSharpImpl01 namespace. The resultant COM-interface C# implementation will have the progid "CSharpImpl01.Class1".
3. Once you have created your C# .NET component, CSharpImpl01.dll say, it cannot be used directly as a COM component in a COM client application. It is, after all, a .NET assembly consisting of BYTE CODES.
3.1 It can, however, be created and used by a COM client with the help of the Microsoft .NET Runtime Execution Engine (mscoree.dll). The resultant object will look and feel just like any ordinary COM object (to a client).
3.2 However, in actual fact, it remains a .NET component and what gets passed to the COM client is actually a proxy.
3.3 In order that mscoree.dll be able to load CSharpImpl01.dll and more specifically, the "COM object" with the progid "CSharpImpl01.Class1" on request, the usual COM information for it must first be registered.
3.4 This is done by using the regasm.exe .NET utility. For example :
regasm CSharpImpl01.dll /tlb
The /tlb option will make regasm generate a COM Type Library file for CSharpImpl01.dll. This type library file (i.e. CSharpImpl01.tlb) can be used by a COM client for import purposes.
3.5 Take note that regasm will generate a COM CLSID for "CSharpImpl01.Class1" and store the usual COM registration information plus some .NET specific information. If you look up the "InprocServer32" registry entry for the CLSID, you will note that the server is NOT CSharpImpl01.dll. It is mscoree.dll instead.
3.6 That's right, it is the .NET Runtime Execution Engine that serves as the COM server. It acts as the middle-layer between your COM client and the .NET assembly CSharpImpl01.dll.
3.7 Finally we will also need to install the CSharpImpl01.dll assembly into the Global Assembly Cache. This is done so that mscoree.dll can locate your assembly. This is done by using the gacutil.exe utility, for example :
gacutil -i CSharpImpl01.dll
3.8 Note also that because the C# project had made a reference to the PIA interop.objectinterfaces.dll, CSharpImpl01.dll will be dependent on it. This is also why we had earlier installed the PIA.
4. Your COM client can now either import the CSharpImpl01.tlb type library (in order to reference the C#-to-COM object CLSID) or it can use the "CSharpImpl01.Class1" progid to instantiate the new "COM object".
I certainly hope the above explanations will be helpful to all.
Best Regards,
Bio.
|
|
|
|
|
Anyone have any clues to try and solve this. I have a C++ application written as a COM object that works great in VB6, yet when it is referenced in a .NET project, this disturbing message appears.
converting the type library to a .net assembly failed
Thx
|
|
|
|
|
how to write a shell extension ( for example context menu) in masm (without using the CoLib)
|
|
|
|
|
|
I am Create Instance in DCOM Client.Show me my code:
// Create the server locally
/*HRESULT hResult = m_pChatSvr->CreateInstance(CLSID_ChatSvr);*/
HRESULT hResult = CoCreateInstanceEx(CLSID_ChatSvr, NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, &serverInfo, 1, &qi);
if (FAILED(hResult))
{
//handle Error
}
When Program is Running in DCOM CLient,visual C++ show me hResult
='-2147024891' and "E_ACCESSDENIED"
Please tell me What about it!
|
|
|
|
|
Hi,
I need to build up a class in a COM DLL. An eg. what I want to do is
|-----Penguin
|-----Non Flying Bird-|
| |-----(Can't think of another Eg.)
BIRD -|
| |-----Eagle
|----Flying Bird-|
|-----Crow
I am still new to COM. I am using the VC++ ATL COM Appwizard. I managed to do a coclass for Bird and I managed to create and use this object in VB.
But how do I build the other classes on this? Can I achieve this by changing the
"interface IFlyingBird : IDispatch" line
to
"interface IFlyingBird : IBird"?
Or what is the proper method of doing what I want to achieve above?
And hoe do I declare virtual functions?
Any help will be very much appreciated. Thanks in advance....
|
|
|
|
|
Hi All,
We have a imaging system application with a combination of COM components, extension dll and stand alone executables. Do we have a way of profiling the thread interaction at run time. Are there any tools available for this. My need is to do a profiling of thread interaction within and across processes.
Regards
Rajdeep
|
|
|
|
|
Hello:
I need to mux two mono audio pcm inputs into one stereo output. Does anyone have a simple DirectShow sample code that I can follow? Many Thanks.
Best Wishes,
Taiwu
|
|
|
|
|
i'm working on a project and i've got dis scenario, I need to read input from a Port -(COM(i)- where i can be any of the ports) and write it to a user(interface -may be a textbox). i'm using vb.net and not cracking it yet.any ideas on how can i crack dis
kwn
|
|
|
|
|
I've been given a VB example of how to use a hidden interface on a COM object. I need to implement this code in C++. The VB code uses the InMemoryRecordset object.
Dim objIMRS As New InMemoryRecordset
When I create a C++ wrapper class the InMemoryRecordset interface is ignored, but an IInMemoryRecordset interface class is created. InMemoryRecordset/IInMemoryRecordset don't exist in registry. The OLE Viewer sees the following in the TLB.
[
uuid(3DCB2383-3BF0-11D1-9211-006097383187),
hidden,
dual,
nonextensible
]
dispinterface IInMemoryRecordset {
properties:
methods:
[id(0x60020000), propget, hidden, helpstring("Returns the output Recordset.")]
GRecordset* OutputRecordset();
[id(0x60020001), hidden, helpstring("Append new read only field")]
GField* AddReadOnlyField(
[in, optional] VARIANT Collating,
[in, optional] VARIANT SourceDatabase,
[in, optional] VARIANT SourceTable,
[in, optional] VARIANT SourceField);
[id(0x60020002), hidden, helpstring("Append new read write field")]
GField* AddReadWriteField(
[in, optional] VARIANT Collating,
[in, optional] VARIANT SourceDatabase,
[in, optional] VARIANT SourceTable,
[in, optional] VARIANT SourceField);
[id(0x60020003), propput, hidden, helpstring("Indicates if ReadOnly property of a field is disabled ")]
void ReadOnlyDisabled([in] VARIANT_BOOL rhs);
};
How can I create an instance of an InMemoryRecordset object when I can only see it in VB?
Thanks
Dave
Dave
http://www.unit-conversion.com
|
|
|
|
|
Is there any method to connect to any web browser, not just IE. For example FireFox, Opera e.g
|
|
|
|
|
The detail is in the following:
Case 1:
1. Create a ATL Project in VS .Net
2. Add Class (ATL Simple Object) to the ATL Project.
3. Add a method [STDMETHODIMP CTestDll::Add(DOUBLE x, DOUBLE y, DOUBLE* result)]
4. Build it
The result is in the following:
http://slibody.dyndns.org/Case1.JPG
Case 2:(The problem happens when i add web reference to the ATL project)
1. Create a ATL Project in VS .Net
2. Add Web Reference
3. Add Class (ATL Simple Object) to the ATL Project.
4. Add a method
[STDMETHODIMP CSessionService::NewSession(BSTR UserID, BSTR PassWd, BSTR IP, BSTR Hostp, BSTR* NewSessionResult, LONG* NewSessionResult_nSizeIs)] <-- Using WebService
5. Build it
The result is in the following:
http://slimbody.dyndns.org/Case2.JPG
The error message is
NtuhWebService error PRJ0019: A tool returned an error code from "Performing registration"
How can i solve this problem?
Thanks ...
|
|
|
|
|
The detail is in the following:
Case 1:
1. Create a ATL Project in VS .Net
2. Add Class (ATL Simple Object) to the ATL Project.
3. Add a method [STDMETHODIMP CTestDll::Add(DOUBLE x, DOUBLE y, DOUBLE* result)]
4. Build it
The result is in the following:
http://slimbody.dyndns.org/Case1.JPG
Case 2The problem happens when i add web reference to the ATL project)
1. Create a ATL Project in VS .Net
2. Add Web Reference
3. Add Class (ATL Simple Object) to the ATL Project.
4. Add a method
[STDMETHODIMP CSessionService::NewSession(BSTR UserID, BSTR PassWd, BSTR IP, BSTR Hostp, BSTR* NewSessionResult, LONG* NewSessionResult_nSizeIs)] <-- Using WebService
5. Build it
The result is in the following:
http://slimbody.dyndns.org/Case2.JPG
The error message is
NtuhWebService error PRJ0019: A tool returned an error code from "Performing registration"
How can i solve this problem?
Thanks ...
|
|
|
|
|
I am new to COM so please be gentle.
I am trying to use COM as follows:
1) I have a client which I would like to load loosely coupled servers.
2) The servers need to be able to handle the following
a) I would like to have a function
HRESULT OnMessage( CSystem * pSys, CMessage * pMsg )
b) I need to be able to use CSystem and CMessage which only exist in the client.
What parts of COM should I use?
I am thinking that besides the basics I will need to use:
1) IDispatch
2) Marshalling ???
Can anyone shed any light or point me to some info?
|
|
|
|
|
smesser wrote:
HRESULT OnMessage( CSystem * pSys, CMessage * pMsg )
Nope. If you pass pointers, they will point to the address space of a different application, and in this case on a different machine. Also, the types which COM can pass are very limited.
You'd need instead to pass the data you need to recreate these classes, and the classes would have to exist in both projects, obviously.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
Thanks for your response.
I have since decided to use abstract interfaces and abstract factories.
This combination seems to meet my needs without having to deal with COM.
|
|
|
|
|
Christian Graus wrote:
Also, the types which COM can pass are very limited.
That depends entirely on what clients you have. For VBScript clients, you'll have to dumb down your interfaces quite a lot. But with C++ clients, you can do virtually anything. All you have to do is play nice with the IDL language, which allows for powerful enough datastructures (structs and unions of arbitrary IDL compatible types). But yeah, you won't be doing any template magic through IDL anytime soon.
[edit]Straight VB handles pretty much everything that C++ does, too.[/edit]
Good music: In my rosary[^]
|
|
|
|
|
I'm trying to change the default tooltip Explorer shows for folders (when the mouse is hovering), using IQueryInfo interface. It works for files (.xxx) but couldn't make it work for folders.
Did anybody do it?
Also, is it possible to modify/subtract items from the Explorer context menu for folders?. I can add items using QueryContextMenu, (albeit not in the desired menu place), but can't delete/modify Explorer's items.
Suggestions will be appreciated.
TIA
alex
alex
|
|
|
|
|
I'm trying to develop an add-in for Outlook Express, the add-in is supposed to intercept sending mails and (optionally) add attachments to the mail being sent.
I have already done that on Microsoft Outlook using Visual Studio Tools for Office, but I couldn't find any way to do it on Outlook Express.
Help would be greatly appreciated, just point me on the way.
Thanks in advance,
Wessam Fathi
|
|
|
|
|
Wessam Fathi wrote:
I'm trying to develop an add-in for Outlook Express, the add-in is supposed to intercept sending mails and (optionally) add attachments to the mail being sent.
Check if this Help :-
http://www.codeproject.com/com/Outlook_Express_Messages.asp[^]
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow
cheers,
Alok Gupta
|
|
|
|
|
Is it possible to have two applications, running as seperate processes, in the same window?
Is so, how or can you point me at a good reference source?
Thanks.
|
|
|
|
|
you can use threading. try search you will find lot on it..
|
|
|
|
|