Как расширить путь в двоичном модуле PowerShell? - PullRequest
1 голос
/ 18 февраля 2020

Я пишу простой пример двоичного модуля PowerShell:

using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;

namespace MyModule
{
    [Cmdlet(VerbsDiagnostic.Test,"SampleCmdlet")]
    [OutputType(typeof(System.String))]
    public class TestSampleCmdletCommand : PSCmdlet
    {
        [Parameter(
            Mandatory = true,
            Position = 0,
            ValueFromPipeline = true,
            ValueFromPipelineByPropertyName = true)]
        public string Path { get; set; }

        // This method gets called once for each cmdlet in the pipeline when the pipeline starts executing
        protected override void BeginProcessing()
        {
            WriteVerbose("Begin!");
        }

        // This method will be called for each input received from the pipeline to this cmdlet; if no input is received, this method is not called
        protected override void ProcessRecord()
        {
            WriteObject( Path );
            WriteObject( System.IO.Path.GetFullPath(Path) );
        }

        // This method will be called once at the end of pipeline execution; if no input is received, this method is not called
        protected override void EndProcessing()
        {
            WriteVerbose("End!");
        }
    }

}

Когда я импортирую модуль и запускаю код, GetFullPath () всегда возвращает путь относительно профиля пользователя, а не полностью заполненный путь:

PS C:\Users\User\GitHub\MyModule\source\MyModule> Import-Module -Name .\bin\Debug\netstandard2.0\MyModule.dll
PS C:\Users\User\GitHub\MyModule\source\MyModule> cd \
PS C:\> Test-SampleCmdlet -Path .\Temp\
.\Temp\
C:\Users\User\Temp\
PS C:\>                                                                                                                                                                                                                                                                     

Как правильно развернуть параметр пути?

1 Ответ

3 голосов
/ 19 февраля 2020
Методы

. NET используют текущий каталог для всего процесса , как указано в Environment.CurrentDirectory, что , а не , то же самое, что и PowerShell runspace-speci c (спецификация потока c) текущее местоположение. [1]

Вы не можете напрямую полагаться на System.IO.Path.GetFullPath(), по крайней мере, без указания текущего местоположения файловой системы пространства выполнения в качестве необязательного второго аргумента basePath, который доступен только в. NET Core / PowerShell [Core] 6 +.

Кому Обращайтесь к текущей файловой системе местоположения вызывающей области выполнения, даже если местоположение другого провайдера оказывается текущим [2] , вы можете использовать .CurrentProviderLocation("FileSystem").ProviderPath следующим образом в PowerShell [Core] 6+ /. NET Core (Path - это свойство, представляющее параметр -Path командлета, то есть путь ввода):

# Get the runspace's file-system location.
string currentDir = CurrentProviderLocation("FileSystem").ProviderPath;

# .NET Core ONLY: Resolve the given path to a full path as a native path.
#                 relative to the given base path.
string fullPath = System.IO.Path.GetFullPath(Path, currentDir);

В Windows PowerShell требуется дополнительная работа:

# Get the runspace's file-system location as a native path.
string currentDir = CurrentProviderLocation("FileSystem").ProviderPath;

# Requires `using System.Text.RegularExpressions;`
# Strips a ".\" or "./" prefix from a relative path.
string relativePathWithoutPrefix = Regex.Replace(Path, @"^.[\\/]", "")

# Caveat: Combine() will not resolve any additional, *interior* . 
#         or .. components, should they be present in relativePathWithoutPrefix.
string fullPath = System.IO.Path.Combine(currentDir, relativePathWithoutPrefix);

Оба метода передадут значение Path, которое больше dy - это полный путь через.

Примечание:

  • Полученный путь является проектной собственной файловой системой путь, даже если текущее местоположение файловой системы пространства выполнения основано на PowerShell-только диске (создан с New-PSDrive).

  • Подход подразумевает, что ваш Командлет поддерживает только файловая система только пути.

Сведения о том, как работать с местоположениями поставщика PS в более общем плане, включая разрешение по шаблону, см. этот ответ .


[1] Это несоответствие является нежелательным побочным эффектом поддержки PowerShell нескольких пространств выполнения (потоков) внутри одного процесса , у каждого из которых должно быть свое собственное текущее местоположение - см. этот выпуск GitHub для справочной информации.

[2] Например, текущее местоположение пространства выполнения может быть реестр расположение, такое как HKCU:\Console.

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