监测程序详细介绍,源代码
在编写这个软件的过程中遇到很多问题,发现网上也有很多人一样也遇到这些问题。
如: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<nCount;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<nCount;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;
}
“退出”按钮直接将确认按钮或者取消按钮 重新命名为 退出即可