Подтвердить что ты не робот

Как вызвать пакетную версию script от Powershell?

У меня есть одна большая партия script, которая устанавливает набор переменных среды. Я хочу называть этот пакет script из powershell, таким образом, я могу получить преимущества как переменной окружения, установленной моей script, так и powershell.

4b9b3361

Ответ 1

Идея исходит из этого сообщения в блоге: Ничего не решает все - PowerShell и другие технологии

Вот моя версия этого script. Он вызывает командный файл (или любую собственную команду) и распространяет его среду:


UPDATE: улучшенная и улучшенная версия этого script находится здесь: Invoke-Environment.ps1

<#
.SYNOPSIS
    Invokes a command and imports its environment variables.

.DESCRIPTION
    It invokes any cmd shell command (normally a configuration batch file) and
    imports its environment variables to the calling process. Command output is
    discarded completely. It fails if the command exit code is not 0. To ignore
    the exit code use the 'call' command.

.PARAMETER Command
        Any cmd shell command, normally a configuration batch file.

.EXAMPLE
    # Invokes Config.bat in the current directory or the system path
    Invoke-Environment Config.bat

.EXAMPLE
    # Visual Studio environment: works even if exit code is not 0
    Invoke-Environment 'call "%VS100COMNTOOLS%\vsvars32.bat"'

.EXAMPLE
    # This command fails if vsvars32.bat exit code is not 0
    Invoke-Environment '"%VS100COMNTOOLS%\vsvars32.bat"'
#>

param
(
    [Parameter(Mandatory=$true)] [string]
    $Command
)

cmd /c "$Command > nul 2>&1 && set" | .{process{
    if ($_ -match '^([^=]+)=(.*)') {
        [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
    }
}}

if ($LASTEXITCODE) {
    throw "Command '$Command': exit code: $LASTEXITCODE"
}

P.S. Вот предложение добавить аналогичную возможность в PowerShell: Расширить концепцию источника dot в файлах cmd

Ответ 2

Если вы захватите Расширения сообщества PowerShell, в нем есть команда Invoke-BatchFile, которая запускает командный файл, но что более важно, он сохраняет любые изменения переменных среды, выполненные командным файлом, например:

>Invoke-BatchFile 'C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat'
Setting environment for using Microsoft Visual Studio 2008 x86 tools.

Ответ 3

Можно ли преобразовать пакет script в PowerShell script? Если вы запустите файл bat, он выполняется в отдельном сеансе, который не изменяет переменные env PowerShell.

Вы можете работать с переменными env очень плавно:

PS> Get-ChildItem env:

Name                           Value
----                           -----
ALLUSERSPROFILE                C:\ProgramData
APPDATA                        C:\Users\xyz\AppData\Roaming
CommonProgramFiles             C:\Program Files (x86)\Common Files
CommonProgramFiles(x86)        C:\Program Files (x86)\Common Files
CommonProgramW6432             C:\Program Files\Common Files
COMPUTERNAME                   xyz
ComSpec                        C:\Windows\system32\cmd.exe
DXSDK_DIR                      D:\prgs\dev\Microsoft DirectX SDK (August 2009)\
FP_NO_HOST_CHECK               NO
HOMEDRIVE                      Z:
HOMEPATH                       \
...

PS> Get-Item env:path
Name  Value
----  -----
Path  c:\dev\CollabNet\SubversionClient;C:\Windows\system32;...

Или даже (намного короче, возвращает только строку):

PS> $env:path
c:\dev\CollabNet\Subversion Client;C:\Windows\system32;...

Вы можете изменить путь к среде следующим образом:

PS> $env:path += ";c:\mydir"

И вы можете даже установить переменные среды на уровне машины следующим образом:

# fist arg = env variable name, second = value, third = level, available are 'Process', 'User', 'Machine'
PS> [Environment]::SetEnvironmentVariable('test', 'value', 'machine')

Ответ 4

Вы можете запустить пакет script из Powershell, просто поместив его имя, но это вам не поможет. Переменные окружения, заданные в пакете script, будут видны только из этой партии и всего, что запускается. Как только элемент управления вернется в PowerShell, переменные среды исчезнут. Вы могли бы запустить пакет script запустите set в конце, а затем проанализировать его вывод в переменных среды PSH.

Ответ 5

Решение @Roman Kuzmin прекрасно работает, но передача вывода команды в nul может оставить вас в неведении. Поэтому я сделал несколько настроек, чтобы вывод команды отображался нормально, и вместо этого направил env vars во временный файл для последующего чтения:

param
(
    [Parameter(Mandatory=$true)] [string]
    $Command
)
$VarsPath = [IO.Path]::GetTempFileName()
cmd /c "$Command && set > $VarsPath"
if (-not $LASTEXITCODE) {
    Get-Content $VarsPath | ForEach-Object {
        if ($_ -match '^([^=]+)=(.*)') {
            [System.Environment]::SetEnvironmentVariable($matches[1], $matches[2])
        }
    }
}
Remove-Item $VarsPath