1 说明
Windows环境
- 此处进程名是指进程可执行文件的名称(任务管理器进程列表中显示的映像名称),如
notepad.exe
。 - Windows中没有直接可用的相关函数,实现思路为使用
CreateToolhelp32Snapshot
函数创建进程或线程快照然后从中逐个比较。 - 需要包含头文件
#include <tlhelp32.h>
- win7下测试
2 实现
获取进程ID
// 由进程名获取进程ID(需要头文件tlhelp32.h)
// 失败返回0
DWORD GetProcessIDFromName(LPCSTR szName)
{
DWORD id = 0; // 进程ID
PROCESSENTRY32 pe; // 进程信息
pe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 获取系统进程列表
if(Process32First(hSnapshot, &pe)) // 返回系统中第一个进程的信息
{
do
{
if(0 == _stricmp(pe.szExeFile, szName)) // 不区分大小写比较
{
id = pe.th32ProcessID;
break;
}
}while(Process32Next(hSnapshot, &pe)); // 下一个进程
}
CloseHandle(hSnapshot); // 删除快照
return id;
}
获取主线程ID(先获取进程ID,再获取该进程的主线程ID)
// 由进程名获取主线程ID(需要头文件tlhelp32.h)
// 失败返回0
DWORD GetMainThreadIdFromName(LPCSTR szName)
{
DWORD idThread = 0; // 进程ID
DWORD idProcess = 0; // 主线程ID
// 获取进程ID
PROCESSENTRY32 pe; // 进程信息
pe.dwSize = sizeof(PROCESSENTRY32);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 获取系统进程列表
if(Process32First(hSnapshot, &pe)) // 返回系统中第一个进程的信息
{
do
{
if(0 == _stricmp(pe.szExeFile, szName)) // 不区分大小写比较
{
idProcess = pe.th32ProcessID;
break;
}
}while(Process32Next(hSnapshot, &pe)); // 下一个进程
}
CloseHandle(hSnapshot); // 删除快照
if (idProcess == 0)
{
return 0;
}
// 获取进程的主线程ID
THREADENTRY32 te; // 线程信息
te.dwSize = sizeof(THREADENTRY32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); // 系统所有线程快照
if(Thread32First(hSnapshot, &te)) // 第一个线程
{
do
{
if(idProcess == te.th32OwnerProcessID) // 认为找到的第一个该进程的线程为主线程
{
idThread = te.th32ThreadID;
break;
}
}while(Thread32Next(hSnapshot, &te)); // 下一个线程
}
CloseHandle(hSnapshot); // 删除快照
return idThread;
}
3 示例
例子是通过向进程的主线程发送WM_QUIT消息结束主线程消息循环使进程退出,这样相比TerminateProcess
有一个优点:如果被关闭的进程是在主线程消息循环之后进行清理工作的话,就保证了该进程退出前能完成清理。(注意,此方法并不能保证关闭任意进程,如没有线程消息循环的普通控制台程序)
#include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
DWORD GetMainThreadIdFromName(LPCSTR szName);
int main(void)
{
DWORD id = GetMainThreadIdFromName("notepad.exe");
if (id > 0)
{
PostThreadMessage(id, WM_QUIT, 0, 0);
}
printf("id = %d\n", id);
system("pause");
return 0;
}
// GetMainThreadIdFromName函数实现略
本文原文链接 http://blog.youkuaiyun.com/yanglx2022/article/details/46582629