我的设置是:
- Windows Server 2008, IIS 7
我想完成什么:
- IIS 7
- 从我的网站收到一个请求,要求执行一些 3D 操作(在 WPF 中),最后 IIS 7 应该呈现一个图像并将其存储在磁盘上的某个位置以加载到网站中
我所知道的和我已经测试过的:
- IIS 7 在 Windows Server 2008 上的会话 0 中作为服务运行 会话 0 中的任何服务
- 都无法访问视频驱动程序,即会话 0 中的任何服务都无法执行任何渲染任务(此处说明:会话 0 隔离)
- Microsoft在另一篇论文中建议在用户会话(通过CreateProcessAsUser)中创建一个进程以成功执行渲染。
到目前为止,我取得了什么成就:
- 登录用户运行良好
- 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);
}
我不是该领域的专家,只是做了一些搜索,似乎您实际上无法更改会话级别,而是应该有一个启用了自动登录的用户并与在该用户下运行的进程进行通信。
这似乎是最有用的:Windows 2008 RenderFarm Service:CreateProcessAsUser "Session 0 Isolation" 和 OpenGL