私はこれについて何日も頭を悩ませてきました. インターネット上のすべてのページを読んだに違いありません. ヘルプ!
シナリオは次のとおりです。Windows 7 では、(サービスではなく) 管理者ユーザー アカウントでプロセスを実行しています。これは、後で通常のユーザー アカウントで実行される子プロセスで使用される名前付きグローバル ミューテックスを作成します。私が何をしても、またはミューテックスにどのような ACL を設定しても、ハンドルを取得しようとすると、子プロセスは Access Denied を返し続けます。
プロセスとミューテックスの部分を試すためだけに、コードをテスト アプリに要約しましたが、驚くべきことがわかりました。最初にミューテックスを作成せずにユーザー アプリから OpenMutex を呼び出すと、Not Found エラーが発生することが予想されますが、それでもアクセスが拒否されます。ただし、代わりにエクスプローラーからユーザー アプリを起動すると (Shift キーを押しながら右クリックし、別のユーザーとして実行...)、期待どおりの動作が得られます。また、管理アプリから起動すると、ユーザー アプリには通常の Windows テーマではなく、単純なブロック状のウィンドウ枠があることに気付きました。
したがって、ユーザーアプリの起動方法に問題があると思いますが、何が欠けているのかわかりません。
関連する部分は次のとおりです。
bool CUserTest::LogInUser()
{
if ((m_hUserToken == NULL) && !LogonUser(TEST_USER_NAME, L".", TEST_USER_PASS, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_hUserToken))
{
CloseHandle(m_hUserToken);
m_hUserToken = NULL;
}
return (m_hUserToken != NULL);
}
bool CUserTest::LaunchTestApp()
{
PROCESS_INFORMATION ProcInfo;
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(si);
si.lpDesktop = L"winsta0\\default";
wchar_t wszCmdLine[MAX_PATH + 1] = { 0 };
wcscpy(wszCmdLine, L"UserTestClient.exe");
bool bSuccess = false;
LPVOID pEnv;
PROFILEINFO sProfileInfo;
ZeroMemory(&sProfileInfo, sizeof(PROFILEINFO));
sProfileInfo.dwSize = sizeof(PROFILEINFO);
sProfileInfo.lpUserName = TEST_USER_NAME;
if (LoadUserProfile(m_hUserToken, &sProfileInfo))
{
if (ImpersonateLoggedOnUser(m_hUserToken))
{
if (CreateEnvironmentBlock(&pEnv, m_hUserToken, FALSE))
{
bSuccess = CreateProcessAsUser(
m_hUserToken,
NULL,
wszCmdLine,
NULL, // ProcessAttributes
NULL, // ThreadAttributes
FALSE, // InheritHandles
CREATE_UNICODE_ENVIRONMENT, // CreationFlags
pEnv, // Environment
NULL, // CurrentDirectory
&si,
&ProcInfo); // ProcessInformation
DestroyEnvironmentBlock(pEnv);
}
RevertToSelf();
}
UnloadUserProfile(m_hUserToken, sProfileInfo.hProfile);
}
if (bSuccess)
{
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess);
}
return bSuccess;
}