2012-01-09 34 views
1

我想开始从Windows服务(本地系统)使用createProcessasUser桂托盘应用程序 - 像这样:CreateProcessasuser - AccessViolationError

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

感谢

+0

'lpEnvironment'被设置为一个有效的指针吗? 'userToken'是一个有效的'HANDLE'? – 2012-01-09 18:46:03

+0

你是怎么定义'CreateProcessAsUser'的? – 2012-01-09 18:54:11

+0

已添加定义。 – Menyh 2012-01-10 06:51:38

回答

1

是您ProcessInformation类型的值类型(结构)或引用类型(类)?

显示它的定义和P/Invoke的声明CreateProcessAsUser

BTW,所有GetLastWin32Error检查是你用p做/如果你使用正确的属性调用。

+0

[StructLayout(LayoutKind.Sequential)] 内部结构PROCESSINFORMATION { \t \t#地区数据成员(4) 公众诠释dwProcessId; public int dwThreadId; public IntPtr hProcess; public IntPtr hThread; \t \t #endregion数据成员 } – Menyh 2012-01-10 06:49:21

相关问题