Как отправить входные данные в [Console] :: In.ReadLine () из родительского процесса? - PullRequest
2 голосов
/ 22 июня 2019

Starter используется для запуска процесса целевого сценария:

# STARTING PS (TARGET) SCRIPT COMPILED TO EXE 
$processStartInfo = New-Object System.Diagnostics.ProcessStartInfo
$processStartInfo.FileName = $somePath
$processStartInfo.WorkingDirectory = (Get-Location).Path
$processStartInfo.RedirectStandardInput = $true
$processStartInfo.RedirectStandardError = $true
$processStartInfo.UseShellExecute = $false
$process = [System.Diagnostics.Process]::Start($processStartInfo)

# SOME OTHER CODE ...

# HERE I'M SENDING "EXIT" TO RUNSPACE RUNNING INSIDE TARGET SCRIPT
$process.StandardInput.WriteLineAsync("exit") | Out-Null

Целевой скрипт (скомпилированный в * .exe) создает пространство выполнения, которое синхронно ожидает ReadLine данных от starter

function main {
  . createRunspace
  while ($true) {
     # PARENT LOOP RUNS IN PARALLEL TO RUNSPACE LOOP
     sleep -s 1
     try {
       if ($hash.flags.exit) {
         # CLEAN UP AND BREAK
       } else {
         # RUN OTHER CODE
       }
     } catch {
       # CAN NOT NOTIFY RUNSPACE ABOUT ERROR USING SYNCHRONIZED HASTABLE,
       # BECAUSE RUNSPACE IS STUCK ON `ReadLine`.
       # ALSO CAN NOT WRITE TO STANDRAD INPUT (DON'T KNOW HOW).
     }
  }
}

function createRunspace {
  #CREATING RUNSPACE WITH SYNCHRONIZED HASTABLE
  $hash = [hashtable]::Synchronized(@{ flags: @{} })
  $runspace= [runspacefactory]::CreateRunspace()
  $runspace.Open()
  $runspace.SessionStateProxy.SetVariable('hash', $hash)
  $powershell= [powershell]::Create()
  $powershell.Runspace = $runspace
  $powershell.AddScript({
    # RUNSPACE LOOP
    while ($true) {
      $value  = [Console]::In.ReadLine()
      if ($value -eq "exit") {
         $hash.flags.exit = $true
         break
      } elseif ($value -eq "valueFromParent") {
         # DO STUFF
      }
    }
  }) | Out    
}

# OTHER CODE
. main 

Есть ли способ отправить standard input данные из parent в пространство выполнения?

1 Ответ

1 голос
/ 23 июня 2019

Скрипт PowerShell-script-packaged-as-an- *.exe, который вы используете , по какой-то причине не передает ввод stdin в завернутый скрипт, поэтому ваш скрипт никогда не получит"exit" строка, которую вы отправляете от звонящего.

Я не знаю ваших точных требований, но вот очень упрощенное решение, которое показывает, что ваш подход работает в принципе:

# The code to execute in the background.
$backgroundScript = {
  while ($true) {
    $value = [Console]::In.ReadLine()
    if ($value -eq "exit") {
      "Background: Exiting."
      break
    }
    else {
      "Background: Performing task: $value"
    }
  }
}

# Start the background script.
$processStartInfo = [System.Diagnostics.ProcessStartInfo] @{
  FileName = "powershell.exe"
  Arguments = '-NoProfile', '-Command', $backgroundScript -replace '"', '\"'
  WorkingDirectory = $PWD.ProviderPath
  RedirectStandardInput = $true
  RedirectStandardError = $true
  RedirectStandardOutput = $true
  UseShellExecute = $false
}
$process = [System.Diagnostics.Process]::Start($processStartInfo)

# Ask the background script to perform a task.
"Submitting task 'doStuff'"
$process.StandardInput.WriteLine("doStuff")

# Ask the background script to exit.
"Submitting exit request."
$process.StandardInput.WriteLine("exit")

# Wait for the background script's process to exit,
# then print its stdout.
$process.WaitForExit()
$process.StandardOutput.ReadToEnd()

выше урожайности:

Submitting task 'doStuff'
Submitting exit request.
Background: Performing task: doStuff
Background: Exiting.
...