今天写了个自动升级程序, 该程序从服务器下载客户端最新版本, 然后通过查找客户端进程的方式, 使用TerminateProcess终止进程, 代码如下:
void KillProcess( CString strProName )
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
return;
CString str;
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
CString strProcessName = _T("");
strProName.MakeUpper();
while(bMore)
{
bMore = ::Process32Next(hProcessSnap, &pe32);
strProcessName = pe32.szExeFile;
strProcessName.MakeUpper();
if(strProcessName.Find( strProName ) != -1)
{
HANDLE hdl = OpenProcess(PROCESS_ALL_ACCESS,TRUE,pe32.th32ProcessID);
TerminateProcess(hdl,0);
::CloseHandle(hProcessSnap);
return;
}
}
::CloseHandle(hProcessSnap);
}
在win7上面正常, 但是在xp系统上,却发现,升级程序终止客户端进程失败,跟踪了下代码,发现执行
<span style="font-size:32px;">OpenProcess(PROCESS_ALL_ACCESS,TRUE,pe32.th32ProcessID)</span>
失败, 错误码 5,拒绝访问,
后来上网查询了一番,终于发现是因为权限问题,并找到一段代码
BOOL EnableDebugPrivilege()
{
HANDLE hToken;
BOOL fOk=FALSE;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount=1;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tp.Privileges[0].Luid);
tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),NULL,NULL);
fOk=(GetLastError()==ERROR_SUCCESS);
CloseHandle(hToken);
}
return fOk;
}
经测试,一切ok。
现在贴出完整代码:
void KillProcess( CString strProName )
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap == INVALID_HANDLE_VALUE)
return;
CString str;
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
CString strProcessName = _T("");
strProName.MakeUpper();
while(bMore)
{
bMore = ::Process32Next(hProcessSnap, &pe32);
strProcessName = pe32.szExeFile;
strProcessName.MakeUpper();
if(strProcessName.Find( strProName ) != -1)
{
HANDLE hdl = OpenProcess(PROCESS_ALL_ACCESS,TRUE,pe32.th32ProcessID);
if ( !hdl )
{
EnableDebugPrivilege();
hdl = OpenProcess(PROCESS_ALL_ACCESS,TRUE,pe32.th32ProcessID);
}
TerminateProcess(hdl,0);
::CloseHandle(hProcessSnap);
return;
}
}
::CloseHandle(hProcessSnap);
}