监测程序详细介绍,源代码
在编写这个软件的过程中遇到很多问题,发现网上也有很多人一样也遇到这些问题。
如:1快捷键的设置;
2 往txt文件里面一行行的读取、删除、添加字符串等;
3 根据程序路径名以及程序名判断程序是否在运行;
等等。。。。。。
所以整理一下发上来分享一下。
本程序采用的环境为VS2008
新建基于对话框的过程 工程名为:MonitorProcess
说明:本程序默认启动为隐藏。按Ctrl+S 弹出对话框。选择添加程序路径名,然后添加,添加之后需要点击下拉列表选择,然后点击启动监测。
默认每4s监测一次。如果被监测的程序未启动,则将其启动,若已经启动,则会弹出提示对话框(可以自己取消对话框)
在cpp文件中添加如下2句
// MonitorProcessDlg.cpp : 实现文件
#include "Psapi.h"
#pragma comment(lib,"psapi.lib")
下面是热键的设置代码:
手动添加注册消息WM_SHOWTASK
在cpp文件中添加
#define WM_SHOWTASK (WM_USER +1)
然后在
BEGIN_MESSAGE_MAP(CMonitorProcessDlg, CDialog)
ON_MESSAGE(WM_SHOWTASK,OnShowTask) 添加这一句。
END_MESSAGE_MAP()
最后在头文件中添加
afx_msg LRESULT OnShowTask(WPARAM wParam,LPARAM lParam) ;
即可。
手动添加消息的处理代码如下:
自定义消息
LRESULT CMonitorProcessDlg::OnShowTask(WPARAM wParam,LPARAM lParam)
{
if(wParam!=IDR_MAINFRAME) //图标ID
return 1;
switch(lParam)
{
case WM_RBUTTONUP://右键起来时弹出快捷菜单,这里只有一个“退出”
{
LPPOINT lpoint=new tagPOINT;
::GetCursorPos(lpoint);//得到鼠标位置
CMenu menu;
menu.CreatePopupMenu();//声明一个弹出式菜单
//增加菜单项“退出”,点击则发送消息WM_DESTROY给主窗口将程序结束。
menu.AppendMenu(MF_STRING,WM_DESTROY,"退出");
//确定弹出式菜单的位置
menu.TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
//资源回收
HMENU hmenu=menu.Detach();
menu.DestroyMenu();
delete lpoint;
DeleteTray();
KillProcess(pName);
}
break;
case WM_LBUTTONDBLCLK://双击左键的处理
{
this->ShowWindow(SW_SHOW);//显示主窗口
DeleteTray();
}
break;
default:
break;
}
return 0;
}
/托盘绘制图标
void CMonitorProcessDlg::ToTray(void)
{
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this-> m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(nid.szTip, "MonitorProcess");//信息提示条
Shell_NotifyIcon(NIM_ADD,&nid);//在托盘区添加图标
ShowWindow(SW_HIDE);//隐藏主窗口
}
删除托盘图标
void CMonitorProcessDlg::DeleteTray(void)
{
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
nid.uCallbackMessage=WM_SHOWTASK;//自定义的消息名称
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
strcpy(nid.szTip,"MonitorProcess"); //信息提示条
Shell_NotifyIcon(NIM_DELETE,&nid); //在托盘区删除图标
}
再添加消息WM_HOTKEY 响应函数 OnHotKey
///快捷键
int i = 0;//用于联合判断热键的按下状态
void CMonitorProcessDlg::OnHotKey(UINT nHotKeyId, UINT nKey1, UINT nKey2)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (i==0 && nHotKeyId == 918)
{
i++;
this->ShowWindow(SW_SHOW);//显示主窗口
DeleteTray();
}
else if (i==1 && nHotKeyId == 918)
{
i--;
ToTray();
//OnShowTask(IDR_MAINFRAME,lParam);
}
CDialog::OnHotKey(nHotKeyId, nKey1, nKey2);
}
然后再OnInitDialog()函数里面添加如下代码:
::RegisterHotKey(m_hWnd,918,MOD_CONTROL,'S');
注册热键。
再添加,对文件进行处理的代码:
此处是一行行的读取txt文档里面的字符串
CStdioFile myFile;
CString oneLine;
if(!myFile.Open(("path.txt"),CFile::modeRead | CFile::typeText))
{
AfxMessageBox(_T("打开文件错误!"));
return FALSE;
}
else
{
//do nothing
}
while (myFile.ReadString(oneLine))
{
m_ctrlPathName.AddString(oneLine);
}
myFile.Close();
return TRUE; // 除非将焦点设置到控件,否则返回TRUE
下面为对话框的界面:
下拉列表 ID:IDC_LIST_PATHNAME
并为其添加相应的变量 CComoBox类型的m_ctrlPathName
以及CString类型的m_strPathName
并添加相应的事件处理程序,OnCbnSelchangeListPathname()
添加代码:
void CMonitorProcessDlg::OnCbnSelchangeListPathname()
{
// TODO: 在此添加控件通知处理程序代码
int j=0;
j = m_ctrlPathName.GetCurSel();
m_ctrlPathName.GetLBText(j,m_strPathName);
}
“添加”按钮
ID:ID_BUTTON_ADD
事件处理程序,OnBnAdd()
//添加程序路径名
void CMonitorProcessDlg::OnBnAdd()
{
// TODO: 在此添加控件通知处理程序代码
//将编辑框中的内容写入m_strPathName中
char chTemp[100];
GetDlgItem(IDC_LIST_PATHNAME)->GetWindowText(chTemp,100);
m_strPathName.Format("%s",chTemp);
//添加到LIST中
m_ctrlPathName.AddString(m_strPathName);
//写入txt文档中
int nCount = m_ctrlPathName.GetCount();
for (int n=0;n { m_ctrlPathName.GetLBText(n,m_strPathName); if (n==1) { ReWriteString(m_strPathName); } else { WriteString(m_strPathName); } } } 函数ReWriteString以及WriteString 代码: 往txt文档里面一行行的添加字符串 //覆盖 void CMonitorProcessDlg::ReWriteString(CString strTemp) { CStdioFile myFile; myFile.Open( "path.txt ", CFile::modeCreate | CFile::modeWrite); myFile.SeekToEnd(); strTemp.Insert(0,"\n"); myFile.WriteString(strTemp) ; myFile.Close() ; } //不覆盖 void CMonitorProcessDlg::WriteString(CString strTemp) { CStdioFile myFile; myFile.Open( "path.txt ",CFile::modeWrite); myFile.SeekToEnd(); strTemp.Insert(0,"\n"); myFile.WriteString(strTemp) ; myFile.Close() ; } “删除”按钮的处理 ID:ID_BUTTON_DELETE 事件处理函数:OnBnDelete() 代码: //删除程序路径名 void CMonitorProcessDlg::OnBnDelete() { // TODO: 在此添加控件通知处理程序代码 //删除选定的行 int nIndex = m_ctrlPathName.GetCurSel(); m_ctrlPathName.DeleteString(nIndex); //将txt文档重写 int nCount = m_ctrlPathName.GetCount(); for (int n=0;n { m_ctrlPathName.GetLBText(n,m_strPathName); if (n==1) { ReWriteString(m_strPathName); } else { WriteString(m_strPathName); } } } “启动”按钮处理 ID:ID_BUTTON_START 函数:OnBnClickedButtonStart() 代码: int KillProcess( LPCSTR pszWindowTitle) { HANDLE hProcessHandle; ULONG nProcessID; HWND TheWindow; TheWindow = ::FindWindow( NULL, pszWindowTitle ); ::GetWindowThreadProcessId( TheWindow, &nProcessID ); hProcessHandle =::OpenProcess( PROCESS_TERMINATE,FALSE, nProcessID ); return ::TerminateProcess( hProcessHandle, 4 ); } LPCSTR pName("MonitorProcess"); 启动 BOOL bStatic; //用于判断程序是否在执行,以便暂停 void CMonitorProcessDlg::OnBnClickedButtonStart() { // TODO: 在此添加控件通知处理程序代码 //添加定时器 SetTimer(1,3888,NULL); bStatic = TRUE; //读取命令行参数 LPTSTR lpstr=AfxGetApp()->m_lpCmdLine; this->ShowWindow(SW_HIDE); //读取路径以及文件名 CString strCmdLine; strCmdLine = m_strPathName; int iStartIndex=1; int iEndIndex=0; CString cCurrentDir=""; CString strTempName=""; iEndIndex=strCmdLine.Find("-",iStartIndex); cCurrentDir=strCmdLine.Mid(iStartIndex,iEndIndex-iStartIndex-1); iStartIndex=iEndIndex+1; strTempName=strCmdLine.Mid(iStartIndex,strCmdLine.GetLength()-iStartIndex); //BOOL Temp = IsAbort((char*)(LPCTSTR)strTempName); LPCSTR pName("MonitorProcess"); if (strlen(strCmdLine) == 0 ) { AfxMessageBox("未输入有效的路径名!"); //KillProcess(pName); bStatic = FALSE; return; } else { //do nothing } HANDLE hYourTargetProcess = OpenProcess(PROCESS_QUERY_INFORMATION | // Required by Alpha PROCESS_CREATE_THREAD | // For CreateRemoteThread PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx PROCESS_TERMINATE | PROCESS_VM_WRITE, // For WriteProcessMemory FALSE, FindProcess((char*)(LPCTSTR)m_strPathName)); //程序已经在执行 if(hYourTargetProcess == NULL) { //如果中断重新启动 ShellExecute(NULL, "open", strTempName , "", cCurrentDir, SW_SHOWNORMAL); //KillProcess(pName); } else { AfxMessageBox("程序正在运行中! 或者输入有误!"); //KillProcess(pName); } return; } FindProcess函数代码: DWORD CMonitorProcessDlg::FindProcess(char* chProcess) { DWORD aProcesses[1024], cbNeeded, cbMNeeded; HMODULE hMods[1024]; HANDLE hProcess; char szProcessName[MAX_PATH]; if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) { return 0; } else { //do nothing } for(int i=0; i < (int) (cbNeeded / sizeof(DWORD)); i++) { hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcesses[i]); EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbMNeeded); GetModuleFileNameEx( hProcess, hMods[0], szProcessName,sizeof(szProcessName)); if(strstr(szProcessName, chProcess)) { return(aProcesses[i]); } else { //do nothing } } return 0; } “暂停”按钮处理 ID:ID_BUTTON_STOP 函数:OnBnStop() 代码: void CMonitorProcessDlg::OnBnStop() { // TODO: 在此添加控件通知处理程序代码 bStatic = FALSE; } “退出”按钮直接将确认按钮或者取消按钮 重新命名为 退出即可