最近在写一个进程监控管理的程序,需求是这样的:在后台监控一个名字为links.exe的进程,由于此进程会出现不定期的挂起(无响应),但有没有任何消息提示,要求写一个的程序,在后台时刻监视着links.exe进程的状态,如果发现挂起,则强制将其结束,然后重新启动一个挂掉的进程(要求参数一致)。
难点:由于这样的进程有多个,且其带的参数不同。如:
links.exe a
links.exe b
links.exe c
上述是命令行形式显示。这个我后来才知道。
此进程对应的应用程序的标题名分别是:
links.exe[a]
links.exe[b]
links.exe[c]
这样看起来很容易区分,但是在任务管理器中的查看他们的进程名是完全相同的。
links.exe
links.exe
links.exe
在代码中怎么区分呢,我首先想到了PID,是的,PID是可以区分不同的进程,但是,问题又来了,
每个PID所对应的进程名字是一样的,如果,我发现PID==5080的进程挂起了,结束掉很容易,通过对应的handle就可以,
那接下来,我要重新启动一个这样的进程,要求参数一致,怎么启动呢?
用creatProcess()创建一个新进程时,
CreateProcess (NULL, // No module name (use command line)
commandline, // Command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi // Pointer to PROCESS_INFORMATION structure
);
其第二个参数commandline表示命令行参数,(如果传递了CommandLine参数,且ApplicationName参数是NULL,那么CreateProcess会尝试从CommandLine中提取ApplicationName。具体参考:http://www.programlife.net/createprocess-command-line.html)
commandline可以是这样的形式:C:\Links:\links.exe a
其中,C:\Links:\links.exe为进程links.exe的路径;
a为参数;
如果,我们不知道参数的名字a,仅仅知道进程的名字links.exe,怎么能够重新启动想要的进程呢。
因此,必须要获得进程所带的参数。
获得进程所带参数可用CreateRemoteThread()和ReadProcessMemory()。
具体实现代码如下:
----------------------------------------------------------------------
int WINAPI GetProcessCommandLine(DWORD dwPID, HANDLE hProcess, LPTSTR lpszCommandLine, DWORD dwByteOfSize)
{
DWORD dwThreadId = 0;
DWORD dwExitCode = 0;
DWORD dwReaded = 0;
HANDLE hThread = ::CreateRemoteThread(hProcess, NULL, NULL, (LPTHREAD_START_ROUTINE)
GetCommandLine, NULL, 0, &dwThreadId);
if (hThread)
{
::WaitForSingleObject(hThread, INFINITE);
::GetExitCodeThread(hThread, &dwExitCode);
::ReadProcessMemory(hProcess, (LPCVOID)dwExitCode, lpszCommandLine,
dwByteOfSize, &dwReaded);
}
return dwReaded;
}
int
_tmain(
int
argc, _TCHAR* argv[])
{
HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, processID ); //根据PID获取进程的handle
TCHAR
szBuffer[256] = {0};
GetProcessCommandLine(processID , hProcess, szBuffer,
sizeof
(szBuffer));
return
0;
}
具体可参考:http://bbs.csdn.net/topics/380196754?page=1#post-397206631
==============================================================
另,在cmd中查看正在运行的进程的参数的方法如下:
(1)查看所有运行中进程的命令行参数:
在cmd中输入:
wmic process get caption,commandline /value
(2)查询指定进程的命令行参数:
在cmd中输入:
wmic process where caption="links.exe" get caption,commandline /value
================================================================
cmd中启动一个进程的方法(打开一个应用程序):
cmd 里面输入:
call D:\QQ files\QQ
或
start D:\QQ files\QQ
均可调用该应用程序!