2009-03-02 2 views
7

Wir haben mehrere Skripte, die wir verwenden, um die Abhängigkeiten zu installieren und zu konfigurieren, die die von uns betreuten Systeme unterstützen. Wir führen diese zu jeder Zeit aus, wenn wir eine Entwicklungsumgebung, eine Testumgebung, eine Demoumgebung, einen Zug, eine Produktionsstätte usw. einrichten. Wir finden oft, dass wir uns mit der x64 vs. x86-Architektur befassen müssen, besonders in Bezug auf die Powershell-Skripte.Was ist der beste Weg, gegen powershell x64 vs. x86 Variabilität zu programmieren

Zum Beispiel habe ich ein Skript, das die Windows Installer PowerShell Extensions verwendet, um festzustellen, ob ein Programm/Patch installiert wurde. Das Skript funktioniert nicht in einer x64-Umgebung, ohne explizit PowerShell (x86) aufzurufen, das standardmäßig nicht im Pfad enthalten ist. Wenn wir diese Skripte auf die x64-Plattform portieren, wäre es großartig, einen einzigen Satz von Skripten zu unterhalten, die in Powershell auf beiden Architekturen arbeiten und bei Bedarf nur x86-Code aufrufen.

Kennt jemand eine Strategie dafür?

Antwort

15

Ich habe dieses Problem mit meinen Konfigurationsskripts sehr oft. Der grundlegende Ansatz, den ich nehmen soll

  1. Verwenden mehrere Funktionen testen, ob ich in einer 64-Bit-Umgebung bin (http://blogs.msdn.com/jaredpar/archive/2008/10/16/powershell-and-64-bit-windows-helper-functions.aspx)
  2. Invoke x86/x64 Powershell basiert auf den Anforderungen eines bestimmten Skript

Leider wird viel davon in einer brutalen Art und Weise getan. Jeder bestimmte Konfigurationseintrag, der x86/x64-abhängig ist, hat im Wesentlichen zwei Codepfade (einen für jede Architektur).

Die einzige wirkliche Ausnahme, die ich machen konnte, ist für die Existenz bestimmter Programme auf der Festplatte zu testen. Ich habe eine praktische Funktion (Get-ProgramFiles32), die es einfach macht, nach Programmen zu suchen.

Hier sind alle Hilfsfunktionen, die ich in meiner allgemeinen Bibliothek habe, die 32/64 Bit-Unterschiede behandeln.

# 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 
} 
+0

Möchten Sie 'Get-ProgramFiles32' nicht' Test-Win64Machine' anstelle von 'Test-Win64' aktivieren? Sie benötigen den richtigen Pfad basierend auf dem Computer, nicht basierend auf dem aktuellen Prozess. Oder fehlt mir etwas? – CoderDennis

Verwandte Themen