我正在尝试做一些非常简单的事情(也可能是)。我希望用户能够定义一个进程(几乎肯定是从任务管理器中获取),然后我的应用程序将根据正在运行的进程执行不同的操作。
我一直在玩Process.GetProcesses()
来获取这些信息,但我很难理解我得到的数据以及它与任务管理器显示的内容之间的关系。
我真正想要的是一个进程名称列表,它与任务管理器中的“名称”字段相同。我可以使用Path.GetFileName(theprocess.MainModule.FileName);
来获取它,但在枚举某些进程时我得到了很多异常。这看起来(来自谷歌搜索)特别是在跨64位/ 32位平台上,并且虽然我可以很容易地捕获并忽略这些,但它变得异常缓慢。
所以,我希望使用像process.ProcessName
这样的东西。乍一看,这似乎与任务管理器完全相同,但是它有一些奇怪的一两个任务,它们没有显示在任务管理器中。
我应该做其他事情,还是应该process.ProcessName就足够了?
顺便说一句,我只对枚举当前用户/会话的进程感兴趣。
这是我的一个代码示例:
foreach (theprocess in processList)
{
try
{
string fileName = theprocess.MainModule.FileName;
currentProcessList.Add(fileName.ToLower());
}
catch (Exception e)
{
}
}
答案 0 :(得分:3)
我从未使用过您的方法,但在我的应用程序中,我使用WMI按如下方式迭代进程:
List<ManagementObject> processInfo = processWmi.CreateRequest("SELECT * FROM Win32_Process");
processWmi是我用于所有WMI查询的类,它具有额外的功能,可以在查询挂起时终止查询(WMI似乎在某些服务器上执行)。本课程的核心如下所示。
private static string _query;
private static string _scope;
private static List<ManagementObject> _data;
private static bool _queryComplete;
private int _timeout = 300;
private static readonly object Locker = new Object();
public List<ManagementObject> CreateRequest(string query, bool eatErrors = false, string scope = null)
{
try
{
lock (Locker)
{
_queryComplete = false;
AscertainObject.ErrorHandler.WriteToLog("Running WMI Query: " + query + " Timeout:" + _timeout, true);
_query = query;
_scope = scope;
Thread serviceThread = new Thread(RunQuery) { Priority = ThreadPriority.Lowest, IsBackground = true };
serviceThread.Start();
int timeLeft = _timeout * 10;
while (timeLeft > 0)
{
if (_queryComplete)
return _data;
timeLeft--;
Thread.Sleep(100);
}
if (eatErrors == false)
AscertainObject.ErrorHandler.WriteToLog("WMI query timeout: " + query, true, "");
serviceThread.Abort();
}
}
catch (Exception ex)
{
if (eatErrors == false)
AscertainObject.ErrorHandler.WriteToLog("Error Running WMI Query", true, ex.ToString());
}
return null;
}
public void SetRequestTimeout(int timeoutSeconds)
{
_timeout = timeoutSeconds;
AscertainObject.ErrorHandler.WriteToLog("WMI query timeout changed to " + timeoutSeconds + " seconds", true);
}
private void RunQuery()
{
try
{
ManagementObjectSearcher searcher = _scope != null ? new ManagementObjectSearcher(_scope, _query) : new ManagementObjectSearcher(_query);
List<ManagementObject> innerData = searcher.Get().Cast<ManagementObject>().ToList();
_data = innerData;
}
catch (Exception ex)
{
AscertainObject.ErrorHandler.WriteToLog("WMI query failed, may have invalid namespace", true, null, true);
_data = null;
}
_queryComplete = true;
}
您可以按照以下方式从WMI结果中提取所需数据(键入适当的转换以匹配我的Process类):
foreach (ManagementObject item in processInfo)
{
Process tempProcess = new Process
{
id = Convert.ToInt32((UInt32)item["ProcessID"]),
name = (String)item["Name"],
path = (String)item["ExecutablePath"],
parentID = Convert.ToInt32((UInt32)item["ParentProcessID"]),
handleCount = Convert.ToInt32((UInt32)item["HandleCount"]),
priority = Convert.ToInt16((UInt32)item["Priority"]),
threadCount = Convert.ToInt32((UInt32)item["ThreadCount"]),
workingSetMB = Convert.ToInt64((UInt64)item["WorkingSetSize"]) / 1048576,
peakWorkingSetMB = Convert.ToInt64((UInt32)item["PeakWorkingSetSize"]) / 1024,
pageFileUsageMB = Convert.ToInt64((UInt32)item["PageFileUsage"]) / 1024,
peakPageFileUsage = Convert.ToInt64((UInt32)item["PeakPageFileUsage"]) / 1024
};
try
{
//get owner info
object[] ownerInfo = new object[2];
item.InvokeMethod("GetOwner", ownerInfo);
tempProcess.processOwner = (string)ownerInfo[0];
}
catch
{
}
}
WMI结果通常很快返回,系统几乎没有开销。它们的行为类似于SQL查询,您可以使用正确的WHERE子句过滤结果。
以下是您可以从Win32_Process获取的所有信息的链接: http://msdn.microsoft.com/en-us/library/aa394372(v=vs.85).aspx