C# CreateProcessasuser-AccessViolationError

C# CreateProcessasuser-AccessViolationError,c#,windows,winapi,uac,C#,Windows,Winapi,Uac,我正在尝试使用createProcessasUser从windows服务(LocalSystem)启动Gui托盘应用程序,如下所示: public static System.Diagnostics.Process StartProcessInSession(int sessionID, String commandLine) { IntPtr userToken; if (WTSQueryUserToken(sessionID, out user

我正在尝试使用createProcessasUser从windows服务(LocalSystem)启动Gui托盘应用程序,如下所示:

    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");  
    }
这实际上起作用了一段时间,但在我的一次跑步中,它突然停止了工作。。。执行CreateProcessAsUser命令时出现以下错误(无法再深入)

我不知道为什么会发生这种情况,甚至不知道如何进一步调试,无论如何,我有什么想法??因为这对我来说毫无意义

CreateProcessAsUser定义:

[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);

谢谢

您的
处理信息
是值类型(结构)还是引用类型(类)

显示其定义和
CreateProcessAsUser
的p/invoke声明


顺便说一句,如果您使用了正确的属性,则所有
GetLastWin32Error
检查都由p/invoke为您完成。

您的
ProcessInformation
是键入值类型(结构)还是引用类型(类)

显示其定义和
CreateProcessAsUser
的p/invoke声明


顺便说一句,如果使用了正确的属性,所有
GetLastWin32Error
检查都由p/invoke完成。

是否将
lpEnvironment
设置为有效指针?和
userToken
一个有效的
HANDLE
?您如何定义
CreateProcessAsUser
?这两个值都在设置中,我该如何确定句柄是否有效?@Menyh:basic是:不是0,不是-1,是四的倍数。除此之外,您还可以使用Process Monitor列出应用程序的有效句柄。
lpEnvironment
是否设置为有效指针?和
userToken
一个有效的
HANDLE
?您如何定义
CreateProcessAsUser
?这两个值都在设置中,我该如何确定句柄是否有效?@Menyh:basic是:不是0,不是-1,是四的倍数。除此之外,您还可以使用Process Monitor列出应用程序的有效句柄。[StructLayout(LayoutKind.Sequential)]内部结构ProcessInformation{#区域数据成员(4)public int dwProcessId;public int dwThreadId;public IntPtr hProcess;public IntPtr hThread;#endregion数据成员}[StructLayout(LayoutKind.Sequential)]内部结构进程信息{#区域数据成员(4)public int dwProcessId;public int dwThreadId;public IntPtr hProcess;public IntPtr hThread;#endregion Data Members}
[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);