在我的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);
怎么继续?替代?
答案 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)流程句柄是通过NtQueryInformationThread
和NtOpenProcess
获得的。
3)NtReadVirtualMemory
用于从位置FIELD_OFFSET(TEB, SubProcessTag)
的已打开进程中的线程内存中读取(不确定如何转换为C#)。这就是所谓的ServiceTag
。
4)使用ServiceTag
中的I_QueryTagInformation
从advapi32.dll
获取服务名称。
所以没有诡计,也没有魔力,但是为C#工作似乎有点工作。