私の設定は次のとおりです。
- Windows Server 2008、IIS 7
私が達成したいこと:
- IIS 7 は私の Web サイトからいくつかの 3D 操作を (WPF で) 実行する要求を受け取り、最終的に IIS 7 はイメージをレンダリングし、それをディスクのどこかに保存して Web サイトにロードする必要があります。
私が知っていることと、すでにテストしたこと:
- IIS 7 は、Windows Server 2008 のセッション 0 でサービスとして実行されます
- セッション 0 のサービスはビデオ ドライバーにアクセスできません。つまり、セッション 0 のサービスはレンダリング タスクを実行できません (ここで説明:セッション 0 分離)
- Microsoft は別の論文で、レンダリングを正常に実行するために (CreateProcessAsUser によって) ユーザー セッションでプロセスを作成することを提案しています。
私が今までに達成したこと:
- LogonUserはうまく機能します
- CreateProcessAsUser はうまく機能します
機能しない唯一の (しかし重要な) 部分: ユーザー名とパスワードでログオンし、ユーザーとしてプロセスを作成すると、プロセスはまだセッション 0 にあるため、レンダリングが失敗します。ユーザーは正常にログオンしました(確認しました)。Microsoft によれば、(セッション 0 ではなく) ユーザー セッションでプロセスを作成できる必要があります。
- 0 以外のセッションでユーザーとしてプロセスを作成するにはどうすればよいですか?
- 自分で新しいセッションを作成する必要がありますか?
ありがとうございました!
私のコード:
PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();
STARTUPINFO startInfo = new STARTUPINFO();
Boolean bResult = false;
IntPtr hToken = IntPtr.Zero;
UInt32 uiResultWait = WAIT_FAILED;
int processCreationFlags;
try
{
// Logon user
bResult = Win32.LogonUser(
strName,
strDomain,
strPassword,
Win32.LogonType.LOGON32_LOGON_BATCH,
Win32.LogonProvider.LOGON32_PROVIDER_DEFAULT,
out hToken
);
if (!bResult) { throw new Exception("Logon error #" + Marshal.GetLastWin32Error()); }
CheckPrivileges(hToken);
// Create process
startInfo.cb = Marshal.SizeOf(startInfo);
startInfo.lpDesktop = null;
startInfo.dwFlags = Convert.ToInt32(STARTF.STARTF_USESHOWWINDOW);
startInfo.wShowWindow = Convert.ToInt16(SHOWWINDOW.SW_HIDE);
processCreationFlags = Convert.ToInt32(CreateProcessFlags.CREATE_BREAKAWAY_FROM_JOB);
retStr += "command line: " + strCommand + Environment.NewLine;
bResult = Win32.CreateProcessAsUser(
hToken,
null, //application name
strCommand, //command line
IntPtr.Zero, //process attributes
IntPtr.Zero, //thread attributes
false, //inherit handles
processCreationFlags, //process creation flags
IntPtr.Zero, //environment
curDir, //current directory
ref startInfo,
out processInfo
);
if (!bResult) { throw new Exception("CreateProcessAsUser error #" + Marshal.GetLastWin32Error()); }
// Wait for process to end
uiResultWait = WaitForSingleObject(processInfo.hProcess, INFINITE);
if (uiResultWait == WAIT_FAILED) { throw new Exception("WaitForSingleObject error #" + Marshal.GetLastWin32Error()); }
}
finally
{
// Close all handles
CloseHandle(hToken);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
}