如何将当前进程分配给新创建的作业对象?

时间:2010-12-08 12:17:10

标签: c++ windows winapi

我似乎无法使用AssignProcessToJobObject函数将当前进程分配给CreateJobObject给出的作业对象句柄。这已经在StackOverflow上被问了好几次,但到目前为止,没有一个解决方案(通常归结为嵌入UAC清单)似乎对我有用。

我在Windows 7上使用MSVC9。这是我的示例应用程序的源代码和我嵌入的一个小清单(据说可以修复问题 - 但不适合我):

我的示例应用程序(main.cpp):

#include <windows.h>

static void dumpLastError()
{
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );
    OutputDebugStringA( (LPTSTR)lpMsgBuf );

    LocalFree(lpMsgBuf);
}

int main()
{
    HANDLE job = CreateJobObjectA( NULL, "demo job 123" );
    if ( !job ) {
        OutputDebugStringA( "CreateJobObject failed" );
        dumpLastError();
        return 1;
    }

    if ( !AssignProcessToJobObject( job, GetCurrentProcess() ) ) {
        OutputDebugStringA( "AssignProcessToJobObject failed" );
        dumpLastError();
        return 1;
    }

    return 0;
}

UAC清单(main.exe.manifest):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
   <ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
      <ms_asmv3:security>
         <ms_asmv3:requestedPrivileges>
            <ms_asmv3:requestedExecutionLevel level="requireAdministrator"/>
         </ms_asmv3:requestedPrivileges>
      </ms_asmv3:security>
   </ms_asmv3:trustInfo>
</assembly>

我通过运行

来构建此示例
cl main.cpp
mt -manifest main.exe.manifest -outputresource:main.exe;1

不幸的是,在尝试main.exe调用后,在执行这些步骤后运行我的AssignProcessToJobObject示例仍会在调试输出中产生“拒绝访问”错误。有人知道那是为什么吗?

2 个答案:

答案 0 :(得分:5)

我知道这是一个老问题,但我最近遇到了完全相同的问题。 正如所建议的那样,我使用命令行解决方法,直到几分钟前我找到了this post

由于我正在创建流程,所以我只是按照文章中的说明将CREATE_BREAKAWAY_FROM_JOB添加到流程创建标记中:

CreateProcess(szPath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi)

CreateProcess(szPath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_BREAKAWAY_FROM_JOB, NULL, NULL, &si, &pi)

我测试了它并按预期工作,进程被分配给作业,没有UAC清单,没有命令行。

希望它可以帮助您或其他任何有此问题的人。

答案 1 :(得分:2)

我在一个关于工作对象和UAC清单的讨论中进行了一些讨论。帮助我解决您所遇到的同一问题的唯一信息是,从cmd运行时,此安全功能(在Vista中引入)显然不会强制执行。

我假设您从开始菜单启动PyCmd。尝试从cmd启动它,我敢打赌问题也会消失。

我最终做的事情(用cygwin运行)是为了制作一个mintty.bat,其中说

start mintty.exe

然后是mintty.bat的快捷方式,其中有一个属性设置为'最小化'(我忘记确切的措辞)。这允许我想从开始菜单启动shell,并且仍然可以像从cmd.exe启动一样工作。

作为旁注,我会喜欢它,如果有人会出现并在构建级别实际解释问题,以及如何解决它。