Как я могу запустить процесс с пользовательским интерфейсом из службы Windows? - PullRequest
1 голос
/ 21 октября 2009

Я создал приложение-службу, а также приложение Windows Form. Теперь я хочу запустить приложение Windows из службы. Я знаю, что в win7 из-за изоляции сервиса Вы не можете сделать это напрямую, поэтому я использовал метод CreateProcessAsUser метода advapi32.dll, но он может создать процесс, также отображаемый в «Диспетчере задач», но пользовательский интерфейс не будет вызывать недовольство пользователя. Какова причина ? кто-нибудь может мне помочь из этого?

Хорошо, позвольте мне дать код, который я написал

[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 ]

1 голос
/ 21 октября 2009

Вы запускаете процесс как пользователь, но в сеансе 0, который не является интерактивным. Не используйте LogonUser для создания токена пользователя. Используйте WTSQueryUserToken , передавая сеанс, в котором вы хотите создать процесс. Этот токен имеет правильный идентификатор сеанса. Вы можете использовать WTSEnumerateSessions для вывода списка всех сеансов на компьютере или обработки уведомлений об изменениях сеансов в обработчике службы.

0 голосов
/ 21 октября 2009

Технически, сервис должен быть помечен как интерактивный, например. sc config <servicename> type= interact.

Службы не должны взаимодействовать с консолью и, безусловно, не должны запускаться при запуске службы. К счастью, это было исправлено после Windows 2003, а в Vista, Windows 2008 и Windows 7 становилось все сложнее и сложнее совершать такое поведение.

Правильный способ - разделить ваше приложение на приложение-службу и приложение-монитор. Монитор работает как обычное приложение в сеансе пользователя и связывается со службой через IPC.

...