Интерактивное приложение, работающее через службу Windows

#powershell

#powershell

Вопрос:

Я пытался запустить .net-приложение на основе меню через службу Windows. Приложение должно быть запущено нажатием клавиш Alt P и Alt S. Я создал сценарий Powershell для этого. При запуске этого скрипта в сеансе рабочего стола он работает нормально, но когда я запускаю его через службу Windows, он выходит из строя на этапе AppActivate. Может ли кто-нибудь помочь в том, как этого добиться? Это устаревшие приложения, и они хотели бы запускать их как есть через службу Windows в фоновом режиме, а не через сеанс пользователя.

Вот фрагмент кода powershell

 add-type -AssemblyName microsoft.VisualBasic
add-type -AssemblyName System.Windows.Forms

##  Application Name 

$Application="D:Application ServicesFile Transferx86Transfer.exe"
$ProgramName="Transfer"

### Validating whether the application already running
"Working..." | Out-File -Append "C:tempUpdate.log"

while ($true) 
{
    $Running = Get-Process $ProgramName -ErrorAction SilentlyContinue

    if ($Running -eq $null) 
    {
      ##  Start the process
      $Proc = Start-Process $Application

      ##  Wait for the process to appear
      Start-sleep -seconds 5

      while ( $Proc.Id -eq $null) {

           $Proc = Get-Process $ProgramName
      }

     "Process Information "    $Proc.Id | Out-File -Append "C:tempUpdate.log"

      ##  Get the Handle of the Application
      ##$WindowHandle = Get-Process | Where-Object { $_.MainWindowTitle -Match $ProgramName } | Select-Object -ExpandProperty MainWindowHandle

      ##  Point the focus to the Given application
      "[Microsoft.VisualBasic.Interaction]::AppActivate("   $Proc.Id   ")" | Out-File -Append "C:tempUpdate.log"

    [Microsoft.VisualBasic.Interaction]::AppActivate("Transfer")

     Start-sleep -seconds 5

     "Send Keys " | Out-File -Append "C:tempUpdate.log"
     ##  Pass the Key control to Start the application
     [System.Windows.Forms.SendKeys]::SendWait("%{p}s")

         "Started "   $Proc.Id   "  "   $Succ  | Out-File -Append "C:tempUpdate.log"
    }
 }
 

При запуске этого кода через службу Windows вызывается приложение, но оно не запускает приложение и выдает ошибку ниже

 Exception calling "AppActivate" with "1" argument(s): "Process '{0}' was not found."
At C:tempTransferApp.ps1:38 char:4
           [Microsoft.VisualBasic.Interaction]::AppActivate("Transfer")
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      FullyQualifiedErrorId : ArgumentException
 
Exception calling "SendWait" with "1" argument(s): "Access is denied"
At C:tempTransferApp.ps1:48 char:3
       $Succ=[System.Windows.Forms.SendKeys]::SendWait("%{p}s")
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      FullyQualifiedErrorId : Win32Exception
 

Комментарии:

1. PowerShell всегда запускается в контексте пользователя, который его запустил. Вы не можете запустить интерактивное приложение на основе графического интерфейса, без пользовательского контекста, это собственно Windows, а не PowerShell. Службы не являются пользовательским контекстом. Кроме того, PowerShell действительно не самый лучший вариант для автоматизации графического интерфейса. Лучше обратиться к таким инструментам, как AutoIt, даже используя их с PowerShell, но это все равно не подрывает / не вытесняет то, что требуется для Windows. На самом деле это не то, что использовать сервис для запуска интерактивных приложений. Интерактивный конкретно означает, что пользователь должен взаимодействовать с активным приложением, что невозможно для фонового процесса.

2. Спасибо за отзыв