简体   繁体   English

OpenProcess函数返回无效的句柄

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM