作者:小 琛
欢迎转载,请标明出处
判断进程是否存在
这里给出一个封装好的函数,可以根据传入的进程名来判断操作系统下是否有该进程
bool isProcessRun(const char* pName) {
if (pName == nullptr || pName == "") {
return false;
}
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
bool bFind = false;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
return false;
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32)) {
CloseHandle(hProcessSnap);
return false;
}
// walk the snapshot of processes
do {
int num = WideCharToMultiByte(CP_OEMCP, NULL, pe32.szExeFile,
-1, NULL, 0, NULL, FALSE);
char* pchar = new char[num];
WideCharToMultiByte(CP_OEMCP, NULL, pe32.szExeFile, -1,
pchar, num, NULL, FALSE);
if (::strstr(pchar, pName) != NULL) {
bFind = true;
break;
}
} while (Process32Next(hProcessSnap, &pe32));
CloseHandle(hProcessSnap);
return bFind;
}
根据进程名拿pid
这里同样给出一个封装好的函数,参数为宽字符的name,主要是为了支持中文,若希望传入的是char*,可进行转换,下面例子中,m_processName是一个string,若本身为char*直接放入
int num = MultiByteToWideChar(0, 0, m_processName…c_str(), -1, NULL, 0);
wchar_t* processName = new wchar_t[num];
MultiByteToWideChar(0, 0, m_processName.toStdString().c_str(), -1, processName, num);
DWORD getProcessIDByName(const wchar_t* name) {
DWORD id = 0;
HANDLE hSnapshot = INVALID_HANDLE_VALUE;
try {
PROCESSENTRY32 pe = { 0 };
pe.dwSize = sizeof(PROCESSENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
if (INVALID_HANDLE_VALUE == hSnapshot) {
throw 0;
}
if (!Process32First(hSnapshot, &pe)) {
throw 0;
}
do {
if (wcscmp(pe.szExeFile, name) == 0) {
id = pe.th32ProcessID;
break;
}
} while (Process32Next(hSnapshot, &pe));
if (INVALID_HANDLE_VALUE != hSnapshot) {
CloseHandle(hSnapshot);
hSnapshot = INVALID_HANDLE_VALUE;
}
}
catch (...) {
if (INVALID_HANDLE_VALUE != hSnapshot) {
CloseHandle(hSnapshot);
hSnapshot = INVALID_HANDLE_VALUE;
}
id = 0;
}
return id;
}
根据进程pid拿句柄
这里比较简单,不做多的阐述
HANDLE getProcessHandleByID(int nID) {
return OpenProcess(PROCESS_ALL_ACCESS, FALSE, nID);
}
根据pid强杀进程
bool killProcessByID(DWORD ProcessId) {
if (ProcessId != 0) {
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, ProcessId);
if (hProcess == NULL)
return false;
if (!TerminateProcess(hProcess, 0))
return false;
return true;
}
return false;
}
启动进程
启动进程的常用方法
这里给出一个简单的例子,和一个可以用在Qt下的封装好的函数
SHELLEXECUTEINFO ShExecInfo;
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = L"runas";
ShExecInfo.lpFile = processName;
if (m_isSilent == true) {
ShExecInfo.lpParameters = L"/S";
} else {
ShExecInfo.lpParameters = NULL;
}
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;
bool ret = ShellExecuteEx(&ShExecInfo);
DWORD runAsAdminSync(const QString& path, const QStringList& arguments, int showCmd) {
QString args = arguments.join(' ');
SHELLEXECUTEINFO ShExecInfo;
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = L"runas";
ShExecInfo.lpFile = reinterpret_cast<LPCWSTR>(path.utf16());
ShExecInfo.lpParameters = reinterpret_cast<LPCWSTR>(args.utf16());
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = showCmd;
ShExecInfo.hInstApp = NULL;
bool ret = ShellExecuteEx(&ShExecInfo);
if (!ret) {
const auto exitCode = GetLastError();
return exitCode;
}
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
DWORD dwCode = 0;
GetExitCodeProcess(ShExecInfo.hProcess, &dwCode);
CloseHandle(ShExecInfo.hProcess);
return dwCode;
}
获取进程状态、阻塞等待进程
- WaitForSingleObject函数会阻塞等待目标进程,一个参数为进程句柄;第二个等待时间,INFINITE为永远等待,若设置为数值,单位为毫秒
- GetExitCodeProcess为得到目标进程的退出值
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
DWORD dwCode = 0;
GetExitCodeProcess(ShExecInfo.hProcess, &dwCode);