2016-06-12 14 views
7

Dlaczego funkcja [System.IO.Path]::Combine nie przyjmuje mojego pierwszego parametru?[System.IO.Path] :: Combine nie bierze mojej zmiennej powershell jako parametru?

PS C:\WINDOWS\system32> $g_basePath 
F:\Dev\OneClickTools 



PS C:\WINDOWS\system32> [Tests.Utils]::CUSTOMASSEMBLY_TEST 
CustomLogic.dll 



PS C:\WINDOWS\system32> [System.IO.Path]::Combine($g_basePath, "\bin\debug", [Tests.Utils]::CUSTOMASSEMBLY_TEST) 
\bin\debug\CustomLogic.dll 

Trzecie polecenie pokazuje, że tylko drugie i trzecie parametry łączone lub używającą pusty ciąg $g_basePath ..?

Odpowiedz

7

Wystarczy pominąć wiodącą backslash na drugiej ścieżce:

[System.IO.Path]::Combine($g_basePath, "bin\debug", [Tests.Utils]::CUSTOMASSEMBLY_TEST) 

Czysty PowerShell próba byłoby użyć Join-path komandletu dwukrotnie:

Join-Path $g_basePath 'bin\debug' | Join-path -ChildPath [Tests.Utils]::CUSTOMASSEMBLY_TEST 
+1

ah dzięki ... Myślałem, że ten rodzaj inteligencji został zbudowany w funkcji "[System.IO.Path] :: Combine" – ibiza

+0

Tak, też tak sądziłem, po prostu wypróbowałem to ;-). –

+2

dziękuję, pomyślałem o użyciu Join-Path ... ale korzystanie z Join-Path dwa razy jest smutne: p – ibiza

8

celu uzupełnienia Martin Brandl's helpful answer:

Spe w skrócie, - przeciw-intuicyjny - logic applied by [System.IO.Path]::Combine jest: "Jeśli ścieżka jest bezwzględną ścieżką, operacja łączenia odrzuca wszystkie uprzednio połączone ścieżki i resetuje do tej bezwzględnej ścieżki." (odnosi się to analogicznie do innych przeciążeniowych metod).

Innymi słowy: ostatni ścieżka argumentem określono, że zaczyna się \ (w tym \\) lub <letter>: powoduje, że wszystkie dotychczasowe ścieżki być ignorowane (spec napęd.).

> [IO.Path]::Combine('\foo', '\bar', '\baz') 
\baz # !! '\foo' and '\bar' were ignored 

Dla oczekiwanego zachowania - gdzie początkowy \ powinny być traktowane jako opcjonalne części każdego składnika ścieżki innej niż pierwsza - upewnić się, że każdy komponent ale pierwszy nie początek z \ - Join-Path obsługuje, jak można się spodziewać.

prosta funkcja może to zrobić:

# Combines array of path components $a to a single path. 
function combine([string[]] $a) { 
    [IO.Path]::Combine([string[]] (@($a[0]) + $a[1..$($a.count-1)] -replace '^\\', '')) 
} 

Zauważ, że odlewy do [string[]] jest niezbędna do tego, aby pracować.

połączenia próbki:

> combine '\foo', '\bar', '\baz' 
\foo\bar\baz # as expected 

Stosując Join-Path, który obsługuje tylko pary elementów od PowerShell v5.1 [1] , jako alternatywa do stosowania Rurociąg do łączenia wielu wywołań to zagnieżdżanie wielu połączeń za pomocą (...) :

> Join-Path \foo (Join-Path \bar \baz) 
\foo\bar\baz 

Należy zauważyć, że chociaż jest nieco niezręczne gniazdowania, nie trzeba się martwić o podległych elementów, które zaczynają się \.


chodzi o logikę PowerShell własnej Join-Path cmdletu:

Mimo to zrozumiałe oczekiwać parametr -ChildPath poprzeć tablicę ścieżek (które nie), ważne jest, aby Rozumiem, że konstrukcja Join-Path różni się zasadniczo od tej z [System.IO.Path]::Combine(), od wersji Windows PowerShell v5.1 [1] :

  • Join-Path wykorzystuje wiele ścieżek wejściowych w celu wygenerowania wiele ścieżek wyjściowych niż interpretowanie ścieżek wejściowych jako części ścieżki wyjściowej pojedynczy.

  • ścieżki wejściowe są para (y) z nadrzędnych i podrzędnych drogach, z każdej pary coraz połączone i powodując jego własnej drogi wyjścia:

    • > Join-Path \foo \bar \foo\bar
      • Skrót: Join-Path -Path \foo -ChildPath \bar
      • Zobacz, jak PS, w przeciwieństwie do [System.IO.Path]::Combine(), obsługuje opcjonalny prowadzący \ w dziecku ścieżkę, jak można się spodziewać.
  • Chociaż parametr nadrzędny ścieżki (-Path) nie wspierać Tablica ścieżek macierzystych parametr dzieci ścieżki (-ChildPath) ma nie, ale w połączeniu z -Resolve Parametr i symbole wieloznaczne mogą skutecznie prowadzić do wielu ścieżek potomnych.

    • > Join-Path -Path \foo, \baz -ChildPath \bar \foo\bar \baz\bar
    • Uwaga jak ścieżki wyjściowe zostały wygenerowane, łącząc każdą ścieżkę nadrzędną ze ścieżką jedno dziecko.
  • przeciwieństwie [System.IO.Path]::Combine(), Join-Path opcjonalnie obsługuje rozwiązywanie wieloznaczne ścieżek z -Resolve:

    • > Join-Path -Resolve C:\Win* Sys* C:\Windows\System C:\Windows\System32 C:\Windows\SystemApps C:\Windows\SystemResources C:\Windows\SysWOW64 C:\Windows\system.ini
  • koniec warto zauważyć, że Join-Path działa nie tylko ze ścieżek systemu plików, ale z ścieżki dowolnego dostawcy [hierarchicznego składnicy danych] PowerShell, z zastosowaniem dostarczania Odpowiednie separatory ścieżek.


[1] i platform wydanie PowerShell PowerShell Rdzeń, od V6.0.0, już nie wsparcie dowolna liczba elementów podrzędnych, enabling calls such as Join-Path a b c to yield a\b\c (Windows) or a/b/c (Unix), natomiast wydanie Windows Powerware dla Windows PowerShell w wersji od wersji 5.1 nadal nie ma znaczenia rt it.
To nowe zachowanie nie jest jeszcze udokumentowane (i nawet nie jest odzwierciedlone składniowo w Join-Path -?), ale może ostatecznie przejść do środowiska Windows PowerShell (i tym samym wszystkie wersje).

+1

To powinna być zaakceptowana odpowiedź. –

Powiązane problemy