[英]OpenProcess function returns invalid handles
I'm working on an application that creates multiple desktops and gives the user the ability to start whatever applications he desires under the desktop he is currently using. 我正在开发一个可创建多个桌面的应用程序,并使用户能够在他当前正在使用的桌面下启动所需的任何应用程序。
When that desktop is closed (using a combo key) I want close all applications opened under that desktop. 当该桌面关闭时(使用组合键),我想关闭在该桌面下打开的所有应用程序。 In order to do this I enumarate all processes using the
EnumProcesses
function and retrive a handle based on every process identifier returned by EnumProcesses using OpenProcess
function. 为此,我使用
EnumProcesses
函数对所有进程进行枚举,并使用OpenProcess
函数根据EnumProcesses返回的每个进程标识符检索句柄。 Using GetThreadId
I retrieve the thread identifier which is used as the parameter for GetThreadDesktop
function and the returned handle is compared with the one from my desktop, so I can find out in which desktop the process runs. 我使用
GetThreadId
检索用作GetThreadDesktop
函数参数的线程标识符,并将返回的句柄与我的桌面上的句柄进行比较,因此我可以找出进程在哪个桌面上运行。
At least in theory, this works, because for every process identifier, OpenProcess
function returns an invalid handle for GetThreadId
(error code 6). 至少从理论上讲,这是可行的,因为对于每个进程标识符,
OpenProcess
函数都会为GetThreadId
返回一个无效的句柄(错误代码6)。 I'm running the application as administrator and I enable the SeDebugPrivilege privilege. 我以管理员身份运行该应用程序,并启用了SeDebugPrivilege特权。
I don't understand why the returned handle is always invalid, here is the code that I use: 我不明白为什么返回的句柄总是无效的,这是我使用的代码:
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;
}
Your error checking is wrong. 您的错误检查是错误的。 Please read the documentation again.
请再次阅读文档。 Only call
GetLastError
if the function failed. 如果函数失败,则仅调用
GetLastError
。
It's reasonable that you will only be able to get all access to a process handle if you are executing elevated. 合理的是,只有在执行提升权限时,您才能够获得对流程句柄的所有访问权限。 But you do need to check the value returned by
OpenProcess
, as described in the documentation. 但是您确实需要检查
OpenProcess
返回的值,如文档中所述。 Only proceed if that value indicates success. 仅当该值表示成功时才继续。 Otherwise, call
GetLastError
to find out why. 否则,请调用
GetLastError
找出原因。
You are expected to pass a thread handle to GetThreadId
. 您应该将线程句柄传递给
GetThreadId
。 hProcess
is a process handle. hProcess
是一个进程句柄。 Hence the ERROR_INVALID_HANDLE
error code. 因此,
ERROR_INVALID_HANDLE
错误代码。 But again, you are not checking for errors properly. 但是同样,您没有正确检查错误。 You must first check the return value, as stated in the documentation.
您必须首先检查返回值,如文档中所述。 Only if that indicates failure do you call
GetLastError
. 仅在指示失败的情况下,才调用
GetLastError
。
I'm not sure how you can expect to get a single thread from a process. 我不确定如何期望从进程中获得单个线程。 Processes can, and do, have many threads.
进程可以而且确实有很多线程。 Indeed threads can be created and destroyed so perhaps the thread you are looking for is not there anymore.
实际上,可以创建和销毁线程,因此也许您正在寻找的线程不再存在。 All the same, here's how to enumerate threads in a process: https://msdn.microsoft.com/en-us/library/windows/desktop/ms686852.aspx
都一样,这是枚举进程中线程的方法: https : //msdn.microsoft.com/zh-cn/library/windows/desktop/ms686852.aspx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.