2012-11-19 88 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

相關問題