关闭使用ShellExecute打开的进程
最近做一个项目使用到ShellExecute来打开一个带参数的外部exe文件,关闭时遇到不少问题,最终解决,总结如下。
对于关闭ShellExecute打开的进程窗口,网上比较多的是用FindWindow方式,可惜我也不知道这窗口的名称。通过查询资料找到以下方式可以关闭进程:
// lpProcessName为打开的进程名称 带文件类型后缀 如:****.exe
void CloseProcess(LPCTSTR lpProcessName);
{
DWORD dwQQID = GetProcessID(lpProcessName);
HANDLE hProecss = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwQQID); //打开进程
if(hProecss)
{
TerminateProcess(hProecss, 0); //关闭进程
}
CloseHandle(hProecss);
}
// 遍历进程,得到进程ID
DWORD GetProcessID(LPCTSTR lpProcessName)
{
//创建进程快照
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnapshot != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe32 = {0};
pe32.dwSize = sizeof(pe32);
// 拿到第一个进程信息
if(!Process32First(hSnapshot, &pe32))
{
CloseHandle(hSnapshot);
return FALSE;
}
do
{
int nLen = _tcslen(lpProcessName);
int nLen2 = _tcslen(pe32.szExeFile);
if(nLen != nLen2)
{
continue;
}
//if(_tcscmp(lower(lpProcessName), lower(pe32.szExeFile)) == 0)
if(_tcscmp(lpProcessName, pe32.szExeFile) == 0)
{
return pe32.th32ProcessID;
}
} while (Process32Next(hSnapshot, &pe32));
}
return 0;
}
后来应用时发现在Win7系统关闭exe进程没有问题,但在winXP系统时关闭进程失败。
经测试是调用OpenProcess()返回0,GetLastError()返回的错误代码为5,表示访问拒绝,权限不够!
BOOL ProcessPrivilege(BOOL bEnable)
{
BOOL bResult = TRUE;
HANDLE hToken=INVALID_HANDLE_VALUE;
TOKEN_PRIVILEGES TokenPrivileges;
if(OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
&hToken) == 0)
{
printf("OpenProcessToken Error: %d\n",GetLastError());
bResult = FALSE;
}
TokenPrivileges.PrivilegeCount = 1;
TokenPrivileges.Privileges[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0;
LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&TokenPrivileges.Privileges[0].Luid);
AdjustTokenPrivileges(hToken,FALSE,&TokenPrivileges,sizeof(TOKEN_PRIVILEGES),NULL,NULL);
if(GetLastError() != ERROR_SUCCESS)
{
bResult = FALSE;
}
CloseHandle(hToken);
return bResult;
}
在CloseProcess()函数的第一行加入ProcessPrivilege(TRUE),关闭成功!