我实施了一个简单的PowerShell NavigationCmdletProvider
。
对于那些不知道的人,这意味着我可以使用cmdlet创建一个管理单元,该cmdlet实际上是一个虚拟文件系统驱动器;可以像任何普通文件夹一样从PowerShell安装和导航此驱动器。针对驱动器的每个操作(例如,检查路径是否指向有效项,获取文件夹中子项的名称列表等)被映射到从{{1}继承的.NET类的方法。 } class。
我正面临制表完成的问题,并希望找到解决方案。我发现制表符完成在使用相对路径时会产生错误的结果。对于绝对路径,它工作正常。
对于那些不知道的人,NavigationCmdletProvider
的标签完成通过PowerShell调用NavigationCmdletProvider
方法,该方法从GetChildNames
类重写。
- 证明问题 -
假设我有一个提供者,'TEST',具有以下文件夹层次结构:
NavigationCmdletProvider
绝对路径:
如果我输入“TEST::child1
TEST::child1\child1a
TEST::child1\child1b
TEST::child2
TEST::child2\child2a
TEST::child2\child2b
TEST::child3
TEST::child3\child3a
TEST::child3\child3b
”并按几次标签,它会给我预期的结果:
dir TEST::child1\
相对路径:
首先,我导航到“TEST :: child1”:
> dir TEST::child1\child1a
> dir TEST::child1\child1b
然后,如果我输入“> cd TEST::child1
space ”并按几次 tab ,它会给我不正确的结果:
dir
我希望看到这些:
> dir .\child1\child1a
> dir .\child1\child1b
这是PowerShell中的错误,还是我做错了什么?
以下是提供商的完整自包含代码:
> dir .\child1a
> dir .\child1b
答案 0 :(得分:1)
不确定这是一个错误,I found this workaround似乎“做了工作”。 (小的更新,结果我的原始代码会在你的方式下降到多个级别时“错误”。
''' <summary>
''' Joins two strings with a provider specific path separator.
''' </summary>
''' <param name="parent">The parent segment of a path to be joined with the child.</param>
''' <param name="child">The child segment of a path to be joined with the parent.</param>
''' <returns>A string that contains the parent and child segments of the path joined by a path separator.</returns>
''' <remarks></remarks>
Protected Overrides Function MakePath(parent As String, child As String) As String
Trace.WriteLine("::MakePath(parent:=" & parent & ",child:=" & child & ")")
Dim res As String = MyBase.MakePath(parent, child)
Trace.WriteLine("::MakePath(parent:=" & parent & ",child:=" & child & ") " & res)
If parent = "." Then
'res = ".\" & child.Split("\").Last
If String.IsNullOrEmpty(Me.SessionState.Path.CurrentLocation.ProviderPath) Then
res = parent & PATH_SEPARATOR & child
Else
res = parent & PATH_SEPARATOR & child.Substring(Me.SessionState.Path.CurrentLocation.ProviderPath.Length + 1)
'res = parent & PATH_SEPARATOR & child.Replace(Me.SessionState.Path.CurrentLocation.ProviderPath & PATH_SEPARATOR, String.Empty)
End If
Trace.WriteLine("::**** TRANSFORM: " & res)
End If
Return res
End Function
答案 1 :(得分:1)
如果您设计了提供程序,以便在创建新驱动器时输入非空根,则可以解决此问题。我注意到如果尚未设置PSDriveInfo的Root属性,则tab完成错误地建议完整子路径而不是只是子名。
可能限制某些提供程序始终需要非空根。如果您不想让用户在创建新驱动器时始终输入一些Root,则上面的解决方法很有效。
答案 2 :(得分:0)
我已将此列为Microsoft Connect中的PowerShell提供程序错误:Issue with relative path tab-completion (via Get-ChildNames) for NavigationCmdletProvider
如果有人可以重现这一点,请访问该链接然后这样说,因为如果只有一个人报告,微软可能不会对此进行调查。
看起来这在PowerShell 3.0中得到了修复。我不知道微软为什么不想在旧版本中修复它,这不是任何代码可能依赖的东西。
答案 3 :(得分:0)
我能够使其覆盖string[] ExpandPath(string path)
并设置ProviderCapabilities.ExpandWildcards
功能。