OpenProcess 函数 returns 句柄无效
OpenProcess function returns invalid handles
我正在开发一个应用程序,它可以创建多个桌面并让用户能够在他当前使用的桌面下启动他想要的任何应用程序。
当该桌面关闭时(使用组合键)我想关闭在该桌面下打开的所有应用程序。为此,我使用 EnumProcesses
函数枚举了所有进程,并使用 OpenProcess
函数根据 EnumProcesses 返回的每个进程标识符检索句柄。使用 GetThreadId
我检索用作 GetThreadDesktop
函数参数的线程标识符,并将返回的句柄与我桌面上的句柄进行比较,这样我就可以找出进程在哪个桌面上运行。
至少在理论上,这是可行的,因为对于每个进程标识符,OpenProcess
函数 returns 是 GetThreadId
的无效句柄(错误代码 6)。我以管理员身份 运行 应用程序并启用了 SeDebugPrivilege 权限。
我不明白为什么返回的句柄总是无效的,这是我使用的代码:
void iterateProcesses(HDESK threadDesktop)
{
EnableDebugPriv(); // functions enables the SeDebugPrivilege privilege
int found = 0;
int wanted = 0;
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded);
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++)
{
if (aProcesses[i] != 0)
{
found++;
if (GetThreadDesktop(checkProcess(aProcesses[i])) == threadDesktop)
{
wanted++;
}
}
}
}
DWORD checkProcess(DWORD processID)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processID);
GetLastError(); // if in the manifest file under 'UAC execution level'
// the application does not requests for administrator rights
// GetLastError() will return code 5 (access denied)
DWORD dwThreadId = GetThreadId(hProcess);
GetLastError(); // return code 6 (ERROR_INVALID_HANDLE)
// dwThreadId returned is always 0 because the handle is not valid
CloseHandle(hProcess);
return dwThreadId;
}
你的错误检查是错误的。请再次阅读文档。仅在函数失败时调用 GetLastError
。
只有在执行提升时才能获得对进程句柄的所有访问权限,这是合理的。但是您确实需要检查由 OpenProcess
编辑的值 return,如文档中所述。仅当该值指示成功时才继续。否则,请致电 GetLastError
找出原因。
您需要将线程句柄传递给 GetThreadId
。 hProcess
是进程句柄。因此 ERROR_INVALID_HANDLE
错误代码。但同样,您没有正确检查错误。您必须首先检查 return 值,如文档中所述。仅当这表明失败时才调用 GetLastError
.
我不确定您如何期望从进程中获得单个线程。进程可以并且确实有很多线程。确实可以创建和销毁线程,因此您正在寻找的线程可能已经不存在了。尽管如此,下面是枚举进程中线程的方法:https://msdn.microsoft.com/en-us/library/windows/desktop/ms686852.aspx
我正在开发一个应用程序,它可以创建多个桌面并让用户能够在他当前使用的桌面下启动他想要的任何应用程序。
当该桌面关闭时(使用组合键)我想关闭在该桌面下打开的所有应用程序。为此,我使用 EnumProcesses
函数枚举了所有进程,并使用 OpenProcess
函数根据 EnumProcesses 返回的每个进程标识符检索句柄。使用 GetThreadId
我检索用作 GetThreadDesktop
函数参数的线程标识符,并将返回的句柄与我桌面上的句柄进行比较,这样我就可以找出进程在哪个桌面上运行。
至少在理论上,这是可行的,因为对于每个进程标识符,OpenProcess
函数 returns 是 GetThreadId
的无效句柄(错误代码 6)。我以管理员身份 运行 应用程序并启用了 SeDebugPrivilege 权限。
我不明白为什么返回的句柄总是无效的,这是我使用的代码:
void iterateProcesses(HDESK threadDesktop)
{
EnableDebugPriv(); // functions enables the SeDebugPrivilege privilege
int found = 0;
int wanted = 0;
DWORD aProcesses[1024], cbNeeded, cProcesses;
unsigned int i;
EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded);
cProcesses = cbNeeded / sizeof(DWORD);
for (i = 0; i < cProcesses; i++)
{
if (aProcesses[i] != 0)
{
found++;
if (GetThreadDesktop(checkProcess(aProcesses[i])) == threadDesktop)
{
wanted++;
}
}
}
}
DWORD checkProcess(DWORD processID)
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, TRUE, processID);
GetLastError(); // if in the manifest file under 'UAC execution level'
// the application does not requests for administrator rights
// GetLastError() will return code 5 (access denied)
DWORD dwThreadId = GetThreadId(hProcess);
GetLastError(); // return code 6 (ERROR_INVALID_HANDLE)
// dwThreadId returned is always 0 because the handle is not valid
CloseHandle(hProcess);
return dwThreadId;
}
你的错误检查是错误的。请再次阅读文档。仅在函数失败时调用 GetLastError
。
只有在执行提升时才能获得对进程句柄的所有访问权限,这是合理的。但是您确实需要检查由 OpenProcess
编辑的值 return,如文档中所述。仅当该值指示成功时才继续。否则,请致电 GetLastError
找出原因。
您需要将线程句柄传递给 GetThreadId
。 hProcess
是进程句柄。因此 ERROR_INVALID_HANDLE
错误代码。但同样,您没有正确检查错误。您必须首先检查 return 值,如文档中所述。仅当这表明失败时才调用 GetLastError
.
我不确定您如何期望从进程中获得单个线程。进程可以并且确实有很多线程。确实可以创建和销毁线程,因此您正在寻找的线程可能已经不存在了。尽管如此,下面是枚举进程中线程的方法:https://msdn.microsoft.com/en-us/library/windows/desktop/ms686852.aspx