如何启动具有Windows服务UI的进程?

时间:2009-10-21 19:17:37

标签: windows-7-x64

我已经创建了一个服务应用程序,还有一个Windows窗体应用程序,现在我想要从服务中获取Windows应用程序。我知道在win7中因为服务isoloation 你不能直接这样做,所以我使用'advapi32.dll'方法的'CreateProcessAsUser',但它能够创建出现在'任务管理器'中的过程,但UI不会对用户不满意。是什么原因 ?任何人都可以帮我解决这个问题吗?

好的,让我给出我写的代码

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Ansi, EntryPoint = "CreateProcessAsUser")] 

public static extern bool CreateProcessAsUser(IntPtr hToken,string lpApplicationName,string lpCommandLine,ref SECURITY_ATTRIBUTES lpProcessAttributes, ref SECURITY_ATTRIBUTES lpThreadAttributes,bool bInheritHandles,int dwCreationFlags,string lpEnvironment,string lpCurrentDirectory,ref STARTUPINFO lpStartupInfo,ref PROCESS_INFORMATION lpProcessInformation);


void LounchNewApplication() 

{


 try

  { 

      string strAppName = @"D:\Working\UAC Demo\Tester\bin\Debug\Tester.exe"; 

      string strAppPath = @"D:\Working\UAC Demo\Tester\bin\Debug\";

      PROCESS_INFORMATION lpProcessInformation = new PROCESS_INFORMATION(); 

      SECURITY_ATTRIBUTES lpProcessAttributes = new SECURITY_ATTRIBUTES(); 

      lpProcessAttributes.nLength = (uint)Marshal.SizeOf(lpProcessAttributes); 

      STARTUPINFO lpStartupInfo = new STARTUPINFO(); 

      lpStartupInfo.cb = Marshal.SizeOf(lpStartupInfo); 

      lpStartupInfo.lpDesktop = "WinSta0\\Default"; 
      IntPtr htoken = IntPtr.Zero; 

      LogonUser("myName", "DomineName", "password", 2, 0, out htoken); 


      if (!CreateProcessAsUser(htoken, strAppName, null, ref lpProcessAttributes,
         ref lpProcessAttributes, true, 0, null, strAppPath, ref lpStartupInfo,
         ref lpProcessInformation)) 

        {

          eventLogger.WriteEntry("Error in starting application", EventLogEntryType.Error); 

        }
     else
         eventLogger.WriteEntry("Application launched successfulll" EventLogEntryType.Information); 




      //CloseHandle(lpProcessInformation.hThread);



      //CloseHandle(lpProcessInformation.hProcess);

  }



  catch (Exception ex) 

  {

    eventLogger.WriteEntry(ex.Message,


     EventLogEntryType.Error); 

  }

}

我正在调用服务的LounchNewApplication()方法OnStart。

2 个答案:

答案 0 :(得分:1)

您正在以用户身份启动该流程,但是在会话0中启动,这是非交互式的。不要使用LogonUser创建用户令牌。使用WTSQueryUserToken,传入要创建进程的会话。此令牌具有正确的会话ID。您可以使用WTSEnumerateSessions列出计算机上的所有会话,或在服务处理程序中处理会话更改通知。

答案 1 :(得分:0)

从技术上讲,服务必须标记为交互式,例如。 sc config <servicename> type= interact

服务不应该与控制台交互,并且绝对不能在服务启动中。幸运的是,这在Windows 2003之后得到了修复,在Vista中,Windows 2008和Windows 7越来越难以做到这种不端行为。

正确的方法是将您的应用程序分成服务和监视器应用程序。监视器作为用户会话上的普通应用程序运行,并通过IPC与服务进行通信。