1

My setting is:

  • Windows Server 2008, IIS 7

What I would like to accomplish:

  • IIS 7 receives a request from my website to do some 3D operations (in WPF) and in the end IIS 7 should render an image and store it somewhere on the disk to get loaded into the website

What I know and what I already have tested yet:

  • IIS 7 runs as service in session 0 on Windows Server 2008
  • no service in session 0 has access to the video driver, that is no service in session 0 can perform any rendering tasks (explained here: Session 0 Isolation)
  • Microsoft proposes in another paper to create a process in a user session (by CreateProcessAsUser) to perform rendering sucessfully.

What I achieved up until now:

  • LogonUser works well
  • CreateProcessAsUser works well

The only (but important) part that doesn't work: When I logon with username and password and create a process as user, the process is still in session 0 and therefore rendering fails. The user logged on successfully (I checked it). According to Microsoft it must be possible to create a process in a user session (not session 0).

  • How can I create a process as user in other session than 0?
  • Do I have to create a new session myself or something like this?

Thank you!

My code:

        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);
        }
manton
  • 541
  • 1
  • 6
  • 26

1 Answers1

0

I'm not an expert in that field, just did some searching around and it seems that you cannot actually change session level, rather you should have a user with auto-logon enabled and communicate with a process running under that user.

This seemed the most useful: Windows 2008 RenderFarm Service: CreateProcessAsUser "Session 0 Isolation" and OpenGL

Community
  • 1
  • 1
hege
  • 987
  • 4
  • 15