C# Source Code: Iterating through the contents of the ROT (running objects table)
[
Home
|
Contents
|
Search
|
Reply
| Previous |
Next
]
C# Source Code
Iterating through the contents of the ROT (running objects table)
By:
Andrew Baker
Email (spam proof):
Email the originator of this post
Date:
Sunday, February 26, 2006
Hits:
5722
Category:
COM/Interop
Article:
The System.Runtime.InteropServices.Marshal.GetActiveObject method will return an existing instance of application registered in the Running Objects Table (ROT) by matching the prog id (or moniker) to an entry in this table. Note, Office applications do not register themselves if another instance is already in the ROT because the moniker for itself is always the same, and cannot be distinguished. This means that you cannot attach to any instance except for the first instance. However, because Office applications also register their documents in the ROT, you can successfully attach to other instances by iterating the ROT looking for a specific document, and attaching to this document to get the Application object from this document. The source code below contains a ROTHelper class, which among other things, demonstrates how to iterate through the ROT. Note, once you have the desired application object you will either need to use reflection or cast to the relevant COM interface to call any methods. using System; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Collections; #region TestROT Class ///
/// Test ROT class showing how to use the ROTHelper. ///
class TestROT { ///
/// The main entry point for the application. ///
[STAThread] static void Main(string[] args) { // Iterate through all the objects in the ROT Hashtable runningObjects = ROTHelper.GetActiveObjectList(null); // Display the object ids foreach( DictionaryEntry de in runningObjects ) { string progId = de.Key.ToString(); if ( progId.IndexOf("{") != -1 ) { // Convert a class id into a friendly prog Id progId = ROTHelper.ConvertClassIdToProgId( de.Key.ToString() ) ; } Console.WriteLine( progId ); object getObj = ROTHelper.GetActiveObject(progId); if ( getObj != null ) { Console.WriteLine( "Fetched: " + progId ); } else { Console.WriteLine( "!!!!!FAILED TO fetch: " + progId ); } } Console.ReadLine(); } } #endregion TestROT Class #region ROTHelper Class ///
/// The COM running object table utility class. ///
public class ROTHelper { #region APIs [DllImport("ole32.dll")] private static extern int GetRunningObjectTable(int reserved, out UCOMIRunningObjectTable prot); [DllImport("ole32.dll")] private static extern int CreateBindCtx(int reserved, out UCOMIBindCtx ppbc); [DllImport("ole32.dll", PreserveSig=false)] private static extern void CLSIDFromProgIDEx([MarshalAs(UnmanagedType.LPWStr)] string progId, out Guid clsid); [DllImport("ole32.dll", PreserveSig=false)] private static extern void CLSIDFromProgID([MarshalAs(UnmanagedType.LPWStr)] string progId, out Guid clsid); [DllImport("ole32.dll")] private static extern int ProgIDFromCLSID([In()]ref Guid clsid, [MarshalAs(UnmanagedType.LPWStr)]out string lplpszProgID); #endregion #region Public Methods ///
/// Converts a COM class ID into a prog id. ///
///
The prog id to convert to a class id. ///
Returns the matching class id or the prog id if it wasn't found.
public static string ConvertProgIdToClassId( string progID ) { Guid testGuid; try { CLSIDFromProgIDEx(progID, out testGuid); } catch { try { CLSIDFromProgID(progID, out testGuid); } catch { return progID; } } return testGuid.ToString().ToUpper(); } ///
/// Converts a COM class ID into a prog id. ///
///
The class id to convert to a prog id. ///
Returns the matching class id or null if it wasn't found.
public static string ConvertClassIdToProgId( string classID ) { Guid testGuid = new Guid(classID.Replace("!","")); string progId = null; try { ProgIDFromCLSID(ref testGuid, out progId); } catch (Exception) { return null; } return progId; } ///
/// Get a snapshot of the running object table (ROT). ///
///
A hashtable mapping the name of the object in the ROT to the corresponding object ///
The filter to apply to the list (nullable). ///
A hashtable of the matching entries in the ROT
public static Hashtable GetActiveObjectList(string filter) { Hashtable result = new Hashtable(); int numFetched; UCOMIRunningObjectTable runningObjectTable; UCOMIEnumMoniker monikerEnumerator; UCOMIMoniker[] monikers = new UCOMIMoniker[1]; GetRunningObjectTable(0, out runningObjectTable); runningObjectTable.EnumRunning(out monikerEnumerator); monikerEnumerator.Reset(); while (monikerEnumerator.Next(1, monikers, out numFetched) == 0) { UCOMIBindCtx ctx; CreateBindCtx(0, out ctx); string runningObjectName; monikers[0].GetDisplayName(ctx, null, out runningObjectName); object runningObjectVal; runningObjectTable.GetObject( monikers[0], out runningObjectVal); if ( filter == null || filter.Length == 0 || filter.IndexOf( filter ) != -1 ) { result[ runningObjectName ] = runningObjectVal; } } return result; } ///
/// Returns an object from the ROT, given a prog Id. ///
///
The prog id of the object to return. ///
The requested object, or null if the object is not found.
public static object GetActiveObject(string progId) { // Convert the prog id into a class id string classId = ConvertProgIdToClassId( progId ); UCOMIRunningObjectTable prot = null; UCOMIEnumMoniker pMonkEnum = null; try { int Fetched = 0; // Open the running objects table. GetRunningObjectTable(0, out prot); prot.EnumRunning(out pMonkEnum); pMonkEnum.Reset(); UCOMIMoniker[] pmon = new UCOMIMoniker[1]; // Iterate through the results while (pMonkEnum.Next(1, pmon, out Fetched) == 0) { UCOMIBindCtx pCtx; CreateBindCtx(0, out pCtx); string displayName; pmon[0].GetDisplayName(pCtx, null, out displayName); Marshal.ReleaseComObject(pCtx); if ( displayName.IndexOf( classId ) != -1 ) { // Return the matching object object objReturnObject; prot.GetObject(pmon[0], out objReturnObject); return objReturnObject; } } return null; } finally { // Free resources if (prot != null ) Marshal.ReleaseComObject( prot); if (pMonkEnum != null ) Marshal.ReleaseComObject ( pMonkEnum ); } } #endregion } #endregion
Terms and Conditions
Support this site
Download a trial version of the best FTP application on the internet