【问题标题】:Is module auto-loading meant to be reliable?模块自动加载是否意味着可靠?
【发布时间】:2023-03-13 16:51:01
【问题描述】:

环境

我有以下文件夹结构,用于保存 powershell 模块:

C:
  PsModules
     ...
     util
        util.psm1 (this contains implementation of 'Test-Function')
        util.test.ps1
     ftp
        ftp.psm1
        http.test.ps1
     ... 

c:\PsModules 中大约有 50 个文件夹和模块。

我已将环境变量PSModulePath 设置为包含c:\PsModules。这似乎符合“格式良好的模块”described in Microsoft's documentationthis answer 的条件。

症状

有时 Test-Function 在从 ISE 调用时不会自动找到。事实上,在任何给定的 ISE 新推出时,总会有一些(看似不可预测的)模块无法自动找到。例如,无法自动找到Test-Function,如下所示:

PS C:\> Test-Function
Test-Function : The term 'Test-Function' is not recognized as the name 
of a cmdlet, function, script file, or operable program. Check the 
spelling of the name, or if a path was included, verify that the path is 
correct and try again.
...
+ FullyQualifiedErrorId : CommandNotFoundException

乍一看,这似乎表明util.psm1 不是“格式正确的”。如果它不是“格式正确的”,那么 ListAvailable 应该不起作用。但它确实有效:

c:\> get-module -ListAvailable util
Directory: c:\PsModules\util

ModuleType Version    Name                 ExportedCommands
---------- -------    ----                 ----------------
Script     0.0        util

PS C:\> Test-Function
...
+ FullyQualifiedErrorId : CommandNotFoundException

另外,模块调用Get-Command后,模块中的命令就可以通用了:

c:\> Get-Command -Module util
CommandType     Name                             ModuleName
-----------     ----                             ----------
Function        Test-Function                    util
c:\> Test-Function
Call to Test-Function succeeded!

问题

  1. 自动发现和模块自动加载是否应该可靠且可预测?

  2. 如何解决为什么 powershell 有时在调用 Get-Command -module 之前找不到命令?

  3. 依靠 powershell 自动加载模块是不好的做法吗?如果是这样,自动加载模块的好习惯是什么?

【问题讨论】:

    标签: powershell module autoloader


    【解决方案1】:

    我发现模块清单中的FunctionsToExport部分不能设置为*

    这很糟糕:

    # Functions to export from this module, for best performance, do not use 
    # wildcards and do not delete the entry, use an empty array if there are no 
    # functions to export.
    FunctionsToExport = '*'
    

    这很好:

    # Functions to export from this module...
    FunctionsToExport = 'Test-Function, Test-Function2'
    

    【讨论】:

      【解决方案2】:

      如果这对其他人有帮助,我认为这可能是 ISE 独有的问题。我无法重现,但最近与 MS 讨论了不一致的 ISE 工作流程行为,经过一番努力,问题在没有解决方案的情况下关闭,官方回答是不使用未经批准用于生产的 ISE,而是使用本机 shell。这对我们来说是一个现实的答案,从来没有在原生 shell 中看到过问题。请问这个症状是不是也一样?

      【讨论】:

      • 这很有趣。你有没有得到任何关于加载模块失败的机制的迹象?
      • 我们的主要症状是会话将锁定/挂起并变得不可用,但我们也看到偶尔的模块加载失败,但这种症状更加稀疏,因此我们没有过多关注它。有消息说 ISE 不适用于生产,此时所有调查都完全停止了。希望我能提供更多帮助。
      【解决方案3】:

      我不能说模块自动加载是否有意是可靠的,但我个人在完成的代码中并不依赖它。

      如果我正在编写脚本或模块,我总是使用Import-Module TheModule -ErrorAction Stop,并且经常使用#Requires -Module AciveDirectory,TheModule,SQLPs 来确保模块可用。

      对于 PowerShell 控制台或 ISE 中的交互式使用,我通常依赖自动加载,但如果失败,我只需手动 Import-Module 进行会话。

      在我总是希望为交互式会话加载特定模块的情况下,我将其加载到配置文件中。要查看各种配置文件,请运行此(从 ISE 和控制台):

      $profile | Get-Member -MemberType NoteProperty
      

      您可以根据您希望模块可用的用户和主机来决定要将模块导入代码的位置。

      到目前为止,我只为posh-git 这样做,但它似乎很适合您的用例。

      【讨论】:

        猜你喜欢
        • 2020-07-29
        • 1970-01-01
        • 2020-11-28
        • 2020-09-19
        • 2016-04-27
        • 2020-10-01
        • 2014-08-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多