这篇文章将介绍一个自制的简易插件。
因为在release版用windows的task manager感觉很麻烦,每次都要找一下自己的程序,就临时想到乾脆做一个简单的小插件来玩玩。
static void Main() { PerformanceDetector.Instance.initialize(); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new frmMain()); PerformanceDetector.Instance.destroy(); }
PerformanceDetector.Instance.initialize(); PerformanceDetector.Instance.destroy();
将第一行代码加于Application.Run()之前,将第二行代码加于Application.Run()之后。
就可以在运行时透过Alt+Ctrl+M呼叫这个插件了。
因为不喜欢每次都用Task Manager,就自己整个了内存监控的代码。
一开始只是想说做个在应用内监控内存使用量的代码。所以使用Process来获取内存使用量。
但又觉得每次都去打开Log档来看很麻烦,就想说做个UI来看好了。
然后又想说,那要怎么显示这个控件?想了想既不想做在Menu也不想用一个按钮或其他控件,最后就决定用快捷来处理了。
不过第一版没有仔细想好,搞了个占据了全部画面的控件。用了才发现这样也不能边操作边看用量,好吧,重做。
所以最后决定了,就用一个单一的窗口来显示,会比较乾净。
想说CPU使用量也可以一起监控,就顺便做了。
本来是有在考虑原本第一版做的比较详细的需不需要有,但后来想想目前似乎还用不到,于是最后做成这样。
第一个关于CPU的使用部分,用的是PerformaceCounter来处理的
theCPUCounter = new PerformanceCounter("Process", "% Processor Time", Process.GetCurrentProcess().ProcessName); m_cpuUsage = (int)(theCPUCounter.NextValue() / Environment.ProcessorCount);
public PerformanceCounter( string categoryName, string counterName, string instanceName )
我需要抓的是当前进程的CPU使用率,所以第一个参数用"Process",第二个参数用"% Processor Time",第三个进程则是用当前进程的名称。
利用Process.GetCurrentProcess().ProcessName取得。
只要呼叫PerformanceCounter.NextValue()就可以取得CPU使用率,并透过Enviroment.ProcessorCount来计算。
另外由于我是利用快捷键的方式来显示窗口。所以利用了Hook来拦截按键。
HookManager.Instance.RegisterHook(HookType.WH_KEYBOARD, new CustomHookProc.HookProcHandler(KeyboardHookProc));
void KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam) { KeyStateInfo ctrlKey = KeyboardInfo.GetKeyState(Keys.ControlKey); KeyStateInfo altKey = KeyboardInfo.GetKeyState(Keys.Alt); KeyStateInfo mKey = KeyboardInfo.GetKeyState(Keys.M); if (ctrlKey.IsPressed && altKey.IsPressed && mKey.IsPressed) { showMonitorForm(); } }
HookManager是我自己封装过的一个简易Hook类,只需透过注册事件即可使用。
最后是利用Process.WorkingSet64来取得进程内存。
Process currentProcess = Process.GetCurrentProcess(); currentProcess.WorkingSet64;
以及使用Process.Modules跟ProcessModule.ModuleMemorySize来取得相关DLL的使用内存。
ProcessModuleCollection myProcessModuleCollection = currentProcess.Modules; // Display the 'ModuleMemorySize' of each of the modules. ProcessModule myProcessModule; for (int i = 0; i < myProcessModuleCollection.Count; i++) { myProcessModule = myProcessModuleCollection[i]; if (m_moduleMemorys.Keys.Contains(myProcessModule.ModuleName)) m_moduleMemorys[myProcessModule.ModuleName].update(myProcessModule.ModuleMemorySize); else { MemoryInfo mem = new MemoryInfo(); mem.Name = myProcessModule.ModuleName; mem.update(myProcessModule.ModuleMemorySize); m_moduleMemorys[myProcessModule.ModuleName] = mem; } }
public class MemoryInfo { string m_name; long m_currentUsage; long m_maximumUsage; public long MaximumUsage { get { return m_maximumUsage; } set { m_maximumUsage = value; } } public long CurrentUsage { get { return m_currentUsage; } set { m_currentUsage = value; } } public string Name { get { return m_name; } set { m_name = value; } } public string GetCurrentKB() { return Convert.ToString(m_currentUsage / 1024.0); } public string GetMaximumKB() { return Convert.ToString(m_maximumUsage / 1024.0); } public void update(long current) { m_currentUsage = current; if (m_currentUsage > m_maximumUsage) m_maximumUsage = m_currentUsage; } }
在代码中,声明了一个简单的类,来储存信息。
Name
: 储存 ProcessModule.ModuleName。
CurrentUsage
: 储存现在内存用量。
MaximumUsage
: 储存最大内存用量。