C# 从cmdlet中的管道中正确获取文件路径
我编写了小测试代码:C# 从cmdlet中的管道中正确获取文件路径,c#,powershell,C#,Powershell,我编写了小测试代码: namespace Test { using System; using System.Management.Automation; using System.Linq; using System.IO; [Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName="Path")] public sealed class GetTestCommand : PSCmdlet { priva
namespace Test {
using System;
using System.Management.Automation;
using System.Linq;
using System.IO;
[Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName="Path")]
public sealed class GetTestCommand : PSCmdlet {
private String[] _paths;
private Boolean _wildcards;
[Parameter(
ParameterSetName="Path",
Mandatory=true,
Position=0,
ValueFromPipeline=true,
ValueFromPipelineByPropertyName=true
)]
public String[] Path {
get { return _paths; }
set {
_wildcards = true;
_paths = value;
}
}
[Parameter(
ParameterSetName="LiteralPath",
Mandatory=true,
Position=0,
ValueFromPipeline=false,
ValueFromPipelineByPropertyName=true
)]
public String[] LiteralPath {
get { return _paths; }
set { _paths = value; }
}
protected override void ProcessRecord() {
ProviderInfo pi;
(from p in _paths
select new {
FilePath = (_wildcards ?
this.SessionState.Path.GetResolvedProviderPathFromPSPath(p, out pi)[0] :
this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(p))
}).ToList()
.ForEach(i => WriteObject(i.FilePath));
}
}
}
这项工作:
Get-Test *.txt
Get-ChildItem -Filter *.txt | Get-Test
这是有效的:
Get-Test *.txt
Get-ChildItem -Filter *.txt | Get-Test
但这不起作用:
Get-ChildItem -Filter *.txt -Recurse | Get-Test
请向我解释出了什么问题,如何修复,以及我应该阅读哪些内容来深入了解PowerShell的机制。问题在于您实际上没有处理从
PowerShell cmdlet
收到的对象。
正确的方法是将收到的参数绑定到适当类型的对象,然后访问其属性,即:
[Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName = "Path")]
public sealed class GetTestCommand : PSCmdlet
{
private FileSystemInfo[] _paths;
[Parameter(
ParameterSetName = "Path",
Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
public FileSystemInfo[] Path
{
get { return _paths; }
set
{
_paths = value;
}
}
protected override void ProcessRecord()
{
ProviderInfo pi;
(from p in _paths
where (p.GetType() != typeof(DirectoryInfo))
select new
{
FilePath = p.FullName}).ToList()
.ForEach(i => WriteObject(i.FilePath));
}
}
为了便于将来参考,您可能需要使用Get ChildItem | foreach object-process{$\uu0.GetType()}
检查从cmdlet
接收到的类型。
更重要的是,使用Powershell
,您实际上可以以相同的方式实现您想要的功能,例如:Get ChildItem | foreach object-process{$\ FullName}
要获得与纯Powershell完全相同的结果,请尝试:
Get-ChildItem -Recurse | ForEach-Object -Process { if ($_ -isnot [System.IO.DirectoryInfo]) { Write-Host $_.FullName } }
将
[Alias(“PSPath”)]
添加到LiteralPath
参数。谢谢,这与此属性一起工作。首先,感谢您的回复,但我不确定这是否是我在测试中寻找的。我只是想了解PowerShell一般是如何工作的。你说的“PowerShell一般是如何工作的”是什么意思?您已经创建了一个函数,该函数接受String
类型的参数,然后处理它们。错误之处在于,您将参数的类型设置为String
,而导入函数的Get ChildItem
的结果返回类型为FileSystemInfo
的对象。由于param的类型是String
,所以您只接收到了所有被强制转换为.ToString()
的对象。实际上,您可以使用getchilditem | ForEach对象-进程{$\u0.ToString()}
检查这一点。