пятница, 24 июля 2026 г.

Powershell, Where

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)

  1. Папка WindowsApps — системная и защищена ACL. Обычные пользователи (и многие службы) не имеют туда доступа на чтение/выполнение по умолчанию. Это может стать проблемой, если ты, например, запускаешь скрипт из BackgroundService или CI/CD под ограниченной учёткой.
  2. Путь не статичен. В имени папки зашита версия (7.6.4.0) и хэш (8wekyb3d8bbwe). При обновлении PowerShell путь изменится — скрипты, которые жёстко прописывают путь, сломаются.
  3. Переменная PATH может быть настроена так, что pwsh находится, но прямого доступа к папке нет. Команда Get-Command pwsh работает, потому что ищет по PATH, а не по фиксированному пути.

Как надёжно находить pwsh в скриптах и сервисах

Учитывая твой контекст (автоматизация, BackgroundService, обработка ошибок и т. д.), лучше не хардкодить путь, а использовать один из этих подходов:

Вариант 1 (самый простой и надёжный)

powershell
$pwshPath = (Get-Command pwsh).Source

Это сработает, если pwsh добавлен в PATH (в Store‑версии обычно так и есть).

Вариант 2 (если нужно убедиться, что это именно pwsh.exe, а не алиас)

powershell

$pwshPath = (Get-Command pwsh -CommandType Application).Source

Вариант 3 (для сценариев, где PATH может быть ограничен)

Можно искать pwsh.exe в типичных местах и брать первый найденный:

powershell


$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), подскажу готовый фрагмент кода под эту задачу. 😊

Комментариев нет:

Отправить комментарий