Powershell, Where
Ага, теперь всё сходится: у тебя PowerShell установлен через Microsoft Store (на это указывает путь в C:\Program Files\WindowsApps\...). Поэтому стандартный путь C:\Program Files\PowerShell\7\ не срабатывает — отсюда и False от Test-Path.
Что это значит для практики
- Путь к исполняемому файлу:
C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.4.0_x64__8wekyb3d8bbwe\pwsh.exe - Корень установки (
$PSHOME):
тот же каталог —C:\Program Files\WindowsApps\Microsoft.PowerShell_7.6.4.0_x64__8wekyb3d8bbwe
Нюансы, которые важно учитывать (особенно для серверной автоматизации и BackgroundService)
- Папка
WindowsApps— системная и защищена ACL. Обычные пользователи (и многие службы) не имеют туда доступа на чтение/выполнение по умолчанию. Это может стать проблемой, если ты, например, запускаешь скрипт из BackgroundService или CI/CD под ограниченной учёткой. - Путь не статичен. В имени папки зашита версия (
7.6.4.0) и хэш (8wekyb3d8bbwe). При обновлении PowerShell путь изменится — скрипты, которые жёстко прописывают путь, сломаются. - Переменная
PATHможет быть настроена так, чтоpwshнаходится, но прямого доступа к папке нет. КомандаGet-Command pwshработает, потому что ищет поPATH, а не по фиксированному пути.
Как надёжно находить pwsh в скриптах и сервисах
Учитывая твой контекст (автоматизация, BackgroundService, обработка ошибок и т. д.), лучше не хардкодить путь, а использовать один из этих подходов:
Вариант 1 (самый простой и надёжный)
$pwshPath = (Get-Command pwsh).Source
Это сработает, если pwsh добавлен в PATH (в Store‑версии обычно так и есть).
Вариант 2 (если нужно убедиться, что это именно pwsh.exe, а не алиас)
$pwshPath = (Get-Command pwsh -CommandType Application).Source
Вариант 3 (для сценариев, где PATH может быть ограничен)
Можно искать pwsh.exe в типичных местах и брать первый найденный:
$paths = @(
"C:\Program Files\PowerShell\7\pwsh.exe",
"C:\Program Files (x86)\PowerShell\7\pwsh.exe"
)
$pwshPath = $paths | Where-Object { Test-Path $_ } | Select-Object -First 1
if (-not $pwshPath) {
# fallback: ищем через Get-Command
$pwshPath = (Get-Command pwsh).Source
}
Если ты, например, хочешь вызывать pwsh из C#‑кода (в том числе в рамках твоего Publisher‑Subscriber сервиса или BackgroundService), лучше всего использовать Вариант 1 и передавать путь в ProcessStartInfo.FileName. Так ты не будешь зависеть от конкретной структуры папок и версии.
Если скажешь, в каком именно сценарии тебе нужен путь (например, запуск из C#, скрипт деплоя, проверка версии в CI/CD), подскажу готовый фрагмент кода под эту задачу. 😊
Комментариев нет:
Отправить комментарий