Как смоделировать пакетный скрипт - PullRequest
0 голосов
/ 07 июня 2018

Мне нужно настроить скрипт PowerShell на основе пакетного скрипта.Исходный пакетный скрипт выглядит следующим образом:

call %SYSTEMROOT%\setup_Env.BAT
command_name command_arguments

Команда зависит от переменных среды из setup_ENV.BAT, который настраивается.

$tempFile = [IO.Path]::GetTempFileName()
$script = "%SYSTEMROOT%\setup_Env.BAT"
cmd /c " $script && set > $tempFile "
cmd /c " command_name command_arguments"

Я получил ошибку:

cmd: 'имя_команды не распознается как внутренняя или внешняя команда, ...

Если есть лучший способ сделать это в PowerShell, я открыт для него.

1 Ответ

0 голосов
/ 07 июня 2018

Вам нужно передать одну командную строку cmd, чтобы сделать эту работу:

cmd /c "call %SYSTEMROOT%\setup_Env.BAT && command_name command_arguments"

As Ansgar Wiechers указывает на то, что каждый вызов cmd выполняется в дочернем процессе, и любые изменения среды, сделанные в дочернем процессе, невидимы для вызывающего процесса и, следовательно, также не для будущих дочерних процессов.

В отличие от этого, вединственной командной строкой выше, изменения переменной среды, выполняемые setup_Env.BAT , видны command_name к моменту его выполнения.


Предупреждение : Если command_arguments содержит %...% ссылки в стиле на окружение переменных, определенных в setup_Env.BAT, требуется дополнительная работа:

  • Изменить %...% -стиль ссылки на !...! -стиль ссылки.
  • Дополнительно вызовите cmd с /v, чтобы включить отложенное расширение переменной (эквивалент setlocal enabledelayedexpansion внутри скрипта`:

    cmd /v /c "call %SYSTEMROOT%\setup_Env.BAT && command_name args_with_delayed_var_refs"
    

Предостережение : выше может все еще не работать должным образом, если command_arguments содержит ! символов.это следует рассматривать как литералы (и / или command_name - другой пакетный файл, содержащий такие данные).

В этом случае самый простой подход состоит в простом воссозданиивесь пакетный файл во временном файле и вызвать это :

# Get temp. file path
$tempBatFile = [IO.Path]::GetTempFileName() + '.bat'

# Write the content of the temp. batch file
@'
@echo off
call %SYSTEMROOT%\setup_Env.BAT
command_name command_arguments
'@ | Set-Content $tempBatFile

# Execute it.
& $tempBatFile 

# Clean up.
Remove-Item -LiteralPath $tempBatFile
...