Click here to Skip to main content
15,880,608 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello

I use one 3rd party C++ based application that exposes functionality thru a COM IDispatch
Server. Essentially, it is a proprietary database reader. It is a very well written commercial software. This C++ application is allowed to run multiple instances, I am wondering whether
or not I can control which executing instance will be used as the COM Server.

Currently, the way I manually configure the machine every morning is as follows

1) I start first instance of the C++ app and correctly connect it to database A.
2) I start my C# app that are clients to this COM and bind it to only running instance.
C# must always connect to COM server with database A only.
3) I start second instance of the C++ app and connect it to database B.

Problem occurs when C# app has to be closed and restarted. I also have to close off the second instance otherwise I cannot determine which process will respond as COM server.

In C#, I can very easily detect the running Processes vide System.Diagnostics.Process so I can know whether or not I have multiple instances. COM Server does expose functionality to know name of opened database but how do I link it back to the executing process?
Posted
Comments
Sergey Alexandrovich Kryukov 27-Sep-13 16:50pm    
I wonder why. From the standpoint of .NET, COM servers is way too obsolete stuff. COM was created as an object-oriented interoperability layer, when OS APIs were non-object-oriented, but this is not the case for .NET. This is the same as offering a wheel chair to a person who can walk well...
—SA
[no name] 27-Sep-13 20:41pm    
Hi, COM and DCOM are not considered obsolete at Microsoft. We are still utilizing this technology on new architectures including WinRT.

Best Wishes,
-David Delaune
Sergey Alexandrovich Kryukov 27-Sep-13 21:33pm    
I know, they do, but it does not make it reasonable. Pure people... :-)
Good luck.
—SA
ExcellentOrg 28-Sep-13 4:06am    
Sergey

I did not decide what 3rd party C++ app uses. I know it is C++ because I happened to get a chance to talk to one of its developer. It is a very good application (probably best in its class). It is certainly good at what it does and it provides access to its data thru COM (which maybe obsolete), is efficient. Moreover from my POV and user's POV, cost of acquiring the s/w; learning its usage is already invested, so why chase a new horse and spend unnecessary moolah?
Sergey Alexandrovich Kryukov 28-Sep-13 10:36am    
Well, you answered my question, thank you. Looks reasonable.
—SA

1 solution

Hi,

Sounds like a missing feature. Perhaps you should contact the company and make a feature request. :)

If the COM Server is local then you could probably call NtQuerySystemInformation[^] with the SystemHandleInformation information class for enumerating all open file handles and matching it with a process ID. This may or may not work; it depends on the process keeping a persistent open file handle.

Another idea... would be to create a wrapper process that launches the COM server via CreateProcess [^] and have the wrapper process export an interface for obtaining the process id.

If its a remote machine... out-of-proc via RPC then unfortunately you are out of luck.

Best Wishes,
-David Delaune
 
Share this answer
 
Comments
ExcellentOrg 28-Sep-13 5:01am    
David,

Yes!, It is on same machine and it is safe to assume that it will always run on the same machine. I did take a look at the URL you gave. it does not have "SystemHandleInformation" but it does have SystemProcessInformation which returns array containing Process information. Following is the code snippet that works correctly as long as only one instance is running.

private Object AccessCOMServer(String nameOfExecutable, String COMProgID)
{
Process[] proc = Process.GetProcessesByName(nameOfExecutable);
if (proc.Length == 1)
{
Type dataAppProgID = Type.GetTypeFromProgID(COMProgID);
_dataApp = Activator.CreateInstance(dataAppProgID);
String currentPath = _dataApp.GetType().InvokeMember("DatabasePath", BindingFlags.GetProperty, null, _dataApp, null).ToString();
}
}

Debugger shows

proc[0] is shown in debugger as instance of System.Diagnostics.Process with all information including process id, name of executable, path of executable and even command line arguments that were used to invoke it.

dataAppProgID is shown as instance of System.RuntimeType with many properties and assembly that originates from is shown as mscorlib
_dataApp as System.__ComObject with only visible properties Identity and m_ObjectToDataMap (Hashtable) as null
but all invoke

Even I use the second suggestion of using CreateProcess, it will execute the new instance all right and connected to correct database but how do I get the COM server to bind to correct running process.

Entire problem revolves around my limited understanding of Activator.CreateInstance which as 13 overloads and some of them do accept things like assembly domain, but Process object does not expose assembly's appdomain.
ExcellentOrg 28-Sep-13 6:52am    

The COM Library
[^]

Second para at the above link reads ....

Implementation-locator services through which COM determines, from a unique class identifier (CLSID), which server implements that class and where that server is located. This service includes support for a level of indirection, usually a system registry, between the identity of an object class and the packaging of the implementation so that clients are independent of the packaging, which can change in the future.

Am I correct in interpretation that in this particular context of mine, I am trying to bypass this indirection and allow client to decide the server is going to be?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900