【问题标题】:Loading a Powershell Module from the C# code of a custom Provider从自定义提供程序的 C# 代码加载 Powershell 模块
【发布时间】:2015-09-25 15:44:39
【问题描述】:

我一直在研究一个非常具体的“需要”功能,以绑定到我用 C# 编写的自定义提供程序。

基本上我开始寻找一种方法来复制

A:
B:

等 PowerShell 加载时定义的函数,因此不必键入

CD A:

你可以做前面提到的

A:

我首先尝试让我的提供程序将函数注入运行空间,但我似乎完全错过了如何让它工作的时机,所以我选择了另一条路线。

基本上我有一个非常简单的 PSM1 文件 UseColons.psm1

function Use-ColonsForPSDrives
{
    [CmdletBinding()] Param()

    Write-Verbose "Looping Through Installed PowerShell Providers"
    Get-PSProvider | % `
    {
        Write-Verbose "Found $($_.Name) checking its drives"
        $_.Drives | ? { (Get-Command | ? Name -eq "$($_.Name):") -eq $null } | `
        { 
            Write-Verbose "Setting up: `"function $($_.Name):() {Set-Location $($_.Name):}`""
            if ($Verbose)
            {
                . Invoke-Expression -Command "function $($_.Name):() {Set-Location $($_.Name):}" 
            }
            else
            {
                . Invoke-Expression -Command "function $($_.Name):() {Set-Location $($_.Name):}" -ErrorAction SilentlyContinue
        }
            Write-Verbose "Finished with drive $($_.Name)"
        }
    }
    # Cert and WSMan do not show up as providers until you try to naviagte to their drives
    # As a result we will add their functions manually but we will check if they are already set anyways
    if ((Get-Command | ? Name -eq "Cert:") -eq $null) { . Invoke-Expression -Command "function Cert:() {Set-Location Cert:}" }
    if ((Get-Command | ? Name -eq "WSMan:") -eq $null) { . Invoke-Expression -Command "function WSMan:() {Set-Location WSMan:}" }
}

. Use-ColonsForPSDrives

简单来说,它遍历所有加载的提供程序,然后遍历每个提供程序的所有驱动器,然后检查 Function: 驱动器是否包含与 {DriveName}: 格式匹配的函数,如果找不到,则创建一个。

psd1文件无非就是导出所有函数

这存储在它自己的文件夹下的 %ProgramFiles%\WindowsPowerShell\Modules 路径中

最后我在 %windir%\system32\windowspowershell\v1.0 目录下有了 profile.ps1

Remove-Module UseColons -ErrorAction SilentlyContinue
Import-Module UseColons

所以当我加载 PowerShell 或 ISE 时,如果我想通过我可以调用的变量说 dir

Variable:

或者如果我需要切换回注册表

HKLM:
HKCU:

当您与多个供应商合作时,您在切换时一遍又一遍地键入 CD,这很烦人。

对于这个问题,我仍在努力开发最初打算用于的实际 PowerShell 提供程序。但是,当我调试它时,UseColons 模块会在 Visual Studio 转身之前加载并加载新的提供程序,因此如果我手动删除并再次导入该模块,它会完成它的工作,并且我拥有我的提供程序的所有驱动功能。

在冗长的解释之后,我想知道我该怎么做:

  • 设置我的 UseColons 模块以加载 LAST
  • 找到一种方法,让我的自定义提供程序(技术上是一个模块,因为它具有提供程序和自定义 Cmdlet)在初始化时加载 UseColons 模块
  • 我不想将它从我的标准配置文件中删除,因为当我不使用新的提供程序并且只是使用 powershell 进行管理工作时,它非常有用。

    希望有人可以给我一些想法或指出一些好的更深入的 powershell 提供程序文档和操作方法的方向。

    【问题讨论】:

      标签: c# powershell powershell-provider


      【解决方案1】:

      在您的模块清单 (.psd1) 中,您有一个 DLL 作为 RootModule?

      这是一个可怕的 hack,对将来创建的驱动器没有帮助,但是...

      在您的模块清单中,不要将 YourProvider.dll 作为 RootModule,而是使用 Dummy.psm1(可以是空文件)。然后,对于 NestedModules,使用 @( 'YourProvider.dll', 'UseColons' )。这允许在 YourProvider.dll 之后加载 UseColons 模块。 (假人将在最后。)

      【讨论】:

        猜你喜欢
        • 2010-12-12
        • 2013-01-01
        • 1970-01-01
        • 2014-08-18
        • 2019-11-23
        • 1970-01-01
        • 1970-01-01
        • 2021-09-23
        相关资源
        最近更新 更多