关机重启后运行父进程

目的:进程在进行某些操作后需要系统重启,并且在系统重启后调用原进程的父进程进行某些操作。

 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 }

 

posted on 2018-12-14 12:21  Noora&w  阅读(269)  评论(0编辑  收藏  举报