自定义Powershell Provider实现

时间:2014-09-02 21:00:14

标签: c# powershell

我想创建一个像目录结构一样工作的PowerShell提供程序。 根是一个返回文本文件的Web地址。此文件包含项目列表。当这些项目中的每一项都附加到原始网址的末尾时,我会得到另一个文件,其中包含另一个项目列表。这将以递归方式进行,直到文件不返回任何项目。所以结构就像:

root: 1.2.3.4/test/     -> returns file0
file0: item1, item2, item3

1.2.3.4/test/item1      -> returns file1
1.2.3.4/test/item2      -> returns file2
1.2.3.4/test/item3      -> returns file3

file1: item4, item5
file2: item6
file3: <empty>

由于我想创建类似导航的结构,我扩展了NavigationCmdletProvider

public class TESTProvider : NavigationCmdletProvider

我可以按如下方式创建新的PSDrive:

PS c:\> New-PSDrive -Name dr1 -PSProvider TestProvider -Root http://1.2.3.4/v1

Name           Used (GB)     Free (GB) Provider     Root                                            CurrentLocation
----           ---------     --------- --------      -------------------
dr1                                    TestProvider  http://1.2.3.4/v1

但当我'cd'到那个驱动器时,我收到一个错误:

PS c:\> cd dr1:

cd : Cannot find path 'dr1:\' because it does not exist.
At line:1 char:1
+ cd dr1:
+ ~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (dr1:\:String) [Set-Location], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand

我需要使用什么方法来实现/覆盖以将提示显示为PS dr1:&gt;当我做cd dr1:? (在此之后我明白我必须覆盖GetChildItems(string path, bool recurse)才能获得列出item1,item2,item3。)

1 个答案:

答案 0 :(得分:3)

我发现实施IsValidPathItemExistsIsItemContainerGetChildren会让您进入工作状态。这是我在实现导航提供程序时通常首先要做的事情:

[CmdletProvider("MyPowerShellProvider", ProviderCapabilities.None)]
public class MyPowerShellProvider : NavigationCmdletProvider
{

    protected override bool IsValidPath(string path)
    {
        return true;
    }

    protected override Collection<PSDriveInfo> InitializeDefaultDrives()
    {
        PSDriveInfo drive = new PSDriveInfo("MyDrive", this.ProviderInfo, "", "", null);
        Collection<PSDriveInfo> drives = new Collection<PSDriveInfo>() {drive};
        return drives;
    }

    protected override bool ItemExists(string path)
    {
        return true;
    }

    protected override bool IsItemContainer(string path)
    {
        return true;
    }

    protected override void GetChildItems(string path, bool recurse)
    {
        WriteItemObject("Hello", "Hello", true);
    }
}