我有以下代码:
#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上运行正常,但AssignProcessToJobObject失败,在Windows XP上出现错误代码5(拒绝访问)。根据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创建为ajobobject。在进程资源管理器中,您可以看到这一点如果我想从此cmd启动我的应用程序,那么AssignProcessToJobObject将失败并且错误访问拒绝,因为thios cmd已经分配给作业。
有没有办法解决我的问题?
答案 0 :(得分:2)
可能是代码运行的环境已经创建了包含父进程的作业。您可以尝试将CREATE_BREAKAWAY_FROM_JOB
添加到进程创建标志中,因为这可能会使新进程中断来自它目前的工作。
我不记得Visual Studio在调试器下运行时是否在作业中运行。
您还可以尝试查询当前进程的作业状态,因为这将显示它是否已经在作业中。