To powinno być proste zadanie, ale widziałem kilka prób uzyskania ścieżki do katalogu, w którym znajduje się wykonane polecenie cmdlet, z różnym powodzeniem. Na przykład, kiedy wykonuję C:\temp\myscripts\mycmdlet.ps1
plik z ustawieniami C:\temp\myscripts\settings.xml
, chciałbym móc przechowywać C:\temp\myscripts
w nim zmienną mycmdlet.ps1
.
Jest to jedno rozwiązanie, które działa (choć nieco uciążliwe):
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$settingspath = $directorypath + '\settings.xml'
Kolejne sugerowało to rozwiązanie, które działa tylko w naszym środowisku testowym:
$settingspath = '.\settings.xml'
Bardzo podoba mi się to drugie podejście i wolę, aby za każdym razem analizować ścieżkę do pliku jako parametr, ale nie mogę zmusić go do działania w moim środowisku programistycznym. Co mam zrobić? Czy ma to coś wspólnego z konfiguracją programu PowerShell?
powershell
cmdlet
Stig Perez
źródło
źródło
Odpowiedzi:
Niezawodny sposób na zrobienie tego jest dokładnie taki, jak pokazałeś
$MyInvocation.MyCommand.Path
.Korzystanie ze ścieżek względnych będzie oparte na $ pwd w programie PowerShell, bieżącym katalogu aplikacji lub bieżącym katalogu roboczym interfejsu API .NET.
PowerShell v3 + :
Użyj zmiennej automatycznej
$PSScriptRoot
.źródło
$PSScriptRoot
i$MyInvocation.MyCommand.Path
?Tak, to powinno działać. Ale jeśli potrzebujesz zobaczyć ścieżkę bezwzględną, to wszystko, czego potrzebujesz:
źródło
C:\mydir
i wywołam polecenieC:\dir1\dir2\dir3\mycmdlet.ps1
, rozwiąże toC:\mydir
, a nieC:\dir1\dir2\dir3
. Wywołanie nowego pliku wykonywalnego ma ten sam problem, ponieważ bieżący katalog jest dziedziczony z procesu nadrzędnego.Najłatwiejszą metodą wydaje się być użycie następującej predefiniowanej zmiennej:
about_Automatic_Variables
iabout_Scripts
oba stwierdzają:Używam tego w ten sposób:
źródło
Możesz także użyć:
Część w nawiasach zwraca
PathInfo
obiekt.(Dostępne od wersji PowerShell 2.0.)
źródło
C:\mydir
i wywołam polecenieC:\dir1\dir2\dir3\mycmdlet.ps1
, rozwiąże toC:\mydir
, a nieC:\dir1\dir2\dir3
. Wywołanie nowego pliku wykonywalnego ma ten sam problem, ponieważ bieżący katalog jest dziedziczony z procesu nadrzędnego.Ścieżka jest często zerowa. Ta funkcja jest bezpieczniejsza.
źródło
Próbować :
lub:
źródło
$pwd
/$PWD
za każdym razem, gdy robię sobie długą przerwę od PowerShell! O wiele bardziej przydatne IMO ...Get-Location
zwróci bieżącą lokalizację:źródło
Podoba mi się rozwiązanie jednowierszowe :)
źródło
Spróbuj tego:
źródło
W Powershell 3 i nowszych możesz po prostu użyć
$PSScriptRoot
źródło
Można by pomyśleć, że użycie „. \” Jako ścieżki oznacza, że jest to ścieżka wywołania. Ale nie przez cały czas. Przykład, jeśli używasz go w zadaniu ScriptBlock. W takim przypadku może to wskazywać na% profil% \ Documents.
źródło
ta funkcja ustawi lokalizację zachęty do ścieżki skryptu, zajmując się różnymi sposobami uzyskania ścieżki skryptu między vscode, psise i pwd:
źródło
Dla tego, co warto być rozwiązaniem jednoliniowym, poniżej jest dla mnie działające rozwiązanie.
1 na końcu ma zignorować
/
.Dzięki powyższym postom za pomocą polecenia cmdlet Get-Location .
źródło
Większość odpowiedzi nie działa podczas debugowania następujących IDE:
Ponieważ w tych
$PSScriptRoot
jest pusty iResolve-Path .\
(i podobne) spowoduje nieprawidłowe ścieżki.Odpowiedź Freakydinde'a jest jedyną, która rozwiązuje te sytuacje, więc głosowałem za nią, ale nie sądzę,
Set-Location
aby odpowiedź była naprawdę pożądana. Naprawiłem to i uczyniłem kod nieco jaśniejszym:źródło
Aby rozwinąć odpowiedź @Cradle: możesz również napisać funkcję wielofunkcyjną, która da ci ten sam wynik na pytanie PO:
źródło
Jeśli potrzebujesz tylko nazwy bieżącego katalogu, możesz zrobić coś takiego:
Zakładając, że pracujesz z C: \ Temp \ Location \ MyWorkingDirectory>
Wynik
MyWorkingDirectory
źródło
Miałem podobne problemy i sprawiało mi to dużo problemów, ponieważ tworzę programy napisane w PowerShell (aplikacje GUI dla użytkowników końcowych) i mam dużo plików i zasobów, które muszę załadować z dysku. Z mojego doświadczenia
.
wynika , że używanie do reprezentowania bieżącego katalogu jest zawodne. Powinien reprezentować bieżący katalog roboczy, ale często nie. Wygląda na to, że PowerShell zapisuje lokalizację, z której wywołano PowerShell.
. Mówiąc ściślej, przy pierwszym uruchomieniu PowerShell, domyślnie uruchamia się w katalogu użytkownika domowego. Zazwyczaj jest to katalog twojego konta użytkownika, coś w rodzajuC:\USERS\YOUR USER NAME
. Następnie PowerShell zmienia katalog na katalog, z którego został wywołany, lub na katalog, w którym znajduje się wykonywany skrypt, przed wyświetleniem monitu programu PowerShell lub uruchomieniem skryptu. Ale dzieje się tak, gdy sama aplikacja PowerShell uruchamia się pierwotnie w katalogu użytkownika domowego.I
.
reprezentuje ten początkowy katalog, w którym uruchomiono PowerShell..
Reprezentuje więc tylko bieżący katalog na wypadek, gdyby PowerShell został wywołany z poszukiwanego katalogu. Jeśli później zmienisz katalog w kodzie programu PowerShell, zmiana nie pojawi się.
w każdym przypadku. W niektórych przypadkach.
reprezentuje bieżący katalog roboczy, aw innych katalog, z którego wywołano PowerShell (sam, a nie skrypt), co może prowadzić do niespójnych wyników. Z tego powodu używam skryptu wywołującego. Skryptu PowerShell z pojedynczym wewnątrz polecenia:POWERSHELL
. To zapewni, że PowerShell zostanie wywołany z poszukiwanego katalogu, a tym samym.
reprezentują bieżący katalog. Działa to tylko wtedy, gdy później nie zmienisz katalogu w kodzie programu PowerShell. W przypadku scenariusza, używam skryptu wywołującego, który jest podobny do ostatniego już wspomniałem, oprócz tego, że zawiera opcję pliku:POWERSHELL -FILE DRIVE:\PATH\SCRIPT NAME.PS1
. Zapewnia to uruchomienie programu PowerShell w bieżącym katalogu roboczym.Po prostu kliknięcie skryptu wywołuje program PowerShell z katalogu domowego użytkownika bez względu na to, gdzie znajduje się skrypt. Wynika to z tego, że bieżącym katalogiem roboczym jest katalog, w którym znajduje się skrypt, ale katalogiem wywołania programu PowerShell jest
C:\USERS\YOUR USER NAME
, a.
zwracanie jednego z tych dwóch katalogów w zależności od sytuacji jest śmieszne.Jednak aby uniknąć zamieszania i to wszystko za pomocą skryptu wywołującego, można po prostu użyć jednej
$PWD
lub$PSSCRIPTROOT
zamiast.
reprezentować bieżącego katalogu w zależności od pogody chcesz reprezentować bieżący katalog lub katalog, z którego scenariusz został wywołany. A jeśli z jakiegoś powodu chcesz odzyskać inny z dwóch.
zwracanych katalogów , możesz użyć$HOME
.Osobiście mam po prostu skrypt wywołujący w katalogu głównym moich aplikacji, które rozwijam za pomocą programu PowerShell, który wywołuje mój główny skrypt aplikacji i po prostu pamiętam, aby nigdy nie zmieniać bieżącego katalogu roboczego w kodzie źródłowym mojej aplikacji, więc nigdy nie muszę się o to martwić, i mogę używać
.
do reprezentowania bieżącego katalogu i do obsługi względnego adresowania plików w moich aplikacjach bez żadnych problemów. Powinno to działać w nowszych wersjach programu PowerShell (nowszych niż wersja 2).źródło