我有以下代碼:爲什麼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已經分配給作業。
有沒有解決我的問題的方法嗎?
未來的讀者應該參考http://stackoverflow.com/questions/13471611/how-to-detach-a-process-from-a-jobobject/13485946#13485946;我已經將我的答案提到了那裏,因爲它更合適。 –