Qual è il modo migliore per programmare contro la variabilità x64 vs x86 di powershell

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

  •  03-07-2019
  •  | 
  •  

Domanda

Abbiamo diversi script che usiamo per installare e configurare le dipendenze a supporto dei sistemi che manteniamo. Li eseguiamo ogni volta che stabiliamo un ambiente di sviluppo, test, demo, formazione, produzione, ecc. Troviamo spesso che abbiamo a che fare con l'architettura x64 vs x86, specialmente per quanto riguarda gli script PowerShell.

Ad esempio, ho uno script che utilizza le Estensioni di PowerShell di Windows Installer per determinare se un programma / la patch è stata installata. Lo script non funziona in un ambiente x64 senza invocare esplicitamente PowerShell (x86), che per impostazione predefinita non si trova sul percorso. Dato che portiamo questi script sulla piattaforma x64, sarebbe bello mantenere un unico set di script che funzionano in PowerShell su entrambe le architetture e invocano il codice x86 solo quando necessario.

Qualcuno conosce una strategia per farlo?

È stato utile?

Soluzione 2

Il blog msgoodies ha questo suggerimento per determinare l'architettura . Si potrebbe usare questo approccio per determinare l'architettura e invocare il PowerShell x86 in caso di incompatibilità nota.

Altri suggerimenti

Ho riscontrato questo problema molto con i miei script di configurazione. L'approccio di base che seguo è

  1. Utilizza diverse funzioni per verificare se mi trovo in un ambiente a 64 bit ( http://blogs.msdn.com/jaredpar/archive/2008/10/16/powershell-and-64-bit-windows-helper-functions.aspx )
  2. Richiama PowerShell x86 / x64 in base alle esigenze di un determinato script

Sfortunatamente molto di questo viene fatto in modo bruto. Ogni particolare voce di configurazione dipendente da x86 / x64 ha essenzialmente 2 percorsi di codice (uno per ogni architettura).

L'unica vera eccezione che sono stato in grado di fare è testare l'esistenza di alcuni programmi su disco. Ho una comoda funzione (Get-ProgramFiles32) che semplifica il test dei programmi.

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

Ecco tutte le funzioni di supporto che ho nella mia libreria comune che si occupano delle differenze a 32/64 bit.

# 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
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top