[英]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.