Как лучше всего программировать против изменчивости powershell x64 и x86? - PullRequest
8 голосов
/ 02 марта 2009

У нас есть несколько сценариев, которые мы используем для установки и настройки зависимостей, поддерживающих системы, которые мы поддерживаем. Мы запускаем их в любое время, когда создаем среду разработки, тестирования, демонстрации, обучения, разработки и т. Д. Мы часто обнаруживаем, что имеем дело с архитектурой x64 и x86, особенно когда речь идет о сценариях powershell.

Например, у меня есть скрипт, который использует Расширения PowerShell для установщика Windows , чтобы определить, была ли установлена ​​программа / исправление. Сценарий не работает в среде x64 без явного вызова PowerShell (x86), который по умолчанию отсутствует в пути. Поскольку мы переносим эти сценарии на платформу x64, было бы здорово поддерживать единый набор сценариев, которые работают в powershell на обеих архитектурах и вызывают код x86 только при необходимости.

Кто-нибудь знает стратегию для этого?

Ответы [ 2 ]

16 голосов
/ 02 марта 2009

Я часто сталкиваюсь с этой проблемой с помощью своих конфигурационных скриптов. Основной подход, который я использую, заключается в

  1. Используйте несколько функций, чтобы проверить, нахожусь ли я в 64-битной среде (http://blogs.msdn.com/jaredpar/archive/2008/10/16/powershell-and-64-bit-windows-helper-functions.aspx)
  2. Вызов PowerShell для x86 / x64 в зависимости от потребностей конкретного сценария

К сожалению, многое из этого сделано методом грубой силы. Каждая конкретная запись конфигурации, которая зависит от x86 / x64, по существу имеет 2 пути кода (по одному для каждой архитектуры).

Единственное реальное исключение, которое я смог сделать, это проверить наличие определенных программ на диске. У меня есть удобная функция (Get-ProgramFiles32), которая позволяет легко тестировать программы.

if ( test-path (join-path Get-ProgramFiles32 "subversion") ) { ...

Вот все вспомогательные функции, которые у меня есть в моей общей библиотеке, которые имеют дело с 32/64-битными различиями.

# Get the path where powershell resides.  If the caller passes -use32 then 
# make sure we are returning back a 32 bit version of powershell regardless
# of the current machine architecture
function Get-PowerShellPath() {
    param ( [switch]$use32=$false,
            [string]$version="1.0" )

    if ( $use32 -and (test-win64machine) ) {
        return (join-path $env:windir "syswow64\WindowsPowerShell\v$version\powershell.exe")
    }

    return (join-path $env:windir "System32\WindowsPowerShell\v$version\powershell.exe")
}


# Is this a Win64 machine regardless of whether or not we are currently 
# running in a 64 bit mode 
function Test-Win64Machine() {
    return test-path (join-path $env:WinDir "SysWow64") 
}

# Is this a Wow64 powershell host
function Test-Wow64() {
    return (Test-Win32) -and (test-path env:\PROCESSOR_ARCHITEW6432)
}

# Is this a 64 bit process
function Test-Win64() {
    return [IntPtr]::size -eq 8
}

# Is this a 32 bit process
function Test-Win32() {
    return [IntPtr]::size -eq 4
}

function Get-ProgramFiles32() {
    if (Test-Win64 ) {
        return ${env:ProgramFiles(x86)}
    }

    return $env:ProgramFiles
}

function Invoke-Admin() {
    param ( [string]$program = $(throw "Please specify a program" ),
            [string]$argumentString = "",
            [switch]$waitForExit )

    $psi = new-object "Diagnostics.ProcessStartInfo"
    $psi.FileName = $program 
    $psi.Arguments = $argumentString
    $psi.Verb = "runas"
    $proc = [Diagnostics.Process]::Start($psi)
    if ( $waitForExit ) {
        $proc.WaitForExit();
    }
}

# Run the specified script as an administrator
function Invoke-ScriptAdmin() {
    param ( [string]$scriptPath = $(throw "Please specify a script"),
            [switch]$waitForExit,
            [switch]$use32=$false )

    $argString = ""
    for ( $i = 0; $i -lt $args.Length; $i++ ) {
        $argString += $args[$i]
        if ( ($i + 1) -lt $args.Length ) {
            $argString += " "
        }
    }

    $p = "-Command & "
    $p += resolve-path($scriptPath)
    $p += " $argString" 

    $psPath = Get-PowershellPath -use32:$use32
    write-debug ("Running: $psPath $p")
    Invoke-Admin $psPath $p -waitForExit:$waitForExit
}
2 голосов
/ 02 марта 2009

В блоге msgoodies есть это предложение для определения архитектуры . Этот подход можно использовать для определения архитектуры и вызова PowerShell x86 при известной несовместимости.

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