我认为COM+管理组件只允许您查询“静态”配置属性(例如Identity、IsEnabled),不允许您查询COM+的动态属性(例如PID)。
更新
:根据@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+管理组件(看起来更简单)来做同样的事情:
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;
}