次のコードがあります。
#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、Windows XP with SP3、Windows Server 2008、Windows Vista、および Windows Server 2003: プロセスがまだジョブに割り当てられていてはなりません。そうである場合、関数は ERROR_ACCESS_DENIED で失敗します。この動作は、Windows 8 および Windows Server 2012 以降で変更されました。
誰かがこのコードを修正するのを手伝ってくれませんか?
ありがとう!
更新: 問題を見つけることができましたが、まだ解決方法がわかりません:(問題は、XPマシンに標準ユーザー(管理者権限なし)でログインし、cmdを開くことですrunas (管理者権限を持つユーザー) を使用すると、このコマンドはジョブ オブジェクトとして作成されます。プロセス エクスプローラーで確認できます。このコマンドからアプリケーションを起動したい場合、AssignProcessToJobObject はエラー アクセス拒否で失敗します。 thios cmd は既にジョブに割り当てられています。
私の問題を解決する方法はありますか?