¿Cuál es la mejor manera de programar contra la variabilidad x64 vs. x86 de powershell?

StackOverflow https://stackoverflow.com/questions/602060

  •  03-07-2019
  •  | 
  •  

Pregunta

Tenemos varios scripts que utilizamos para instalar y configurar las dependencias que respaldan los sistemas que mantenemos. Los ejecutamos en cualquier momento que establezcamos un entorno de desarrollo, prueba, demostración, tren, producción, etc. A menudo nos encontramos con que tenemos que lidiar con la arquitectura x64 vs. x86, especialmente en lo que respecta a los scripts de powershell.

Por ejemplo, tengo una secuencia de comandos que utiliza Extensiones de PowerShell de Windows Installer para determinar si un programa / Se ha instalado el parche. La secuencia de comandos no funciona en un entorno x64 sin invocar explícitamente PowerShell (x86), que no está en la ruta de forma predeterminada. Como portamos estos scripts a la plataforma x64, sería fantástico mantener un solo conjunto de scripts que funcionen en powershell en ambas arquitecturas y solo invocar el código x86 cuando sea necesario.

¿Alguien sabe de una estrategia para hacer esto?

¿Fue útil?

Solución 2

El blog de msgoodies tiene esta sugerencia para determinar la arquitectura . Uno podría usar este enfoque para determinar la arquitectura e invocar el powershell x86 cuando se sepa que hay incompatibilidad.

Otros consejos

Me encuentro mucho con este problema con mis scripts de configuración. El enfoque básico que tomo es

  1. Use varias funciones para comprobar si estoy en un entorno de 64 bits ( http://blogs.msdn.com/jaredpar/archive/2008/10/16/powershell-and-64-bit-windows-helper-functions.aspx )
  2. Invoque PowerShell x86 / x64 según las necesidades de un script en particular

Desafortunadamente, mucho de esto se hace de manera bruta. Cada entrada de configuración particular que depende de x86 / x64 esencialmente tiene 2 rutas de código (una para cada arquitectura).

La única excepción real que he podido hacer es probar la existencia de ciertos programas en el disco. Tengo una función práctica (Get-ProgramFiles32) que facilita la prueba de los programas.

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

Aquí están todas las funciones de ayuda que tengo en mi biblioteca común que se ocupan de las diferencias de 32/64 bits.

# 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
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top