如何通过PID和线程ID查找Windows服务?

时间:2015-11-22 20:03:40

标签: c# windows multithreading service pid

在我的C#应用​​程序中,我有一个Windows服务的PID和threadID。我如何找到它是哪个服务(注意:例如,svchost.exe的单个实例可以托管多个服务)?直接在C#中或者调用其他实用程序对我来说没问题。

Process Hacker可以显示服务名称(进程的属性 - >制表符线程 - >列服务)。

到目前为止,我已经找到了这个过程以及线程:

var p = Process.GetProcessById(pid);
var t = p.Threads.Cast<ProcessThread>().SingleOrDefault(t => t.Id == threadId);

怎么继续?替代?

2 个答案:

答案 0 :(得分:0)

一般情况下,你不能。线程和服务之间没有1:1的关系。单个线程可以运行多个服务,单个服务可以(通常也有)具有多个线程。

Process Hacker可能正在使用某种启发式方法,例如,跟踪线程的调用堆栈并识别svchost.exe正在运行的DLL。或者它可能假设该线程与调用ServiceMain()的线程相同;可能有一种无证件的识别方法。

答案 1 :(得分:0)

我查看了Process Hacker的源代码。 Harry Johnston建议没有启发式。反而是什么:

1)使用NtQueryInformationThread查找线程的基地址。 检查Get StartAddress of win32 thread from another process以了解如何从C#拨打电话。

2)流程句柄是通过NtQueryInformationThreadNtOpenProcess获得的。

3)NtReadVirtualMemory用于从位置FIELD_OFFSET(TEB, SubProcessTag)的已打开进程中的线程内存中读取(不确定如何转换为C#)。这就是所谓的ServiceTag

4)使用ServiceTag中的I_QueryTagInformationadvapi32.dll获取服务名称。

所以没有诡计,也没有魔力,但是为C#工作似乎有点工作。