本帖最后由 goldli 于 2019-3-20 08:59 编辑
如题。 使用 C# + WMI + WPF 完成。 速度快。可以直接点击拷贝文字。 缺点,后台使用了3个线程,大约会占17%~30% 的CPU
需要安装 .net framework 4.52来运行
文件下载
WinAppCmdLineMonitor.rar
(9.2 KB, 下载次数: 163)
核心代码如下:
[C#] 纯文本查看 复制代码 internal sealed class ProcessMonitor
{
private readonly ConcurrentDictionary<string, ProcessInfo> _processes;
private readonly ConcurrentQueue<ProcessInfo> _listQueue;
public ProcessMonitor()
{
_processes = new ConcurrentDictionary<string, ProcessInfo>();
_listQueue = new ConcurrentQueue<ProcessInfo>();
}
public void Start(CancellationToken token)
{
StartMonitor(token);
Parse(token);
ProcessDestroyMonitor(token);
}
/// <summary>
/// 使用wmi获取当前进程快照
/// </summary>
/// <param name="fields">选取的字段</param>
/// <returns></returns>
private ManagementObjectCollection getCurrentProcess(string fields = "*")
{
using (var searcher = new ManagementObjectSearcher($"SELECT {fields} FROM Win32_Process"))
{
return searcher.Get();
}
}
/// <summary>
/// 开始监控
/// </summary>
/// <param name="token"></param>
private void StartMonitor(CancellationToken token)
{
Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested)
{
foreach (var o in getCurrentProcess())
{
var w = new ProcessInfo(o);
if (!_processes.ContainsKey(w.Key))
{
_processes[w.Key] = w;
_listQueue.Enqueue(w);
}
Thread.Sleep(1);
}
Thread.Sleep(10);
}
},token);
}
/// <summary>
/// 开始解析监控的结果
/// </summary>
/// <param name="token"></param>
private void Parse(CancellationToken token)
{
Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested)
{
if (!_listQueue.IsEmpty)
{
if (_listQueue.TryDequeue(out var p))
{
OnAsyncGotProcess?.BeginInvoke(p,null,null);
}
}
Thread.Sleep(10);
};
}, token);
}
/// <summary>
/// 判断指定的进行是否还在运行
/// </summary>
/// <param name="pi"></param>
/// <param name="list"></param>
/// <returns></returns>
private bool IsProcessExists(ProcessInfo pi, ManagementObjectCollection list)
{
foreach (var p in list)
{
if (pi.IsSameWith(p))
{
return true;
}
}
return false;
}
/// <summary>
/// 对当前进程快照进行分析,与原有的快照进行对比。以判断是否有进程已经销毁
/// </summary>
/// <param name="token"></param>
private void ProcessDestroyMonitor(CancellationToken token)
{
Task.Factory.StartNew(() =>
{
while (!token.IsCancellationRequested)
{
if (!_processes.IsEmpty)
{
var list = getCurrentProcess(" ProcessId ,Name ");
var storedList = _processes.Values;
foreach (var p1 in storedList)
{
if (IsProcessExists(p1, list))
{
continue;
}
_processes.TryRemove(p1.Key, out _);
Thread.Sleep(1);
}
}
Thread.Sleep(200);
};
}, token);
}
public event Action<ProcessInfo> OnAsyncGotProcess;
}
|