2013-04-10 14 views
6

Coś jest naprawdę dziwnego w tym języku. Próbuję wykonać funkcję i użyć jej wartości wyniku jako warunku. To jest mój kod:Stan z wywołaniem funkcji w PowerShell

function Get-Platform() 
{ 
    # Determine current Windows architecture (32/64 bit) 
    if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null) 
    { 
     echo "x64" 
     return "x64" 
    } 
    else 
    { 
     echo "x86" 
     return "x86" 
    } 
} 

if (Get-Platform -eq "x64") 
{ 
    echo "64 bit platform" 
} 
if (Get-Platform -eq "x86") 
{ 
    echo "32 bit platform" 
} 

oczekiwany wynik to:

x64 
64 bit platform 

Ale rzeczywista moc jest taka:

64 bit platform 
32 bit platform 

Co tu się dzieje? Jak to może zostać naprawione? Nie mogłem znaleźć żadnych przykładów w Internecie, które używają funkcji w stanie if. Czy to w ogóle możliwe w Powershell? Pracuję w systemie Windows 7 bez specjalnej konfiguracji, więc mam z nim dowolną wersję PS.

Odpowiedz

16

Jeśli chcesz porównać wartości zwracanej przez funkcję w sposób warunkowy, należy grupa wywołanie funkcji (czyli umieścić go w nawiasach) lub (jak @FlorianGerhardt zasugerowano) przypisać zwracaną wartość funkcji do zmiennej i użyć tej zmiennej w warunku. W przeciwnym razie operator porównania i drugi operand zostaną przekazane jako argumenty funkcji (w twoim przypadku zostaną po cichu odrzucone). Twoja funkcja zwraca wynik, który nie jest ani "" ani 0 ani $null, więc ocenia się na $true, powodując wyświetlanie obu komunikatów.

ten powinien robić to, co chcesz:

... 
if ((Get-Platform) -eq 'x64') { 
    echo "64 bit platform" 
} 
... 

BTW, należy unikać stosowania oddzielnych if oświadczenia o warunkach, które wykluczają się wzajemnie. Na platformie sprawdzić się if..then..elseif

$platform = Get-Platform 
if ($platform -eq "x64") { 
    ... 
} elseif ($platform -eq "x86") { 
    ... 
} 

lub switch oświadczenie

Switch (Get-Platform) { 
    "x86" { ... } 
    "x64" { ... } 
} 

byłoby bardziej odpowiednie.

Chciałbym również uniknąć echo wewnątrz funkcji. Po prostu zwróć wartość i wykonaj dowolne echo, które może być wymagane przy zwracanej wartości. Wszystko, co pojawiło się wewnątrz funkcji, zostanie również zwrócone rozmówcy.

Ostatnia uwaga: osobiście wolałbym nie polegać na istnieniu konkretnego folderu lub zmiennej środowiskowej do określania architektury systemu operacyjnego. Korzystanie z WMI do tego zadania uzna mnie dużo bardziej wiarygodne:

function Get-Platform { 
    return (gwmi Win32_OperatingSystem).OSArchitecture 
} 

funkcja ta zwróci ciąg "32-Bit" lub "64-Bit", w zależności od architektury systemu operacyjnego.

+0

Dziękuję za pełne wyjaśnienie. Używanie nawiasów wokół nazwy funkcji wydaje się naprawdę wywoływać funkcję, więc wydaje się, że jest to uniwersalne rozwiązanie takich problemów. Znacznie prostsze niż użycie innej nazwy zmiennej. Echo w funkcji (zastąpione przez Write-Host, aby było funkcjonalne) służy wyłącznie do śledzenia. To jest skrypt testowy. Chociaż teraz widzę następujący wynik: "x64", "platforma 64-bitowa", "x64". Wydaje się, że wywołanie WMI zwraca zwarty łańcuch, dla mnie jest to "64-bitowy". Inne sprawdzanie jest szeroko stosowane w innych miejscach, jak się wydaje. – ygoe

+0

'OSArchitecture' zwraca ciąg' '32-bitowy' 'lub' "64-Bit" ', w zależności od architektury systemu operacyjnego, więc musisz dostosować warunki do tego. –

3

Myślę, że porównujesz funkcję, a nie wynik funkcji. Również jakoś echo nie działa zgodnie z oczekiwaniami w funkcji. Zwykle używam Write-Hosta.

Oto moje rozwiązanie problemu:

function Get-Platform() 
{ 
    # Determine current Windows architecture (32/64 bit) 
    if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null) 
    { 
     Write-Host("x64") 
     return "x64" 
    } 
    else 
    { 
     Write-Host("x86") 
     return "x86" 
    } 
} 

$platform = Get-Platform 

if ($platform -eq 'x64') 
{ 
    echo "64 bit platform" 
} 

if ($platform -eq 'x86') 
{ 
    echo "32 bit platform" 
} 
Powiązane problemy