Примите путь как буквальный путь, относительный путь или относительно корня скрипта - PullRequest
0 голосов
/ 31 октября 2019

В настоящее время мы хотим охватить эти 3 случая при получении информации о файле:

  • Литеральный путь
  • Относительный путь относительно корня скрипта
  • Aотносительный путь относительно текущего рабочего каталога

Чтобы охватить эти 3 случая, мы создали следующую функцию:

Function Get-FilePathItemHC {
    Param (
        [Parameter(Mandatory)]
        [String]$Path
    )

    $Params = @(
        @{
            # Path relative to the script root
            LiteralPath = Join-Path -Path $PSScriptRoot -ChildPath $Path
        }
        @{
            # Literal or path relative to the present work directory
            Path = $Path
        }
    )

    $Item = $null

    foreach ($P in $Params) {
        if ($Item = Get-Item @P -ErrorAction Ignore) {
            $Item
            Break
        }
    }

    if (-not $Item) {
        throw "Cannot find path '$Path' because it does not exist."
    }
}

Это правильный способ сделать это? Кажется, что мы изобретаем колесо здесь.

1 Ответ

1 голос
/ 31 октября 2019

Сделайте ваш -Path Параметр объектом System.IO.FileInfo и просто передайте относительный путь в качестве параметра. Файловый объект разрешается с относительным или полным путем, тогда вы можете использовать $path.FullName для ссылки на полный путь к файлу.

Function Get-FilePathItemHC {
    Param (
        [Parameter(Mandatory)]
        [ValidateScript({ $_.Exists })]
        [System.IO.FileInfo]$Path
    )

    # The ValidateScript attribute makes sure the file you passed in exists
    # so your validation code no longer is required
}

Если вы хотите обрабатывать как каталоги, так и файлы, вы быв этом случае нужно иметь две отдельные переменные, поскольку пути к каталогам станут объектом System.IO.DirectoryInfo, но вы можете сделать аргументы взаимоисключающими:

Function Get-FilePathItemHC {
Param (
    [Parameter(Mandatory=$true, ParameterSetName="FilePath")]
    [ValidateScript({ $_.Exists })]
    [System.IO.FileInfo]$FilePath,
    [Parameter(Mandatory=$true, ParameterSetName="DirectoryPath")]
    [ValidateScript({ $_.Exists })]
    [System.IO.DirectoryInfo]$DirectoryPath
)

  $Path = $FilePath
  if( $DirectoryPath ) {
    $Path = $DirectoryPath
  }

  # The ValidateScript attribute makes sure the file you passed in exists
  # so your validation code no longer is required
}

Get-FilePathItemHC -Path .\path\to\file.txt

Получить относительный путь из $PSScriptRoot

Я не уверен, зачем вам нужен путь относительно $PSScriptRoot, если у вас уже есть полный путь к файлу, но после получения объекта System.IO.FileInfo или System.IO.DirectoryInfo вы можете использовать Resolve-Path из $PSScriptRoot чтобы получить относительный путь из этого каталога:

$file = Get-FilePathItemHC -Path .\path\to\file.txt
Push-Location $PSScriptRoot
$relativeFromScriptRootPath = Resolve-Path -Relative $file
Pop-Location

Push-Location и Pop-Location обрабатывают местоположение как стек. Операция push устанавливает новое местоположение и добавляет его в стек, а операция pop удаляет последнее добавленное местоположение из стека и помещает вас в следующее самое последнее местоположение. Работает немного как cd - в Linux, если вы знакомы.

Resolve-Path вернет путь к файлу, а переключатель -Relative вернет путь относительно вашего текущего каталога. Вы не можете передать альтернативный каталог для разрешения, поэтому мы меняем место для его запуска.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...