Как я могу передать переменную из одного сценария PS в другой через VBS? - PullRequest
3 голосов
/ 03 марта 2020

Я работаю над сценарием PowerShell с GUI с 3 файлами:

  • window1.ps1 - ввод в переменную и запускается start.vbs
  • start.vbs - начинается window2.ps1
  • window2.ps1 - отображает значение, введенное в окне 1

В окне 1 я ввожу value1 в textbox1 и нажимаю button.

gui window 1

Нажав на него, value1 должен быть сохранен в global variable, чтобы window2 мог всплыть (через VBS) и использовать value1.

код для button в window1:

$button_OnClick= 
{
    $global:value1 = $textBox1.Text
    start-process .\start.vbs
}

start.vbs:

Set objShell = CreateObject("Wscript.Shell")
objShell.run("powershell.exe -nologo -file .\window2.ps1"), 0, True

Пока все хорошо. Насколько я понимаю, value1 является глобальной переменной и может использоваться в window2.ps1.

Так что window2 - это пустое окно, в котором только текст должен отображать value1.

$label1.Text = "$value1"

Но по какой-то причине переменная пуста, а window2 пуста.

gui window 2

Чего мне не хватает? Я все еще изучаю PowerShell, и мне может не хватать деталей.

Примечание: я знаю, как странно открывать window2 через .vbs. Но в этом случае GUI открывается без окна PowerShell в фоновом режиме.

1 Ответ

5 голосов
/ 03 марта 2020

«Глобальная переменная» - это не то, что волшебным образом доступно каждому процессу на вашем компьютере. Вы запускаете два совершенно отдельных процесса PowerShell. Ни один из их компонентов не является общим.

Вам нужно дать значение в качестве аргумента командной строки для второго процесса PowerShell, если вы хотите использовать его там.

И это означает, что вы должны дать значение, которое ваш первый сценарий PowerShell генерирует в качестве аргумента командной строки для вашего промежуточного VBScript, потому что это тоже совершенно отдельный процесс.

Первый сценарий PowerShell вызывает wscript.exe с двумя аргументами (имя и значение сценария):

$button_OnClick= 
{
    $value1 = $textBox1.Text
    Start-Process wscript.exe "window2.vbs","`"$value1`""
}

Если пользователь ввел Hello World!, он выполнит командную строку (обратите внимание на кавычки, они гарантируют, что значения с пробелами не будут рассматриваться как отдельные аргументы):

wscript.exe window2.vbs "Hello World!"

Посредник VBS может затем прочитать Hello World! из его первого аргумента командной строки (кавычки будут удалены, поэтому нам нужно добавить их обратно для следующего вызова):

value1 = WScript.Arguments.Unnamed(0)

Set objShell = CreateObject("Wscript.Shell")
objShell.run("powershell.exe -nologo -file .\window2.ps1 """ & value1 & """"), 0, True

теперь выполняется следующая командная строка:

powershell.exe -nologo -file .\window2.ps1 "Hello World!"

Второй сценарий PowerShell может затем извлечь Hello World! из своего первого аргумента командной строки, так же, как это делал VBScript (кавычки будут снова удалены):

$label1.Text = $args[0]

Я бы порекомендовал вам создать VBScript windowless.vbs, который может запускать практически любую команду без окон:

' windowless.vbs
For Each arg In WScript.Arguments
    If InStr(arg, " ") > 0 Then
        cmd = cmd & """" & arg & """ "
    Else
        cmd = cmd & arg & " "
    End If
Next
CreateObject("WScript.Shell").Run(Trim(cmd)), 0, True

и затем используйте его в своем скрипте PowerShell

$value1 = "Hello World!"
Start-Process wscript.exe "windowless.vbs","powershell.exe","-nologo","-file window2.ps1","`"$value1`""

, который создаст эту командную строку

powershell.exe -nologo -file .\window2.ps1 "Hello World!"

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...