有什么办法如何枚举窗口给定的PID进程,并获得他所有打开的句柄(locking的文件等)的列表?
编辑:我不在乎语言。 如果是在.NET中,我会很高兴,如果在WinApi(C)中,它不会受到伤害。 如果在别的地方,我想我可以重写它:-)
我做了一个深度的搜索,发现这篇文章 。 本文给出了一个链接, 下载源代码 :
我尝试了NtSystemInfoTest.cpp(下载的源代码)的方法,它的工作非常好。
void ListHandles( DWORD processID, LPCTSTR lpFilter )
代码有以下免责声明:
// Written by Zoltan Csizmadia, zoltan_csizmadia@yahoo.com // For companies(Austin,TX): If you would like to get my resume, send an email. // // The source is free, but if you want to use it, mention my name and e-mail address // ////////////////////////////////////////////////////////////////////////////////////// //
我希望这可以帮助你。
如果你只是想要一个工具,Sysinternals的命令行“ Handle ”工具就可以做到这一点。 但是,如果你正在寻找一个代码解决方案,这将无济于事。
这里是一个使用DDK中的ZwQueryProcessInformation
的例子 。 DDK现在被称为“WDK”,可以在MSDN上使用。 如果你没有MSDN,你可以从这里得到它。
我没有尝试过,我只是GOOGLE了你的问题。
#include "ntdll.h" #include <stdlib.h> #include <stdio.h> #include "ntddk.h" #define DUPLICATE_SAME_ATTRIBUTES 0x00000004 #pragma comment(lib,"ntdll.lib") BOOL EnablePrivilege(PCSTR name) { TOKEN_PRIVILEGES priv = {1, {0, 0, SE_PRIVILEGE_ENABLED}}; LookupPrivilegeValue(0, name, &priv.Privileges[0].Luid); HANDLE hToken; OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken); AdjustTokenPrivileges(hToken, FALSE, &priv, sizeof priv, 0, 0); BOOL rv = GetLastError() == ERROR_SUCCESS; CloseHandle(hToken); return rv; } int main(int argc, char *argv[]) { if (argc == 1) return 0; ULONG pid = strtoul(argv[1], 0, 0); EnablePrivilege(SE_DEBUG_NAME); HANDLE hProcess = OpenProcess(PROCESS_DUP_HANDLE, FALSE, pid); ULONG n = 0x1000; PULONG p = new ULONG[n]; while (NT::ZwQuerySystemInformation(NT::SystemHandleInformation, p, n * sizeof *p, 0) == STATUS_INFO_LENGTH_MISMATCH) delete [] p, p = new ULONG[n *= 2]; NT::PSYSTEM_HANDLE_INFORMATION h = NT::PSYSTEM_HANDLE_INFORMATION(p + 1); for (ULONG i = 0; i < *p; i++) { if (h[i].ProcessId == pid) { HANDLE hObject; if (NT::ZwDuplicateObject(hProcess, HANDLE(h[i].Handle), NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ATTRIBUTES) != STATUS_SUCCESS) continue; NT::OBJECT_BASIC_INFORMATION obi; NT::ZwQueryObject(hObject, NT::ObjectBasicInformation, &obi, sizeof obi, &n); printf("%p %04hx %6lx %2x %3lx %3ld %4ld ", h[i].Object, h[i].Handle, h[i].GrantedAccess, int(h[i].Flags), obi.Attributes, obi.HandleCount - 1, obi.PointerCount - 2); n = obi.TypeInformationLength + 2; NT::POBJECT_TYPE_INFORMATION oti = NT::POBJECT_TYPE_INFORMATION(new CHAR[n]); NT::ZwQueryObject(hObject, NT::ObjectTypeInformation, oti, n, &n); printf("%-14.*ws ", oti[0].Name.Length / 2, oti[0].Name.Buffer); n = obi.NameInformationLength == 0 ? MAX_PATH * sizeof (WCHAR) : obi.NameInformationLength; NT::POBJECT_NAME_INFORMATION oni = NT::POBJECT_NAME_INFORMATION(new CHAR[n]); NTSTATUS rv = NT::ZwQueryObject(hObject, NT::ObjectNameInformation, oni, n, &n); if (NT_SUCCESS(rv)) printf("%.*ws", oni[0].Name.Length / 2, oni[0].Name.Buffer); printf("\n"); CloseHandle(hObject); } } delete [] p; CloseHandle(hProcess); return 0; }
这是从Sysinternals论坛看起来像一个很好的答案: HOWTO:枚举句柄