<br>异常死亡进程的自动复活<br><br>一、问题的产生 <br>我们或多或少都有这样的经历,在Windows上运行的应用程序常常会异常终止,需要通过手工重新将其启动起来。若计算机无人看守,异常终止的进程不能实时启动,则可能给生产造成损失。 <br>本人在开发GPS全球卫星定位系统控制中心程序时,就遇到过控制中心程序异常终止死亡的情况,由此,找出了一个自动复活死亡进程的方法,供参考。 <br>二、相关知识 <br>通常,把一个应用程序的一次运行实例叫做一个进程,在一个进程内又可包含多条可并发执行的路径,每条执行路径叫做一个线程,一个进程至少包含一个主线程。主线程负责执行运行的启动代码。另外,一个进程可以创建若干子进程。当进程被创建时,系统自动产生主线程,主线程然后可创建更多的线程。 <br>我们可以编写一个程序,让其创建、启动子进程,并监视进程的运行情况,在其出现异常终止时,立即重新创建并启动子进程即可。 <br>三、相关函数 <br>1、创建一个子进程函数: <br>BOOL CreateProcess( <br>LPCTSTR lpApplicationName, <br>LPTSTR lpCommandLine, <br>LPSECURITY_ATTRIBUTES lpProcessAttributes, <br>LPSECURITY_ATTRIBUTES lpThreadAttributes, <br>BOOL bInheritHandles, <br>DWORD dwCreationFlags, <br>LPVOID lpEnvironment, <br>LPCTSTR lpCurrentDirectory, <br>LPSTARTUPINFO lpStartupInfo, <br>LPPROCESS_INFORMATION lpProcessInformation <br>); <br>参数说明: <br>lpApplicationName:新进程将要使用的可执行文件的名字,必须包含扩展名。 <br>LpCommandLine:新进程的命令行。若lpApplicationName为NULL,LpCommandLine 的第一个参数是新进程将要使用的可执行文件的名字,可以不包含扩展名,系统假定是exe文件。 <br>LpProcessAttributes和lpThreadAttributes:分别是给进程对象和线程对象指定的安全属性。 <br>BInheritHandles:指定该进程是否继承其父进程中的句柄。 <br>dwCreationFlags:指定新进程产生方式的标志,可用逻辑操作符or相连接。 <br>LpEnvironment:指向含有新进程将要使用的环境块字符串的一块内存,一般为NULL,使子进程继承父进程的一组环境块。 <br>LpCurrentDirectory:设置子进程的当前驱动器和工作目录, 为NULL,子进程继承父进程的当前驱动器和工作目录。 <br>LpStartupInfo:指向STARTUPINFO 的结构。一般让子进程使用缺省值。但要把该结构中的所有成员初始化为0,并设置cb为结构大小。 <br>STARTUPINFO 结构如下: <br>typedef struct _STARTUPINFO { <br>DWORD cb; <br>LPTSTR lpReserved; <br>LPTSTR lpDesktop; <br>LPTSTR lpTitle; <br>DWORD dwX; <br>DWORD dwY; <br>DWORD dwXSize; <br>DWORD dwYSize; <br>DWORD dwXCountChars; <br>DWORD dwYCountChars; <br>DWORD dwFillAttribute; <br>DWORD dwFlags; <br>WORD wShowWindow; <br>WORD cbReserved2; <br>LPBYTE lpReserved2; <br>HANDLE hStdInput; <br>HANDLE hStdOutput; <br>HANDLE hStdError; <br>} STARTUPINFO, *LPSTARTUPINFO; <br>lpProcessInformation 参数指向LPPROCESS_INFORMATION结构,CreateProcess在返回之前,填入有关子进程的信息,父进程正是利用该信息监测子进程是否终止。该结构如下: <br>typedef struct _PROCESS_INFORMATION { <br>HANDLE hProcess; <br>HANDLE hThread; <br>DWORD dwProcessId; <br>DWORD dwThreadId; <br>} PROCESS_INFORMATION; <br>hProcess和hThread分别是子进程的句柄和子进程的主线程的句柄,dwProcessId和dwThreadId分别是子进程的标识号和子进程的主线程的标识号。 <br>2、子进程终止检测函数 <br>GetEXitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode ); <br>Hprocess:进程句柄,lpExitCode:进程终止时的退出码。 <br>如果一个进程没有终止,lpExitCode 的返回值是STILL_ACTIVE,否则返回其他值。 <br>四、方法的Delphi5语言实现 <br>1、创建一个新的项目 Project1 <br>选择File,New Application。在表单Form1上放一Memo组件,一个OK按钮组件,改变OK按钮组件的Cation属性为 CreateProcess。再放一个timer组件。设置timer组件的Interval值为1000,每秒检查一次进程是否终止。 <br>2、在Unit1 Use节的Type后定义一个过程 <br>procedure EstablishProcess; <br>在Unit1 Use节的Var后定义一个变量: <br>piProcInfoGPS
ROCESS_INFORMATION; <br>3、在Unit1 implementation节中编写EstablishProcess过程的实现代码如下: <br>procedure EstablishProcess; <br>Var <br>siStartupInfo:STARTUPINFO; <br>saProcess,saThread:SECURITY_ATTRIBUTES; <br>fSuccess:boolean; <br>begin <br>fSuccess:=false; <br>ZeroMemory(@siStartupInfo,sizeof(siStartupInfo)); <br>siStartupInfo.cb:=sizeof(siStartupInfo); <br>saProcess.nLength:=sizeof(saProcess); <br>saProcess.lpSecurityDescriptor:=PChar(nil); <br>saProcess.bInheritHandle:=true; <br>saThread.nLength:=sizeof(saThread); <br>saThread.lpSecurityDescriptor:=PChar(nil); <br>saThread.bInheritHandle:=true; <br>fSuccess:=CreateProcess(PChar(nil),'c:/sr350/Sr350buff',@saProcess,@saThread,false, <br>CREATE_DEFAULT_ERROR_MODE,Pchar(nil),Pchar(nil),siStartupInfo,piProcInfoGPS); <br>if( not fSuccess)then <br>Form1.Memo1.Lines.Add('Create Process Sr350buff fail.') <br>else <br>Form1.Memo1.Lines.Add('Create Process Sr350buff success.') <br>end; <br>4、在CreateProcess按钮的OnClick事件中调用过程 <br>EstablishProcess; <br>5、为Timer1的OnTimer事件编写代码: <br>Procedure TForm1.Timer1Timer(Sender: TObject); <br>Var <br>dwExitCode
WORD; <br>fprocessExit:boolean; <br>Begin <br>? <br>dwExitCode:=0; <br>fprocessExit:=false; <br>fprocessExit:=GetExitCodeProcess(piProcInfoGPS.hProcess,dwExitCode); <br>if(fprocessExit and (dwExitCode<>STILL_ACTIVE))then <br>begin <br>Memo1.Lines.Add('SR350buff.exe进程终止'); <br>CloseHandle(piProcInfoGPS.hThread); <br>CloseHandle(piProcInfoGPS.hProcess); <br>EstablishProcess; <br>end; <br>End; <br>6、程序中设可执行文件名为c:/sr350/sr350buff.exe,所以c:盘/sr350目录下需有sr350buff.exe文件。 <br>7、编译联接,运行project1,单击CreateProcess可见c:/sr350/sr350buff.exe启动。关掉sr350buff.exe进程,可见sr350buff.exe自动再启动。 <br><br>