CreateProcessasuser - ข้อผิดพลาดในการละเมิดการเข้าถึง

ฉันกำลังพยายามเริ่มแอปพลิเคชันถาด Gui จากบริการ windows (LocalSystem) โดยใช้ createProcessasUser - เช่น:

    public static System.Diagnostics.Process StartProcessInSession(int sessionID, String commandLine)
    {
        IntPtr userToken;
        if (WTSQueryUserToken(sessionID, out userToken))
        {
            //note that WTSQueryUserToken only works when in context of local system account with SE_TCB_NAME
            IntPtr lpEnvironment;
            if (CreateEnvironmentBlock(out lpEnvironment, userToken, false))
            {
                StartupInfo si = new StartupInfo();
                si.cb = Marshal.SizeOf(si);
                si.lpDesktop = "winsta0\\default";
                si.dwFlags = STARTF.STARTF_USESHOWWINDOW;
                si.wShowWindow = ShowWindow.SW_SHOW;
                ProcessInformation pi;
                if (CreateProcessAsUser(userToken, null, new StringBuilder(commandLine), IntPtr.Zero, IntPtr.Zero, false, CreationFlags.CREATE_NEW_CONSOLE | CreationFlags.CREATE_UNICODE_ENVIRONMENT, lpEnvironment, null, ref si, out pi))
                {
                    CloseHandle(pi.hThread);
                    CloseHandle(pi.hProcess);
                    //context.Undo();
                    try
                    {
                        return System.Diagnostics.Process.GetProcessById(pi.dwProcessId);
                    }
                    catch (ArgumentException e)
                    {
                        //The process ID couldn't be found - which is what always happens because it has closed
                        return null;
                    }
                }
                else
                {
                    int err = Marshal.GetLastWin32Error();
                    throw new System.ComponentModel.Win32Exception(err, "Could not create process.\nWin32 error: " + err.ToString());
                }
            }
            else
            {
                int err = Marshal.GetLastWin32Error();
                throw new System.ComponentModel.Win32Exception(err, "Could not create environment block.\nWin32 error: " + err.ToString());
            }
        }
        else
        {
            int err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
            if (err == 1008) return null; //There is no token
            throw new System.ComponentModel.Win32Exception(err, "Could not get the user token from session " + sessionID.ToString() + " - Error: " + err.ToString());
        }
    }

ฉันใช้ฟังก์ชันดังนี้:

   protected override void OnStart(string[] args)
    {   
       _agentProcess = StartProcessInSession(WTSGetActiveConsoleSessionId(), "Some_correct_path");  
    }

สิ่งนี้ใช้งานได้จริงมาระยะหนึ่งแล้ว แต่ในการรันครั้งหนึ่งของฉัน มันหยุดทำงานกะทันหัน... ให้ข้อผิดพลาดต่อไปนี้เมื่อดำเนินการคำสั่ง CreateProccessAsUser (ไม่สามารถลงลึกกว่านี้ได้)

{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}

ฉันไม่รู้ว่าทำไมสิ่งนี้ถึงเกิดขึ้นหรือแม้แต่จะแก้ไขข้อบกพร่องนี้ต่อไปได้อย่างไร มีความคิดบ้างไหม? เพราะสิ่งนี้ไม่สมเหตุสมผลสำหรับฉัน

นิยาม CreateProccessasuser:

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        static extern bool CreateProcessAsUser(IntPtr hToken, String lpApplicationName, [In] StringBuilder lpCommandLine, IntPtr /*to a SecurityAttributes struct or null*/ lpProcessAttributes, IntPtr /*to a SecurityAttributes struct or null*/ lpThreadAttributes, bool bInheritHandles, CreationFlags creationFlags, IntPtr lpEnvironment, String lpCurrentDirectory, ref StartupInfo lpStartupInfo, out ProcessInformation lpProcessInformation);

ขอบคุณ


person Menyh    schedule 09.01.2012    source แหล่งที่มา
comment
lpEnvironment ถูกตั้งค่าเป็นตัวชี้ที่ถูกต้องหรือไม่ และ userToken ถูกต้อง HANDLE?   -  person Ben Voigt    schedule 09.01.2012
comment
คุณให้คำนิยาม CreateProcessAsUser อย่างไร   -  person David Heffernan    schedule 09.01.2012
comment
กำลังตั้งค่าทั้งสองค่า ฉันจะทราบได้อย่างไรว่าหมายเลขอ้างอิงนั้นถูกต้องหรือไม่   -  person Menyh    schedule 10.01.2012
comment
@Menyh: พื้นฐานคือ: ไม่ใช่ 0 ไม่ใช่ -1 และผลคูณของสี่ นอกจากนั้น คุณสามารถใช้ Process Monitor เพื่อแสดงรายการตัวจัดการที่ถูกต้องสำหรับแอปพลิเคชันได้   -  person Ben Voigt    schedule 10.01.2012


คำตอบ (1)


ประเภท ProcessInformation ของคุณเป็นประเภทค่า (struct) หรือประเภทอ้างอิง (คลาส) หรือไม่

แสดงคำจำกัดความและการประกาศ p/incall สำหรับ CreateProcessAsUser

BTW การตรวจสอบ GetLastWin32Error ทั้งหมดนั้นเสร็จสิ้นเพื่อคุณโดย p/incall หากคุณใช้แอตทริบิวต์ที่ถูกต้อง

person Ben Voigt    schedule 09.01.2012
comment
[StructLayout (LayoutKind.Sequential)] โครงสร้างภายใน ProcessInformation { #region Data Members (4) public int dwProcessId; สาธารณะ int dwThreadId; สาธารณะ IntPtr hProcess; สาธารณะ IntPtr hThread; #สมาชิกข้อมูล endregion } - person Menyh; 10.01.2012