线程、线程ID获取
一、进程ID获取
1.1 当前进程的Id
方法1 通过进程名获取
下面的例子中,也包含了获取该进程下的线程的方法。
System.Diagnostics.Process[] processes;bool foundProcess = false; System.Diagnostics.ProcessThreadCollection threads = null; System.Threading.Thread thread = null;
processes = System.Diagnostics.Process.GetProcesses(); foreach (System.Diagnostics.Process p in processes) { if (p.ProcessName == "进程名") { threads = p.Threads; foundProcess = true; break; } } if (foundProcess) { foreach (System.Threading.Thread th in threads) { if (th.Name == "xxxxx") { thread = th; break; } } } if (thread != null) { // 不知道threadId是不是你说的线程ID. int threadId = thread.ManagedThreadId; }
方法2 直接获取
Process processes = Process.GetCurrentProcess processes.id // 获得当前进程的ID
二、线程ID获取
2.1 C#获取当前线程ID
方法1 推荐
Thread.CurrentThread.ManagedThreadId
方法2
AppDomain.GetCurrentThreadId()
其它
GetThreadId 根据线程句柄得到线程ID;
GetWindowThreadProcessId ,根据窗口句柄得到此窗口所在线程的ID(也同时得到进程的ID);
OpenThread,能根据ID得到线程的句柄;
获取在关联进程中运行的一组线程:Process.Threads 属性
获取线程的唯一标识符:ProcessThread.Id
2.2 C++获取主线程
此处进程名是指进程可执行文件的名称(任务管理器进程列表中显示的映像名称),如notepad.exe。Windows中没有直接可用的相关函数,实现思路为使用CreateToolhelp32Snapshot函数创建进程或线程快照然后从中逐个比较。需要包含头文件#include <tlhelp32.h>。
获取进程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; }
使用:
例子是通过向进程的主线程发送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函数实现略
参考文章
你们的评论、反馈,及对你们有所用,是我整理材料和博文写作的最大的鼓励和唯一动力。欢迎讨论和关注!
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。
没有整理与归纳的知识,一文不值!高度概括与梳理的知识,才是自己真正的知识与技能。 永远不要让自己的自由、好奇、充满创造力的想法被现实的框架所束缚,让创造力自由成长吧! 多花时间,关心他(她)人,正如别人所关心你的。理想的腾飞与实现,没有别人的支持与帮助,是万万不能的。