繁体   English   中英

检查COM +应用程序是否已在运行?

[英]Check if COM+ application is already running?

是否可以在C#(4.0)中获取已安装的Com +应用程序列表在同一个框中,然后检索每个应用程序的状态(运行/关闭)?

我可以找到启动/停止的方法,但不能检索状态。

我认为COM +管理组件只允许您查询“静态”配置属性(例如Identity,IsEnabled),并且不允许您查询COM +的动态属性(例如PID)。

我发现做你想做的唯一方法是使用COMSVCSLib(COM +服务类型库)。

更新 :根据@ Vagaus的评论,我们可以使用COM +管理组件或COM +服务类型库!

Comonitor - A COM + Monitor这篇文章中提供了相当多的帮助。 我拼凑了一些使用COM +服务类型库的代码:

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;
}


但是我们也可以使用COM + Administrative组件(看起来更简单)来做同样的事情:

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;
}

你检查过COM +管理组件了吗? 我敢打赌你可以使用这些界面找到这些信息。

最好

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM