Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if COM+ application is already running?

Tags:

c#

com+

Is it possible in C# (4.0) to get the list of installed Com+ applications on the same box and then retrieve the status (Running/Shut down) of each of them?

I can find methods to start/stop, but not retrieve status.

like image 301
BlueChippy Avatar asked Sep 16 '10 12:09

BlueChippy


People also ask

How do you check if a application is running?

The best place to start when monitoring apps is the Task Manager. Launch it from the Start menu or with the Ctrl+Shift+Esc keyboard shortcut. You'll land on the Processes screen. At the top of the table, you'll see a list of all the apps which are running on your desktop.

How can I tell if an EXE is running C#?

GetCurrentProcess(); Process[] processes = Process. GetProcessesByName (current. ProcessName); //Loop through the running processes in with the same name foreach (Process process in processes) { //Ignore the current process if (process.Id != current.Id) { //Make sure that the process is running from the exe file.


2 Answers

I think the COM+ Administrative components only lets you query the "static" configuration properties (e.g. Identity, IsEnabled) and doesn't let you query the dynamic properties of COM+ (e.g. PID).

The only way I found to do what you want is using the COMSVCSLib (COM+ Services Type Library).

UPDATE: Based on @Vagaus's comment, we can use either COM+ Administrative components or COM+ Services Type Library!

With quite a bit of help from the article Comonitor - A COM+ Monitor. I've cobbled together some code that uses COM+ Services Type Library:

public static bool IsComPlusApplicationRunning(string appName)
{
    int appDataSize = Marshal.SizeOf(typeof(COMSVCSLib.appData));
    Type appDataType = typeof(COMSVCSLib.appData);

    uint appCount;
    IntPtr appDataPtr = IntPtr.Zero;    

    GCHandle gh = GCHandle.Alloc(appDataPtr, GCHandleType.Pinned);
    IntPtr addressOfAppDataPtr = gh.AddrOfPinnedObject();

    COMSVCSLib.IGetAppData getAppData = null;
    COMSVCSLib.TrackerServer tracker = null;

    try
    {
        tracker = new COMSVCSLib.TrackerServerClass();
        getAppData = (COMSVCSLib.IGetAppData)tracker;

        getAppData.GetApps(out appCount, addressOfAppDataPtr);
        appDataPtr = new IntPtr(Marshal.ReadInt32(addressOfAppDataPtr));

        for (int appIndex = 0; appIndex < appCount; appIndex++)
        {
            COMSVCSLib.appData appData = (COMSVCSLib.appData)Marshal.PtrToStructure(
                new IntPtr(appDataPtr.ToInt32() + (appIndex * appDataSize)),
                appDataType);

            string currentAppName = GetPackageNameByPID(appData.m_dwAppProcessId);

            if (string.Compare(currentAppName, appName, StringComparison.OrdinalIgnoreCase) == 0)
            {
                Console.WriteLine("Application " + appName + " is running with PID " + appData.m_dwAppProcessId);
                return true;
            }            
        }
    }
    finally
    {
        Marshal.FreeCoTaskMem(appDataPtr);

        if (tracker != null)
        {
            Marshal.ReleaseComObject(tracker);
        }

        gh.Free();
    }

    return false;
}

private static string GetPackageNameByPID(uint PID)
{
    COMSVCSLib.MtsGrp grpObj = new COMSVCSLib.MtsGrpClass();

    try
    {
        object obj = null;
        COMSVCSLib.COMEvents eventObj = null;

        for (int i = 0; i < grpObj.Count; i++)
        {
            try
            {
                grpObj.Item(i, out obj);

                eventObj = (COMSVCSLib.COMEvents)obj;

                if (eventObj.GetProcessID() == PID)
                {
                    return eventObj.PackageName;
                }
            }
            finally
            {
                if (obj != null)
                {
                    Marshal.ReleaseComObject(obj);
                }
            }
        }
    }
    finally
    {
        if (grpObj != null)
        {
            Marshal.ReleaseComObject(grpObj);
        }
    }

    return null;
}


But we can also use the COM+ Administrative components (which seems simpler) to do the same thing:

public static bool IsComPlusApplicationRunning(string appName)
{
    COMAdmin.COMAdminCatalog catalog = new COMAdmin.COMAdminCatalogClass();

    COMAdmin.ICatalogCollection appCollection = (COMAdmin.ICatalogCollection)catalog.GetCollection("Applications");
    appCollection.Populate();

    Dictionary<string, string> apps = new Dictionary<string, string>();
    COMAdmin.ICatalogObject catalogObject = null;

    // Get the names of the applications with their ID and store for later
    for (int i = 0; i < appCollection.Count; i++)
    {
        catalogObject = (COMAdmin.ICatalogObject)appCollection.get_Item(i);
        apps.Add(catalogObject.get_Value("ID").ToString(), catalogObject.Name.ToString());
    }

    appCollection = (COMAdmin.ICatalogCollection)catalog.GetCollection("ApplicationInstances");
    appCollection.Populate();

    for (int i = 0; i < appCollection.Count; i++)
    {
        catalogObject = (COMAdmin.ICatalogObject)appCollection.get_Item(i);

        if (string.Compare(appName, apps[catalogObject.get_Value("Application").ToString()], StringComparison.OrdinalIgnoreCase) == 0)
        {
            Console.WriteLine(appName + " is running with PID: " + catalogObject.get_Value("ProcessID").ToString());
            return true;
        }
    }

    return false;
}
like image 140
Randy supports Monica Avatar answered Sep 19 '22 18:09

Randy supports Monica


Have you checked the COM+ administration components? I'd bet that you can find this information using these interfaces.

Best

like image 35
Vagaus Avatar answered Sep 19 '22 18:09

Vagaus