gpt4 book ai didi

c# - 如何在二进制 PowerShell 模块中扩展路径?

转载 作者:行者123 更新时间:2023-12-03 00:57:57 25 4
gpt4 key购买 nike

我正在编写一个简单的示例二进制 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 提供程序位置的信息,包括通配符解析,请参阅 this answer .

    [1] 这种差异是 PowerShell 支持单个进程内的多个运行空间(线程)的一个不幸的副作用,所有这些都需要有自己的当前位置 - 请参阅 this GitHub issue背景信息。

    [2] 例如,运行空间的当前位置可能是注册表位置,例如 HKCU:\Console .

    关于c# - 如何在二进制 PowerShell 模块中扩展路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60288939/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com