COMClient easy integration - using generic COMProxy and VAO


posted by Gary
03-28-2007

Downloads: 820
Views: 3,159
COMClient easy integration - using generic COMProxy and VAO

This example shows how simple it is to integrate VSTA into a COM application using a generic proxy and VAO. The generic proxy can be used to expose any COM object model (type library) to VSTA without using proxygen.  VAO is used to simplify the integration process.

Synopsis:  The COMClient passes an IUnknown ptr to an instance of its COM object directly to the VSTA Addin via a Connector object:

pConnector->AssignHostObject(pDispMyCOMServer);

The VSTA Addin obtains the same instance of the COM Object as a System.__ComObject.

object obj = this.GetHostObject();

The VSTA Addin uses a reference to the COMInterop assembly (created with tlbimp MSDNCOMServer.dll ) to provide strong type information for the COM Object .

MSDNCOMServerLib.IMyCOMServer myOM = obj as MSDNCOMServerLib.IMyCOMServer;

myOM.MySimpleCOMServerMethod();

This approach uses a generic proxy layer (no need to run proxygen) that exposes one method to the Addin author.

System.Object Connector.GetHostObject()

Although the sample macro does not demonstrate it, this hookup method can easily be hidden in a global property like 'Application' so that the Addin author can use normal syntax to access the Application object model:

Application.MySimpleCOMServerMethod();

 

updated download with ReadMe:  ftp://ftp.summsoft.com/vsta/COMClientVAOv2.zip

Comments

hyun wrote Re: COMClient easy integration - using generic COMProxy and VAO
on 03-29-2007 2:40 AM
thank you very much, Gary. I am very glad to see this! ^^ the samples that summit software provide are very helpful. I will test with this sample and let you know any problem if exists.
Gary wrote Re: COMClient easy integration - using generic COMProxy and VAO
on 04-30-2007 5:14 PM
Updated with revised VAO source and a revised COMClient sample that properly manages messageloop and the ComConnector ref count. The change in VAO is in VSTAHookup.cs, StopVSTA() method’s last few lines, which causes the connector object to be released immediately: [ mHostItemProvider = null; GC.Collect(); GC.WaitForPendingFinalizers(); ] public void StopVSTA() { // Safely exit debug mode in the VSTA IDE before shutting VSTA down if (mDTE != null) { StopDebugging(); mDTE.Quit(); } try { ExternalDebugging.UnregisterExternalDebugHost(mHostDebugUri); } catch { // Ignore the exception } UnloadAppAddIns(); UnloadMacros(); try { if (mAddInProcess != null) { mAddInProcess.AddInProcessExited -= new EventHandler(AddInProcess_AddInProcessExitedMacro); mAddInProcess.Dispose(); mAddInProcess = null; } } catch { // Ignore the exception } mHostItemProvider = null; GC.Collect(); GC.WaitForPendingFinalizers(); } ============= The other changes – in COMClient.cpp and COMConnector, ConnectorClass.cpp properly manages the messageloop and the Connector ref count for proper shut down. ============= Incidentally, if necessary, your COM application can force the CLR to release all its references to interface ptrs inside RCWs (ie: like VSTA’s reference to CLSID_COMConnector instance) by calling CoEEShutDownCOM() as follows: #include "cor.h" … CoEEShutDownCOM(); This was not necessary in the sample, and usually should not be necessary. Also, your unmanaged application can instruct the CLR to shutdown in an orderly way (includes CLR calling finalization of all unfinalized .NET objects) and exit process by calling CorExitProcess() with passed in error code. This may be needed by pre-VC++7 COM clients to assure that finalization occurs at shutdown as expected: #include "mscoree.h" … CorExitProcess(0); ==========
Melody wrote Re: COMClient easy integration - using generic COMProxy and VAO
on 06-12-2007 3:36 PM
Here is an updated download. It contains the release and debugg versions as well as a walkthrough
kab wrote Re: COMClient easy integration - using generic COMProxy and VAO
on 07-07-2008 10:47 AM
Hello Gary and Melody I am new to VSTA and have downloaded you sample and am trying it out. Wow it takes a lot of complicated setup just to run the sample. I have created a new exe (TestGUI) to replace ComClient and a new ATL COM Sever (VSTATester) which contains a COM object (HostControlTest) to replace MSDNComServer. I can launch the IDE, create a script and run it as a macro. However, there are some problems with the ref. counting on the ComConnector which often leads to a crash at shut down! I have tried to look at Garys comment above regarding the StopVSTA but cannot figure out if the GC.Collect and GC.Wait... should be added or removed. If I do the following: -Create the pVAO, connector etc. as in your sample -Run the macro using pVao->LoadMacros(true); -Wait for the macro to execute, it uses this.GetHostObject() -Release the com objects I created The ICOMConnector used for pVao->RegisterHostItem() has a ref count of 1 after I release my 'instance'. This means that the last 'instance' is destroyed when the app closes causing an exection somewhere in: Microsoft.VisualStudio.Tools.Applications.InteropAdapter.dll!Microsoft.VisualStudio.Tools.Applications.ComObjectAdapter.FreeNativeResources() Or at least that is what the compiler thinks. It does not seem to make a difference if I use the last three lines from Gary's comment or not: ... mHostItemProvider = null; GC.Collect(); GC.WaitForPendingFinalizers(); ... I have tried to search your forums and found various stuff sounding similar but have not been able to determine how to solve this. Could you please help? Kim
kab wrote Re: COMClient easy integration - using generic COMProxy and VAO
on 07-07-2008 10:54 AM
Hello again, The crash only happens if the macro uses GetHostObj(), but I guess that is to be expected? Kim
Copyright Summit Software Company, 2008. All rights reserved.