回答
您应该使用Native API和GetProcAddress
来查找NtQueryInformationProcess
的地址。
typedef struct _PROCESS_BASIC_INFORMATION
{
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
HANDLE UniqueProcessId;
HANDLE InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
NTSYSCALLAPI
NTSTATUS
NTAPI
NtQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESS_INFORMATION_CLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
PROCESS_BASIC_INFORMATION basicInfo;
NtQueryInformationProcess(NtCurrentProcess(), ProcessBasicInformation, &basicInfo, sizeof(basicInfo), NULL);
// My parent PID (*) is in basicInfo.InheritedFromUniqueProcessId
为了让祖父母PID,打开使用父PID父进程和父进程再次调用NtQueryInformationProcess
。
注意 - 严格来说,父进程(创建子进程的进程)实际上并未被记录。 InheritedFromUniqueProcessId
只是为您提供了继承属性的过程。但这很少是一个问题。
或者,如果您不喜欢Native API,请使用CreateToolhelp32Snapshot和TH32CS_SNAPPROCESS
,它会为您提供所需的信息,不同之处在于您必须搜索整个列表。
AFAIK,没有标准的方法来找到当前进程的祖父进程。找到父母的过程是正常的,但不是祖父母。如果你真的需要这些信息,那么父母的过程必须教育他们的孩子关于父母自己的父母过程 - 就像父母必须教孩子一般关于生活的真实生活。
通信如何发生取决于进程是仅仅复制自己(分叉)还是它也在执行其他进程。如果这些过程只是分叉,那么父类只需要设置一个适当的变量。如果进程正在执行其他程序,则需要查看环境变量或命令行参数以中继该信息。
如果我离开祖父母,只是想找到父母的身份证号码,我该怎么办。 – 2011-03-16 07:15:44
@Beetles:在Unix中,你会使用'getppid()'。如果你的Windows机器上有Unix服务,那么你也可以在那里使用它。否则,你可能会发现'_getppid()'可用并且可行,但可能还有一个原生WinAPI调用可以完成同样的工作 - 我不知道它是什么,我的Google-fu似乎抛弃了我。 – 2011-03-16 16:34:12
wj32的答案应该做你需要的,但我想我会提到另一种方式,以防其他人需要一个不同级别的祖先。您还可以拍摄快照列举流程树并浏览祖先,直到达到您想要达到的任何级别,如here所述。
下面的示例获取的父进程的进程ID(该过程开始的当前一个):
// Speed up build process with minimal headers.
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRALEAN
#include <tchar.h>
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
/* Macros for prettier code. */
#ifndef MAX_PATH
# define MAX_PATH _MAX_PATH
#endif
// Search each process in the snapshot for id.
BOOL FindProcessID(HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe)
{
BOOL fOk;
ppe->dwSize = sizeof(PROCESSENTRY32);
for (fOk = Process32First(snap, ppe); fOk; fOk = Process32Next(snap, ppe))
if (ppe->th32ProcessID == id)
break;
return fOk;
}
// Obtain the process and thread identifiers of the parent process.
BOOL ParentProcess(LPPROCESS_INFORMATION ppi)
{
HANDLE hSnap;
PROCESSENTRY32 pe;
THREADENTRY32 te;
DWORD id = GetCurrentProcessId();
BOOL fOk;
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS|TH32CS_SNAPTHREAD, id);
if (hSnap == INVALID_HANDLE_VALUE)
return FALSE;
FindProcessID(hSnap, id, &pe);
if (!FindProcessID(hSnap, pe.th32ParentProcessID, &pe))
{
CloseHandle(hSnap);
return FALSE;
}
te.dwSize = sizeof(te);
for (fOk = Thread32First(hSnap, &te); fOk; fOk = Thread32Next(hSnap, &te))
if (te.th32OwnerProcessID == pe.th32ProcessID)
break;
CloseHandle(hSnap);
ppi->dwProcessId = pe.th32ProcessID;
ppi->dwThreadId = te.th32ThreadID;
return fOk;
}
int _tmain(int argc, _TCHAR* argv[])
{
PROCESS_INFORMATION parentInformation;
if(!ParentProcess(&parentInformation)) {
_tprintf(TEXT("Fatal: Could not get parent information.\n"));
return 1;
}
_tprintf(TEXT("Parent Process ID: %ul\n"), parentInformation.dwProcessId);
return 0;
}
这里是一个C程序获取父进程ID(与上仅处理一个环路总)。 函数GetParentProcessId()在其输出参数“parent_process_id”中返回Windows父进程标识。
#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>
// Find a process with a given id in a snapshot
BOOL FindProcessID(HANDLE snap, DWORD id, LPPROCESSENTRY32 ppe)
{
BOOL res;
ppe->dwSize = sizeof(PROCESSENTRY32); // (mandatory)
res = Process32First(snap, ppe);
while (res) {
if (ppe->th32ProcessID == id) {
return TRUE;
}
res = Process32Next(snap, ppe);
}
return FALSE;
}
// Get the parent process id of the current process
BOOL GetParentProcessId(DWORD* parent_process_id)
{
HANDLE hSnap;
PROCESSENTRY32 pe;
DWORD current_pid = GetCurrentProcessId();
// Take a snapshot of all Windows processes
hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (INVALID_HANDLE_VALUE == hSnap) {
return FALSE;
}
// Find the current process in the snapshot
if (!FindProcessID(hSnap, current_pid, &pe)) {
return FALSE;
}
// Close the snapshot
if (!CloseHandle(hSnap)) {
return FALSE;
}
*parent_process_id = pe.th32ParentProcessID;
return TRUE;
}
- 1. C程序从父母id(minix)获取子进程ID
- 2. 从进程名称获取进程ID
- 3. 获取子进程ID
- 4. 如何从父进程获取子进程
- 5. C++如何获取父进程ID
- 6. 在solaris内核模块中获取进程ID和父进程
- 7. 子进程/父进程
- 8. 如何从子进程定义具有相同进程ID的父进程
- 9. 从子进程获取PID
- 10. 获取PowerShell进程的进程ID
- 11. Node.JS父进程ID
- 12. 子进程stdin不会获取父进程发送的数据
- 13. 猛砸获取进程ID在子shell
- 14. shelljs - 获取由shelljs.exec()创建的进程的进程ID()进程
- 15. 获取Scala.sys.process.Process的进程ID
- 16. 正确获取进程ID
- 17. 为什么子进程认为父进程ID是1?
- 18. 如何从进程名称获取进程ID?
- 19. 如何从进程ID获取进程句柄?
- 20. 从进程ID获取进程可执行文件名称
- 21. 获取进程的ID从进程名称
- 22. NodeJS:从进程ID获取进程信息
- 23. 从进程ID获取进程名称(win32)
- 24. 如果您从子进程fork()和exec(),并在父进程中等待,父进程如何从子进程获取返回代码?
- 25. 从DLL获取当前进程ID
- 26. 从进程ID获取窗口标题
- 27. 从Com对象获取进程ID
- 28. 如何从IAudioSessionManager2获取进程ID
- 29. 如何在shell脚本中从分叉子进程获取进程ID(pid)
- 30. 父和子进程
在MSDN上,NtQueryInformationProcess文档提到了PROCESS_BASIC_INFORMATION,但它没有InheritedFromUniqueProcessId。这是特定于某个Windows版本吗? https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280%28v=vs.85%29.aspx – chilemagic 2015-10-28 14:06:56