是否可以在C#(4.0)中获取已安装的Com +应用程序列表在同一个框中,然后检索每个应用程序的状态(运行/关闭)?
我可以找到启动/停止的方法,但不能检索状态。
答案 0 :(得分:6)
我认为COM +管理组件只允许您查询“静态”配置属性(例如Identity,IsEnabled),并且不允许您查询COM +的动态属性(例如PID)。 < / p>
我发现做你想做的事的唯一方法是使用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;
}
答案 1 :(得分:1)
您检查过COM+ administration个组件了吗?我敢打赌,你可以使用这些界面找到这些信息。
最佳