1. 程式人生 > >關機重啟後執行父程序

關機重啟後執行父程序

目的:程序在進行某些操作後需要系統重啟,並且在系統重啟後呼叫原程序的父程序進行某些操作。

 1 BOOL ParentProcessRunonce()
 2 {
 3     DWORD pid = GetCurrentProcessId();
 4     CString strParentPath;
 5     if(!GetParentProcessFileName(pid,strParentPath))   //傳出至strParentPath
 6     {
 7         WRITE_LOG(_T("無法獲取父程序的路徑"));
 8         return FALSE;
9 } 10 11 if(SetRunonce(strParentPath,L"")) 12 { 13 WRITE_LOG(_T("SetRunonce [%s] SUC"),strParentPath); 14 return TRUE; 15 } 16 else 17 { 18 WRITE_LOG(_T("SetRunonce [%s] FAIL"),strParentPath); 19 return FALSE; 20 } 21 }

1.通過當前程序ID獲得父程序ID 

 1 BOOL GetParentProcessFileName( DWORD dwProcessId, CString& szFileName )
 2 {
 3     szFileName.Empty();
 4     HANDLE hProcessSnap = ::CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
 5     if( hProcessSnap == INVALID_HANDLE_VALUE )
 6         return FALSE;
 7 
 8     PROCESSENTRY32 pe32 = { 0
}; 9 pe32.dwSize = sizeof(pe32); 10 BOOL bContinue = ::Process32First( hProcessSnap, &pe32 ); 11 DWORD dwParentProcessId = 0; 12 while( bContinue ) 13 { 14 if( pe32.th32ProcessID == dwProcessId ) 15 { 16 dwParentProcessId = pe32.th32ParentProcessID; 17 break; 18 } 19 20 bContinue = ::Process32Next( hProcessSnap, &pe32 ); 21 } 22 ::CloseHandle( hProcessSnap ); 23 24 return GetProcessFileName( dwParentProcessId, szFileName ); 25 }

 

2.通過父程序ID獲得程序路徑 

 1 BOOL GetProcessFileName( DWORD dwPID, CString& szFileName )
 2 {
 3     szFileName.Empty();
 4     if( dwPID != 0 )
 5     {
 6         HANDLE hProcessParent = ::OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwPID );
 7         if( hProcessParent != NULL )
 8         {
 9             HMODULE hModule = NULL;
10             DWORD dwNeeded = 0;
11             TCHAR szBuff[MAX_PATH] = { 0 };
12             EnumProcessModules( hProcessParent, &hModule, sizeof( hModule ), &dwNeeded );    //獲得指定程序中所有模組的控制代碼
13             GetModuleFileNameEx( hProcessParent, hModule, szBuff, MAX_PATH );
14             szFileName = szBuff;
15             ::CloseHandle( hProcessParent );
16         }    
17     }    
18     return ( szFileName.GetLength() > 0 );
19 }

 

3.將父程序路徑寫入登錄檔(重啟後自動執行父程序)

 1 BOOL SetRunonce( LPCTSTR lpPath, LPCTSTR lpParam )
 2 {
 3     //CRegKey提供了對系統登錄檔的操作方法,通過CRegKey類,可以方便的開啟登錄檔的某個分支或子鍵(CRegKey::Open)
 4     //可以方便的修改一個鍵的鍵值(CRegKey::SetValue),也可以查詢某個鍵的鍵值(CRegKey::QueryValue),操作完成之後,可以關閉子鍵(CRegKey::Close)
 5     CRegKey key;
 6     if (ERROR_SUCCESS == key.Create(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
 7     {
 8         CString strPath = lpPath;
 9 
10         //判斷路徑中是否有空格,有的話,就是用“”引號把整個路徑包含起來
11         PathQuoteSpaces(CStrBuf(strPath, MAX_PATH));
12         CString strParam = lpParam;
13         if (!strParam.IsEmpty())
14         {
15             strPath += _T(" ");
16             strPath += lpParam;
17         }
18         return key.SetStringValue(L"***設定的值的名稱", strPath, REG_SZ) == ERROR_SUCCESS;
19     }
20     else
21     {
22         //HKEY_CURRENT_USER、HKEY_LOCAL_MACHINE代表登錄檔中不同分支
23         if (ERROR_SUCCESS == key.Create(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce"))
24         {
25             CString strPath = lpPath;
26 
27             PathQuoteSpaces(CStrBuf(strPath, MAX_PATH));    
28             CString strParam = lpParam;
29             if (!strParam.IsEmpty())
30             {
31                 strPath += _T(" ");
32                 strPath += lpParam;
33             }
34             return key.SetStringValue(L"***設定的值的名稱", strPath, REG_SZ) == ERROR_SUCCESS;
35         }
36     }
37     return FALSE;
38 }