Release the "ownership" of the COM object in .NET.

I have a client / partner who is trying to associate their application with ours using our open COM functionality. Until now, they have a COM object, which is an instance of our software package, and then uses our COM methods to programmatically create something for the user based on what they did in their application. This is essentially an โ€œexportโ€.

What they asked me to do, and I cannot figure out how to do this, to allow the user to decide when the instance is closed. What I mean is when our software package is downloaded, it is available for viewing and interacts with the user. When they end, they will naturally click the cross in the upper right corner to exit the software. This does not work because the COM object is still โ€œactiveโ€ in its application. Our software package can be closed only by killing the process in the task manager, while the application that downloaded it through COM remains open. As soon as their application comes out, ours will automatically close. It seems that their application owns ours due to a call to COM.

I made a quick demo application in C # to try using things like Marshal.FinalReleaseComObject(myObject) to no avail.

I understand that using COM for this kind of thing is actually not what it is intended for, but I hope there is some workaround? The client / partner uses VB.NET, but C # is fine.

+6
source share
1 answer

You left some critical information about your own application, including the most important thing, how do you implement the COM interfaces that you open for the client application. One aspect of your description, which is a red flag for me, is creating your application. You say that the client application "uses VB to start a new process, referencing our exe." This is not necessary if you correctly executed and registered your COM server. Let me tell you about the architecture that I would use to accomplish what you are asking, and I hope this will be useful to you.

For starters, if you want to provide a COM object from a separate process, the correct way is to implement a COM server. If there is no process server, COM starts your application automatically when the client requests one of your interfaces through COM. Part of the requirements for executing outside the process server is to automatically shut down when the last COM client releases its last interface pointer.

To bring the user interface out of the processing server, you want to create a separate single-threaded apartment (STA) stream with a message loop. This will allow you to close any window in the STA stream, including the main window, without killing your COM server. This is because the implementation of the COM server will start its own stream of message flows with multiple threads (MTA) to support COM calls from proc. The MTA thread is the main thread of the application, and the server will disable it when the last client interface is deleted.

The COM server should not stop while the interfaces remain unreleased. This means that the client application is responsible for properly releasing the interfaces. But your .NET test frame was supposed to do this, so something seems wrong with your implementation.

Assuming you are following this guide, you will need a script processing plan in which the last client interface will be released, but you still have open user interface windows. Once you're set up correctly, this should not be a serious problem. For example, you can simply take a link to one of your own interfaces while the user interface is open, this will prevent the MTA from stopping.

+3
source

Source: https://habr.com/ru/post/914735/


All Articles