您现在的位置:首页 >> 硬件系统 >> 硬件系统 >> 内容

在Delphi中隐藏程序进程的方法[3]异常结束进程的自动复活法

时间:2011/9/3 15:20:34 点击:

  核心提示:一、问题的产生 我们或多或少都有这样的经历,在Windows上运行的应用程序常常会异常终止,需要通过手工重新将其启动起来。若计算机无人看守,异常终止的进程不能实时启动,则可能给生产造成损失。本人在开发...

一、问题的产生
     我们或多或少都有这样的经历,在Windows上运行的应用程序常常会异常终止,需要通过手工重新将其启动起来。若计算机无人看守,异常终止的进程不能实时启动,则可能给生产造成损失。
本人在开发GPS全球卫星定位系统控制中心程序时,就遇到过控制中心程序异常终止的情况,由此,找出了一个自动复活终止进程的方法,供参考。

二、相关知识
     通常,把一个应用程序的一次运行实例叫做一个进程,在一个进程内又可包含多条可并发执行的路径,每条执行路径叫做一个线程,一个进程至少包含一个主线程。主线程负责执行运行的启动代码。另外,一个进程可以创建若干子进程。当进程被创建时,系统自动产生主线程,主线程然后可创建更多的线程。
我们可以编写一个程序,让其创建、启动子进程,并监视进程的运行情况,在其出现异常终止时,立即重新创建并启动子进程即可。

三、相关函数
1、
创建一个子进程函数:
BOOL    CreateProcess(
   LPCTSTR    lpApplicationName,
   LPTSTR    lpCommandLine,
   LPSECURITY_ATTRIBUTES    lpProcessAttributes,
   LPSECURITY_ATTRIBUTES    lpThreadAttributes,
   BOOL    bInheritHandles,
   DWORD    dwCreationFlags,
   LPVOID    lpEnvironment,
   LPCTSTR    lpCurrentDirectory,
   LPSTARTUPINFO    lpStartupInfo,
   LPPROCESS_INFORMATION    lpProcessInformation
);
参数说明:
lpApplicationName:新进程将要使用的可执行文件的名字,必须包含扩展名。
LpCommandLine:新进程的命令行。若lpApplicationName为NULL,LpCommandLine    的第一个参数是新进程将要使用的可执行文件的名字,可以不包含扩展名,系统假定是exe文件。
LpProcessAttributes和lpThreadAttributes:分别是给进程对象和线程对象指定的安全属性。
BInheritHandles:指定该进程是否继承其父进程中的句柄。
dwCreationFlags:指定新进程产生方式的标志,可用逻辑操作符or相连接。
LpEnvironment:指向含有新进程将要使用的环境块字符串的一块内存,一般为NULL,使子进程继承父进程的一组环境块。
LpCurrentDirectory:设置子进程的当前驱动器和工作目录,    为NULL,子进程继承父进程的当前驱动器和工作目录。
LpStartupInfo:指向STARTUPINFO    的结构。一般让子进程使用缺省值。但要把该结构中的所有成员初始化为0,并设置cb为结构大小。

STARTUPINFO    结构如下:
typedef    struct    _STARTUPINFO    {
   DWORD    cb;
   LPTSTR    lpReserved;
   LPTSTR    lpDesktop;
   LPTSTR    lpTitle;
   DWORD    dwX;
   DWORD    dwY;
   DWORD    dwXSize;
   DWORD    dwYSize;
   DWORD    dwXCountChars;
   DWORD    dwYCountChars;
   DWORD    dwFillAttribute;
   DWORD    dwFlags;
   WORD    wShowWindow;
   WORD    cbReserved2;
   LPBYTE    lpReserved2;
   HANDLE    hStdInput;
   HANDLE    hStdOutput;
   HANDLE    hStdError;
}    STARTUPINFO,    *LPSTARTUPINFO;

lpProcessInformation    参数指向LPPROCESS_INFORMATION结构,CreateProcess在返回之前,填入有关子进程的信息,父进程正是利用该信息监测子进程是否终止。该结构如下:
typedef    struct    _PROCESS_INFORMATION    {
   HANDLE    hProcess;
   HANDLE    hThread;
   DWORD    dwProcessId;
   DWORD    dwThreadId;
}    PROCESS_INFORMATION;

hProcess和hThread分别是子进程的句柄和子进程的主线程的句柄,dwProcessId和dwThreadId分别是子进程的标识号和子进程的主线程的标识号。

2、子进程终止检测函数
GetEXitCodeProcess(HANDLE    hProcess,    LPDWORD    lpExitCode    );
Hprocess:进程句柄,lpExitCode:进程终止时的退出码。
如果一个进程没有终止,lpExitCode    的返回值是STILL_ACTIVE,否则返回其他值。

四、方法的Delphi语言实现

1、创建一个新的项目    Project1
选择File,New    Application。在表单Form1上放一Memo组件,一个OK按钮组件,改变OK按钮组件的Cation属性为    CreateProcess。再放一个timer组件。设置timer组件的Interval值为1000,每秒检查一次进程是否终止。

2、在Unit1    Use节的Type后定义一个过程
procedure    EstablishProcess;
在Unit1    Use节的Var后定义一个变量:
piProcInfoGPS:PROCESS_INFORMATION;

3、在Unit1    implementation节中编写EstablishProcess过程的实现代码如下:
procedure    EstablishProcess;
Var
   siStartupInfo:STARTUPINFO;
   saProcess,saThread:SECURITY_ATTRIBUTES;
   fSuccess:boolean;
begin
   fSuccess:=false;
   ZeroMemory(@siStartupInfo,sizeof(siStartupInfo));
   siStartupInfo.cb:=sizeof(siStartupInfo);
   saProcess.nLength:=sizeof(saProcess);
   saProcess.lpSecurityDescriptor:=PChar(nil);
   saProcess.bInheritHandle:=true;
   saThread.nLength:=sizeof(saThread);
   saThread.lpSecurityDescriptor:=PChar(nil);
   saThread.bInheritHandle:=true;
   fSuccess:=CreateProcess(PChar(nil),'c:\sr350\Sr350buff',@saProcess,@saThread,false,
   CREATE_DEFAULT_ERROR_MODE,Pchar(nil),Pchar(nil),siStartupInfo,piProcInfoGPS);
   if(    not    fSuccess)then
     Form1.Memo1.Lines.Add('Create    Process    Sr350buff    fail.')
   else
     Form1.Memo1.Lines.Add('Create    Process    Sr350buff    success.')
end;
4、在CreateProcess按钮的OnClick事件中调用过程
EstablishProcess;
5、为Timer1的OnTimer事件编写代码:
Procedure    TForm1.Timer1Timer(Sender:    TObject);
Var
   dwExitCode:DWORD;
   fprocessExit:boolean;
Begin
   dwExitCode:=0;
   fprocessExit:=false;
   fprocessExit:=GetExitCodeProcess(piProcInfoGPS.hProcess,dwExitCode);
   if(fprocessExit    and    (dwExitCode<>STILL_ACTIVE))then
   begin
     Memo1.Lines.Add('SR350buff.exe进程终止');
     CloseHandle(piProcInfoGPS.hThread);
     CloseHandle(piProcInfoGPS.hProcess);
     EstablishProcess;
   end;
End;
6、程序中设可执行文件名为c:\sr350\sr350buff.exe,所以c:盘\sr350目录下需有sr350buff.exe文件。
7、编译联接,运行project1,单击CreateProcess可见c:\sr350\sr350buff.exe启动。关掉sr350buff.exe进程,可见sr350buff.exe自动再启动。

作者:网络 来源:转载
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • 盒子文章(www.2ccc.com) © 2022 版权所有 All Rights Reserved.
  • 沪ICP备05001939号