2012-11-19 87 views
2

我有以下代码:为什么AssignProcessToJobObject在XP上失败,出现Access Denied错误?

#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失败,错误码5在Windows XP(拒绝访问)。根据MSDN:Windows 7,Windows Server 2008 R2,带有SP3,Windows Server 2008,Windows Vista和Windows Server 2003的Windows XP:该过程不得已分配给作业;如果是,则该函数将因ERROR_ACCESS_DENIED而失败。此行为从Windows 8和Windows Server 2012开始发生变化。

有人能帮我改正这段代码吗?

谢谢!

更新: 我能够发现问题,但我仍然不知道如何解决它:( 的问题是,这是我登录XP的机器,有一个标准的用户(无管理员权限),然后用runas打开一个cmd(拥有管理员权限的用户),那么这个cmd将被创建为一个jobobject。在进程资源管理器中,你可以看到这个,如果我想从这个cmd启动我的应用程序,那么AssignProcessToJobObject将失败,埃罗访问拒绝,因为thios CMD已经分配给作业。

有没有解决我的问题的方法吗?

+0

未来的读者应该参考http://stackoverflow.com/questions/13471611/how-to-detach-a-process-from-a-jobobject/13485946#13485946;我已经将我的答案提到了那里,因为它更合适。 –

回答

2

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

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

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

+0

请阅读我的更新。你有没有其他的想法如何解决我的问题,知道更新? – kampi

+0

你有没有试过把你所在工作的细节抛出去?你有没有尝试在进程创建标志中添加'CREATE_BREAKAWAY_FROM_JOB'? –

+0

I1m检查我应该查询哪些信息。我尝试使用CREATE_BREAKAWAY_FROM_JOB,但随后createprocess失败,访问被拒绝。 – kampi

相关问题