異常死亡程式的自動復活 (轉)
異常死亡程式的自動復活 (轉)[@more@]
異常死亡程式的自動復活
一、問題的產生
我們或多或少都有這樣的經歷,在上執行的應用常常會異常終止,需要透過手工重新將其啟動起來。若無人看守,異常終止的程式不能實時啟動,則可能給生產造成損失。
本人在開發GPS全球衛星定位控制中心程式時,就遇到過控制中心程式異常終止死亡的情況,由此,找出了一個自動復活死亡程式的方法,供參考。
二、相關知識
通常,把一個應用程式的一次執行例項叫做一個程式,在一個程式內又可包含多條可併發的路徑,每條執行路徑叫做一個執行緒,一個程式至少包含一個主執行緒。主執行緒負責執行執行的啟動程式碼。另外,一個程式可以建立若干子程式。當程式被建立時,系統自動產生主執行緒,主執行緒然後可建立更多的執行緒。
我們可以編寫一個程式,讓其建立、啟動子程式,並監視程式的執行情況,在其出現異常終止時,立即重新建立並啟動子程式即可。
三、相關
1、建立一個子程式函式:
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
D 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,否則返回其他值。
四、方法的5語言實現
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:sr350Sr350buff',@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: T);
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:sr350sr350buff.exe,所以c:盤sr350目錄下需有sr350buff.exe檔案。
7、編譯聯接,執行project1,單擊CreateProcess可見c:sr350sr350buff.exe啟動。關掉sr350buff.exe程式,可見sr350buff.exe自動再啟動。
異常死亡程式的自動復活
一、問題的產生
我們或多或少都有這樣的經歷,在上執行的應用常常會異常終止,需要透過手工重新將其啟動起來。若無人看守,異常終止的程式不能實時啟動,則可能給生產造成損失。
本人在開發GPS全球衛星定位控制中心程式時,就遇到過控制中心程式異常終止死亡的情況,由此,找出了一個自動復活死亡程式的方法,供參考。
二、相關知識
通常,把一個應用程式的一次執行例項叫做一個程式,在一個程式內又可包含多條可併發的路徑,每條執行路徑叫做一個執行緒,一個程式至少包含一個主執行緒。主執行緒負責執行執行的啟動程式碼。另外,一個程式可以建立若干子程式。當程式被建立時,系統自動產生主執行緒,主執行緒然後可建立更多的執行緒。
我們可以編寫一個程式,讓其建立、啟動子程式,並監視程式的執行情況,在其出現異常終止時,立即重新建立並啟動子程式即可。
三、相關
1、建立一個子程式函式:
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
D 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,否則返回其他值。
四、方法的5語言實現
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:sr350Sr350buff',@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: T);
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:sr350sr350buff.exe,所以c:盤sr350目錄下需有sr350buff.exe檔案。
7、編譯聯接,執行project1,單擊CreateProcess可見c:sr350sr350buff.exe啟動。關掉sr350buff.exe程式,可見sr350buff.exe自動再啟動。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10796304/viewspace-952182/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 任務異常自動告警
- Spring 自動注入失敗異常Spring
- AI賦能一鍵自動檢測:頁面異常、控制元件異常、文字異常AI控制元件
- Supervisor多程式管理 異常自動重啟 視覺化管理視覺化
- 聊聊springboot自動裝配出現的TypeNotPresentExceptionProxy異常排查Spring BootException
- 擷取Spring框架自動丟擲異常Spring框架
- 2018, 自動駕駛異常艱難的一年自動駕駛
- SQLServer異常故障恢復(二)SQLServer
- DG同步異常恢復文件
- Cacheable 類轉換異常
- python自動化測試之異常及日誌Python
- dns異常怎麼修復 dns配置異常怎麼處理DNS
- WPS異常關閉怎麼恢復檔案?Wps文件儲存及自動儲存方法
- Python監控線上異常圖片地址自動告警Python
- 策略,讓我在《死亡細胞》裡死去活來的動力
- JAVA: 捕捉啟動時的異常Java
- 異常-異常的注意事項
- 7_Oracle truncate異常恢復之plsql修復OracleSQL
- 6_Oracle truncate異常恢復之bbed修復Oracle
- 自動化時序異常檢測的可擴充套件通用框架套件框架
- 巧用Grafana和Arthas自動抓取K8S中異常Java程式的執行緒堆疊GrafanaK8SJava執行緒
- Oracle asm磁碟損壞異常恢復OracleASM
- 關注程式異常流
- MongoDB Java開發從Mongo讀取Object值轉Long異常引起的資料型別轉換異常MongoDBJavaObject資料型別
- 異常-異常的概述和分類
- 異常-throws的方式處理異常
- dns解析狀態異常怎麼處理 dns解析異常怎麼修復DNS
- win10無線網路卡驅動異常怎麼修復_win10無線網路卡驅動異常解決方法Win10
- 異常-編譯期異常和執行期異常的區別編譯
- 兩種異常(CPU異常、使用者模擬異常)的收集
- 路由器dns異常怎麼修復 路由器正常上網dns異常路由器DNS
- 小程式異常監控收集
- 程式執行異常: Modulo by zero
- [轉載] Java異常處理習題Java
- 執行程式時,程式返回TooManyResultsException異常行程OOMException
- 【PARANETERS】Oracle異常恢復相關的隱含引數Oracle
- React Native Android 啟動異常React NativeAndroid
- oracle主動丟擲異常Oracle
- DG修復:異常關庫導致的資料庫啟動失敗ORA-01110及GAP修復資料庫