簡體   English   中英

如何在二進制 PowerShell 模塊中擴展路徑?

[英]How to expand path in binary PowerShell module?

我正在編寫一個簡單的示例二進制 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:\>                                                                                                                                                                                                                                                                     

如何正確擴展路徑參數?

.NET方法使用進程范圍當前目錄中所反映Environment.CurrentDirectory ,這是一樣的Powershell的運行空間特異性(線程特定的)當前位置。 [1]

您不能直接依賴System.IO.Path.GetFullPath() ,至少在沒有將運行空間的當前文件系統位置指定為可選的第二個basePath參數的情況下不能直接依賴- 這僅在 .NET Core / PowerShell [Core] 6+ 中可用.

為了可靠地引用調用運行空間的當前文件系統位置,即使不同提供程序的位置恰好是當前位置[2] ,您也可以使用.CurrentProviderLocation("FileSystem").ProviderPath在 PowerShell [Core] 6+ 中如下所示/ .NET Core( Path是表示 cmdlet 的-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值。

筆記:

  • 生成的路徑設計為本地文件系統路徑,即使運行空間的當前文件系統位置基於僅限 PowerShell 的驅動器(使用New-PSDrive創建)。

  • 該方法意味着您的 cmdlet 僅支持文件系統路徑。

有關如何更一般地使用 PS 提供程序位置的信息,包括通配符解析,請參閱此答案


[1] 這種差異是 PowerShell 在單個進程內支持多個運行空間(線程)的不幸副作用,所有這些都需要有自己的當前位置 - 請參閱此 GitHub 問題以獲取背景信息。

[2] 例如,運行空間的當前位置可能是一個注冊表位置,例如HKCU:\\Console

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM