这篇文章将介绍一个自制的简易插件。
因为在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
: 储存最大内存用量。