Working with the COM + admin using C#

 

Pre Requisites to work with the sample

Windows 2000 Sp1
.NET SDK

This sample covers the following concepts:<o:p> </o:p>
- Late binding to COM objects via Reflection
- Using the XmlDocument, DocumentNavigator, etc within the  System.Xml namespace to load XML files and fire XPath querries.
- Using the COM+ admin objects to talk to the COM+ catalog and query theproperties for each COM+ app installed as well as the components within them.

Motivation
I wanted to explore the interoperability .Net provides with COM components. What would be a better way than to test it with existing components installed within the system. Since I already had worked with the COM+ admin objects sometime back and not much samples are available on it, thought that working with it in C# would be cool.

<center>

Source/Misc Files

 

Descriptions

 

TestComAdmin.cs

 

Contains the client

 

dispCOMWrapper.cs 

 

Contains helper classes which are compiled as components

 

build.bat

 

Builds the source files
ComPlusPropertyMap.xml Contains a complete list from MSDN about the various properties exposed by the Applications as well as the Components collection in XML format. *See diagram below.

</center>

 

 

 <!–[if gte vml 1]><V:SHAPETYPE id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"> <V:STROKE joinstyle="miter" /><V:FORMULAS><V:F eqn="if lineDrawn pixelLineWidth 0" /><V:F eqn="sum @0 1 0" /><V:F eqn="sum 0 0 @1" /><V:F eqn="prod @2 1 2" /><V:F eqn="prod @3 21600 pixelWidth" /><V:F eqn="prod @3 21600 pixelHeight" /><V:F eqn="sum @0 0 1" /><V:F eqn="prod @6 1 2" /><V:F eqn="prod @7 21600 pixelWidth" /><V:F eqn="sum @8 21600 0" /><V:F eqn="prod @7 21600 pixelHeight" /><V:F eqn="sum @10 21600 0" /></V:FORMULAS><V:PATH o:connecttype="rect" gradientshapeok="t" o:extrusionok="f" /><O:LOCK aspectratio="t" v:ext="edit" /></V:SHAPETYPE><V:SHAPE id=_x0000_i1025 style="WIDTH: 431.25pt; HEIGHT: 324pt" type="#_x0000_t75"><V:IMAGEDATA o:title="" src="file:///C:/DOCUME~1/ranjeet/LOCALS~1/Temp/msoclip1/01/clip_image001.png" /></V:SHAPE><![endif]–><o:p></o:p>

<o:p></o:p>Figure1 :ComPlusPropertyMap.xml

 

Description
There are 2 approaches I could have taken to use theseobjects:
- Use the tlbimp tool to generate equivalent .NET metadata to be used within C# or
- Late binding via IDispatch using Reflection. I chose thelatter purely to explore reflection. Using tlbimp would have been easier. 

When a .NET client tries to use and instantiate a COM component, the .NETruntime exposes the object via something called a runtime callable wrapper (RCW)that acts as a proxy for the real unmanaged object. The .NET client is fooled into thinking that it is talking to just another block of managed code. Theprimary function of the RCW is to marshal calls between the boundaries of themanaged and unmanaged code. For more details/diagrams on the Runtime CallableWrappers refer the .NET Framework SDK documentation under 
.NET Framework Developer's Guide\Interoperating with Unmanaged Code\Advanced COMInterop\COM Interop Wrappers  .
 Every body starts off/steals/borrows/enhances code from there.

In the example, I have create an instance of the COMAdminCatalog object along with these lines.
Via this object I can get at the Applications' collection exposed as a COMAdminCatalogCollectionObject.

The sample comes with two helper classes dispCOMWrapper and COMPlusAdminHelper.
The following lines uses these helper classes to print out the count of all theCOM+ apps installed on your system.


dispCOMWrapper
m_oCatalog;
dispCOMWrapper m_oDispColApps;
m_oCatalog = new dispCOMWrapper("COMAdmin.COMAdminCatalog");
m_oDispColApps = new dispCOMWrapper(m_oCatalog.callMethod("GetCollection", new Object [] {"Applications"} ));
m_oDispColApps.callMethod("Populate",newobject [] {});
Console.Write( ?Total no of COM+ applications on your system :? + m_oDispColApps.getProperty("Count").ToString());

 

There is a method known as GenerateReport() within the COMPlusAdminHelper classthat peek

s in to
the COM+ catalog and iterates each and every application andthen through each and every Component within it, and while it does, it generatesan XML based report in the same directory as the executable.
One can write equivalent XSL to display it in a more intuitive UI than thedefault vanilla XSL that IE provides.

Theoutput file generated looks something like this:

<!–[if gte vml 1]><V:SHAPETYPE id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><V:STROKE joinstyle="miter" /><V:FORMULAS><V:F eqn="if lineDrawn pixelLineWidth 0" /><V:F eqn="sum @0 1 0" /><V:F eqn="sum 0 0 @1" /><V:F eqn="prod @2 1 2" /><V:F eqn="prod @3 21600 pixelWidth" /><V:F eqn="prod @3 21600 pixelHeight" /><V:F eqn="sum @0 0 1" /><V:F eqn="prod @6 1 2" /><V:F eqn="prod @7 21600 pixelWidth" /><V:F eqn="sum @8 21600 0" /><V:F eqn="prod @7 21600 pixelHeight" /><V:F eqn="sum @10 21600 0" /></V:FORMULAS><V:PATH o:connecttype="rect" gradientshapeok="t" o:extrusionok="f" /><O:LOCK aspectratio="t" v:ext="edit" /></V:SHAPETYPE><V:SHAPE id=_x0000_i1025 style="WIDTH: 431.25pt; HEIGHT: 324pt" type="#_x0000_t75"><V:IMAGEDATA o:title="" src="file:///C:/DOCUME~1/ranjeet/LOCALS~1/Temp/msoclip1/01/clip_image001.png" /></V:SHAPE><![endif]–>

Figure2 :ComPlusReport.xml

 

 

Figure3: The structure of the generated XML file.

To read/write/navigate xml files/nodes Ihave used the following classes provided the System.Xml namespace:
XmlDocument, DocumentNavigator, XmlNode, XmlElement, XmlNamedNodeMap,XmlAttribute.


One thing I have to admit. I found it difficult to initially move to a syntaxdifferent than the regular MSXML syntax for firing XPath querries, but then nochoice, you gotta learn it.

Build:
Run build.bat, and then the sample.

References:
http://msdn.microsoft.com/msdnmag/issues/01/01/xml/xml.asp
(From the GURUAaron Skonnard himself)
http://www.codeproject.com/com/complus_admin.asp
(using COM+ admin objectsfrom VC++)

Note: Havent done much bugtesting though and not much exception handling :( Lemme know if any bugs.
And as usual as Paul Di Lascia says, If this works I am reponsible or I don'tknow who the hell did it !

 <o:p></o:p>


Twitter Digg Delicious Stumbleupon Technorati Facebook Email

No comments yet... Be the first to leave a reply!