Quelle est la meilleure façon de programmer contre la variabilité x64 vs x86 de powershell

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

  •  03-07-2019
  •  | 
  •  

Question

Nous utilisons plusieurs scripts pour installer et configurer les dépendances sauvegardant les systèmes que nous gérons. Nous les exécutons chaque fois que nous établissons un environnement de développement, de test, de démonstration, de formation, de production, etc. Nous constatons souvent que nous devons faire face à une architecture x64 par rapport à une architecture x86, en particulier en ce qui concerne les scripts PowerShell.

Par exemple, j'ai un script qui utilise les extensions Windows Installer PowerShell pour déterminer si un programme / le correctif a été installé. Le script ne fonctionne pas dans un environnement x64 sans appeler explicitement PowerShell (x86), qui ne figure pas dans le chemin par défaut. Alors que nous portons ces scripts sur la plate-forme x64, il serait bien de ne conserver qu'un seul ensemble de scripts qui fonctionnent avec PowerShell sur les deux architectures et d'appeler uniquement du code x86 en cas de besoin.

Quelqu'un connaît-il une stratégie pour le faire?

Était-ce utile?

La solution 2

Le blog msgoodies comporte cette suggestion pour déterminer l'architecture . On pourrait utiliser cette approche pour déterminer l’architecture et invoquer le shell x86 en cas d’incompatibilité connue.

Autres conseils

Je rencontre souvent ce problème avec mes scripts de configuration. L’approche de base que j’adopte est de

  1. Utilisez plusieurs fonctions pour tester si je suis dans un environnement 64 bits ( http://blogs.msdn.com/jaredpar/archive/2008/10/16/powershell-and-64-bit-windows-helper-functions.aspx )
  2. Appelez PowerShell x86 / x64 en fonction des besoins d'un script particulier

Malheureusement, cela se fait en grande partie par force brute. Chaque entrée de configuration particulière qui dépend de x86 / x64 a essentiellement 2 chemins de code (un pour chaque architecture).

La seule exception réelle que j'ai pu faire est de tester l'existence de certains programmes sur disque. J'ai une fonction pratique (Get-ProgramFiles32) qui facilite le test des programmes.

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

Voici toutes les fonctions d’aide de ma bibliothèque commune qui traitent des différences 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
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top