1

我的设置是:

  • 视窗服务器 2008、IIS 7

我想完成的事情:

  • IIS 7 从我的网站接收到执行一些 3D 操作(在 WPF 中)的请求,最后 IIS 7 应该渲染图像并将其存储在磁盘上的某个位置以加载到网站中

我所知道的以及我已经测试过的:

  • IIS 7 在 Windows Server 2008 上的会话 0 中作为服务运行
  • 会话 0 中的任何服务都无法访问视频驱动程序,即会话 0 中的任何服务都无法执行任何渲染任务(此处解释:会话 0 隔离
  • 微软在另一篇论文中建议在用户会话中创建一个进程(通过 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);
        }
4

1 回答 1

0

我不是该领域的专家,只是进行了一些搜索,似乎您实际上无法更改会话级别,而是您应该拥有一个启用了自动登录的用户并与在该用户下运行的进程进行通信。

这似乎是最有用的:Windows 2008 RenderFarm Service: CreateProcessAsUser "Session 0 Isolation" and OpenGL

于 2012-06-29T16:19:54.283 回答