回答
您應該使用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