目的:进程在进行某些操作后需要系统重启,并且在系统重启后调用原进程的父进程进行某些操作。
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 }