Запуск удаленного приложения с графическим интерфейсом в Powershell - PullRequest
16 голосов
/ 26 августа 2010

У нас есть пользовательский компонент, который включает некоторые функциональные возможности powershell, поэтому его можно использовать в BizTalk 2006. Для большинства операций (проверка пути к файлу, копирование или перемещение файла) это работает нормально. Однако нам нужно удаленно запустить приложение с графическим интерфейсом, чтобы выполнить некоторую обработку. Компонент сам обрабатывает соединение с удаленным блоком, все, что нам нужно сделать, это установить некоторые параметры и затем сказать ему выполнить команду

Start-Process -FilePath "path to exe" -ArgumentList "arguments for exe" -WorkingDirectory "workingdir for exe"

Проблема заключается в следующем: если мы запустим это из командной строки powershell на самой коробке, это будет работать нормально. Однако, когда мы запускаем его удаленно (из BizTalk, из тестового жгута, даже используя удаленную командную строку Powershell и соединение через Start-PSSession), это приложение будет работать недолго, а затем завершать работу, фактически ничего не делая. Я подозреваю, что, поскольку рассматриваемый exe-файл требует загрузки графического интерфейса для запуска процесса, именно это вызывает проблему. Я перепробовал все, что мог придумать, включая -NoNewWindow и -WindowStyle, но безрезультатно. Любая помощь в получении этой работы будет очень признательна.

Примечание. У нас нет доступа к исходному коду приложения, которое мы пытаемся запустить, поскольку оно является более старым приложением win32, и пакетная или командная версия этого приложения не была предоставлена.

Ответы [ 2 ]

18 голосов
/ 25 октября 2010

Используя стандартные методы PowerShell (WinRM, WMI), вы не можете запускать приложения с графическим интерфейсом. Единственное решение, о котором я знаю, - это использование PsExec от SysInternals (или аналогичных инструментов). Он может запускать приложения, которые предоставляют пользователю графический интерфейс. Ваша командная строка будет выглядеть так:

& ".\psexec" -accepteula -i "\\computername" -u "domain\username" -p "password" "command line"
  • -accepteula - молча принять EULA.
  • -i - разрешить графический интерфейс.

Другие решения более хакерские, включая удаленное добавление задач в планировщик.

7 голосов
/ 31 мая 2016

Так как я столкнулся с этим недавно, вот мое решение, использующее предложение Discord о добавлении удаленной задачи. Я предпочел «взломать», а не настраивать отдельный инструмент.

function Start-Process-Active
{
    param
    (
        [System.Management.Automation.Runspaces.PSSession]$Session,
        [string]$Executable,
        [string]$Argument,
        [string]$WorkingDirectory,
        [string]$UserID,
        [switch]$Verbose = $false

    )

    if (($Session -eq $null) -or ($Session.Availability -ne [System.Management.Automation.Runspaces.RunspaceAvailability]::Available))
    {
        $Session.Availability
        throw [System.Exception] "Session is not availabile"
    }

    Invoke-Command -Session $Session -ArgumentList $Executable,$Argument,$WorkingDirectory,$UserID -ScriptBlock {
        param($Executable, $Argument, $WorkingDirectory, $UserID)
        $action = New-ScheduledTaskAction -Execute $Executable -Argument $Argument -WorkingDirectory $WorkingDirectory
        $principal = New-ScheduledTaskPrincipal -userid $UserID
        $task = New-ScheduledTask -Action $action -Principal $principal
        $taskname = "_StartProcessActiveTask"
        try 
        {
            $registeredTask = Get-ScheduledTask $taskname -ErrorAction SilentlyContinue
        } 
        catch 
        {
            $registeredTask = $null
        }
        if ($registeredTask)
        {
            Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
        }
        $registeredTask = Register-ScheduledTask $taskname -InputObject $task

        Start-ScheduledTask -InputObject $registeredTask

        Unregister-ScheduledTask -InputObject $registeredTask -Confirm:$false
    }

}
...