1
我的設置是:CreateProcessAsUser在用戶會話(0以外)從服務(IIS 7)
- Windows Server 2008中,IIS 7
我想什麼來完成:
- IIS 7從我的網站收到一個請求(在WPF中)執行一些3D操作,最後IIS 7應該呈現圖像並將其存儲在磁盤上的某處以加載到網站中
我知道什麼,我已經測試過:
- IIS 7箇中運行的服務會話0的Windows Server 2008
- 在會話0沒有服務就可以訪問視頻驅動器上,該在會話0中沒有服務可以執行任何呈現任務(在這裏解釋:Session 0 Isolation)
- 微軟在另一篇文章中建議在用戶會話(由CreateProcessAsUser)中創建一個進程以成功執行呈現。
我取得了什麼到現在爲止:
- LogonUser的效果很好
- CreateProcessAsUser效果很好
唯一的(但很重要)的部分不工作: 當我使用用戶名和密碼登錄並以用戶身份創建進程,該進程仍在會話0中,因此呈現失敗。用戶登錄成功(我檢查了它)。根據微軟的說法,必須有可能在用戶會話中創建一個進程(而不是會話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);
}