【问题标题】:Why does AssignProcessToJobObject fail on XP with error Access Denied?为什么在 XP 上 AssignProcessToJobObject 会失败并显示拒绝访问错误?
【发布时间】:2012-11-19 07:42:38
【问题描述】:

我有以下代码:

#include <windows.h>
#include <stdio.h>
#include <shlwapi.h>

#pragma comment ( lib, "shlwapi.lib" )

int __cdecl wmain( int argc, PWSTR argv[] )
{
HANDLE Job( CreateJobObject( NULL, NULL ) );
if( !Job )
{
    wprintf( L"Could not create job object, error %d\n", GetLastError() );
    return 0;
}

HANDLE IOPort( CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 1 ) );
if( !IOPort )
{
    wprintf( L"Could not create IO completion port, error %d\n", GetLastError() );
    return 0;
}

JOBOBJECT_ASSOCIATE_COMPLETION_PORT Port;
Port.CompletionKey = Job;
Port.CompletionPort = IOPort;

if( !SetInformationJobObject( Job, JobObjectAssociateCompletionPortInformation, &Port, sizeof( Port ) ) )
{
    wprintf( L"Could not associate job with IO completion port, error %d\n", GetLastError() );
    return 0;
}

PROCESS_INFORMATION ProcessInformation;
STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
PWSTR CommandLine = PathGetArgs(GetCommandLine());

if( !CreateProcess( NULL, CommandLine, NULL, NULL, FALSE, CREATE_NEW_CONSOLE | CREATE_SUSPENDED, NULL, NULL, &StartupInfo, &ProcessInformation ) )
{
    wprintf( L"Could not run process, error %d\n", GetLastError() );
    return 0;
}

if( !AssignProcessToJobObject( Job, ProcessInformation.hProcess ) )
{
    wprintf( L"Could not assign process to job, error %d\n", GetLastError() );
    return 0;
}

ResumeThread( ProcessInformation.hThread );
CloseHandle( ProcessInformation.hThread );
CloseHandle( ProcessInformation.hProcess );

DWORD CompletionCode;
ULONG_PTR CompletionKey;
LPOVERLAPPED Overlapped;

int ProcessCount = 0;

while ( GetQueuedCompletionStatus( IOPort, &CompletionCode, &CompletionKey, &Overlapped, INFINITE ) && CompletionCode != JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO )
{
    if ( CompletionCode == JOB_OBJECT_MSG_NEW_PROCESS ) ProcessCount++;
    if ( ( CompletionCode == JOB_OBJECT_MSG_EXIT_PROCESS ) || ( CompletionCode == JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS) ) ProcessCount--;

    wprintf( L"Waiting for %d processes to finish...\n", ProcessCount );
}

wprintf( L"All done\n" );

return 0;
}

此代码在 Windows 7 上运行良好,但在 Windows XP 上 AssignProcessToJobObject 失败并出现错误代码 5 ( Access Denied )。根据 MSDN:Windows 7、Windows Server 2008 R2、带有 SP3 的 Windows XP、Windows Server 2008、Windows Vista 和 Windows Server 2003:进程必须尚未分配给作业;如果是,则函数失败并显示 ERROR_ACCESS_DENIED。从 Windows 8 和 Windows Server 2012 开始,此行为发生了变化。

有人可以帮我更正这段代码吗?

谢谢!

更新: 我能够找到问题,但我仍然不知道如何解决它:( 问题是,我使用标准用户(没有管理员权限)登录 XP 机器,并使用 runas(具有管理员权限的用户)打开一个 cmd,然后这个 cmd 将被创建为一个jobobject。在进程资源管理器中,您可以看到这一点。如果我想从此 cmd 启动我的应用程序,则 AssignProcessToJobObject 将失败,并出现错误访问拒绝,因为 thios cmd 已分配给作业。

有没有办法解决我的问题?

【问题讨论】:

标签: c windows


【解决方案1】:

可能是代码运行的环境已经创建了一个包含父进程的作业。您可以尝试将CREATE_BREAKAWAY_FROM_JOB 添加到进程创建标志中,因为这可能会使新进程中断它目前从事的工作。

我不记得 Visual Studio 在调试器下运行时是否在作业中运行。

您也可以尝试查询当前进程的作业状态,因为这将显示它是否已经在作业中。

【讨论】:

  • 请阅读我的更新。知道更新后,您还有其他想法如何解决我的问题吗?
  • 你有没有试过把你所从事的工作的细节倾倒出来?您是否尝试将CREATE_BREAKAWAY_FROM_JOB 添加到进程创建标志中?
  • I1m 检查我应该查询哪些信息。我尝试使用 CREATE_BREAKAWAY_FROM_JOB 但随后 createprocess 失败并拒绝访问。
  • 如果你从事的工作不允许你脱离,那么你就会陷入困境。如果您直接以管理员身份运行,我认为它可以正常工作?
  • 这就是我害怕的。如果我在 SYSTEM 帐户下打开一个 cmd,然后从那里启动我的应用程序,那么它工作正常。另一种解决方案是,如果我可以在 SYSTEM 帐户下创建一个进程(如果可能,不使用服务),但我不知道该怎么做。需要明确的是,这仅在 XP 下发生。在 Windows 7 下它可以完美运行。
猜你喜欢
  • 2010-09-10
  • 1970-01-01
  • 2015-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多