【问题标题】:Import-Module Verbose output implies module is loaded twiceImport-Module Verbose 输出意味着模块被加载了两次
【发布时间】:2016-04-27 16:49:07
【问题描述】:

我在非标准路径下有一个模块 (MyModule),即不在$env:PSModulePath -split ";" 中列出的通常位置下。但是,我已将 MyModule 的“生产”路径添加到该环境变量中,同时继续处理“开发”副本。

在尝试调试某些东西时,我使用以下命令加载了模块(使用$VerbosePreference = "Continue"),并立即看到两条看似矛盾的详细输出行:

[D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule

VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
VERBOSE: Loading module from path 'D:\Dev\usera\MyModule2\MyModule.psm1'.

我想了解为什么 Import-Module 似乎加载了两次模块,尤其是在第二个路径不正确的情况下。


更多细节:

模块的文件夹结构是:

MyModule\MyModule.psd1
MyModule\MyModule.Test-Module.xml
MyModule\MyModule1\MyModule.psm1
MyModule\MyModule2\MyModule.psm1

注意 (1) 我在 MyModule1 子文件夹中保留了该模块的旧“版本 1”,并将更新后的“版本 2”文件放在 MyModule2 子文件夹中,并且 (2) 使用了 .xml 文件通过自定义模块测试脚本列出测试用例。我很确定后者可以忽略。

我的模块清单 (.psd1) 文件包含以下内容,所有其他行均为空白或 cmets:

@{
  RootModule = '.\MyModule2\MyModule.psm1'
  ModuleVersion = '2.0.0.0'
  GUID = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'
  Author = 'Old Developer (v1.x) & New Developer (v2.x)'
  CompanyName = 'MyCompany'
  Copyright = '(c) 2013-2015 MyCompany. All rights reserved.'
  Description = 'Really useful functions'
  FileList = @(
    '.\MyModule.psd1'
    '.\MyModule.Test-Module.xml'
    '.\MyModule1\MyModule.psm1'
    '.\MyModule2\MyModule.psm1'
    '.\MyModule2\Examples\Archive-FilesWithCompression.ps1'
  )
}

很明显,我使用了文件的相对路径,尤其是。 RootModule 键;这是必要的,因为我无法确定共享模块时会将其复制到哪里。

回到 Verbose 输出,我可以看到两行显示 (1) PSD1 文件的正确路径和 (2) PSM1 文件的无效路径。我确实注意到第二个路径的用户名是小写的,这就是我在测试前Set-Location 时碰巧输入它的方式。因此,看起来第一个路径是通过将 MyModule.psd1 附加到给定给 Import-Module cmdlet 的路径而采用的,第二个是 (Get-Location) 和 RootModule 路径的串联。

这似乎只发生在这个模块上。我在同一个“根”文件夹下有其他人没有表现出这种行为。

【问题讨论】:

    标签: powershell module relative-path verbose


    【解决方案1】:

    嗯。好的。我可能已经解决了,至少部分...

    我不小心在运行 Import-Module cmdlet 的位置下复制了 MyModule2 子文件夹。一旦我删除了那个文件夹,详细的输出就开始变得更有意义了:

    [D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule
    
    VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
    VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\.\MyModule2\MyModule.psm1'.
    VERBOSE: Exporting function '<function>'.
    ....
    

    我猜这意味着当 PowerShell 解析清单文件中的 RootModule 时,它首先会在当前路径下查找,然后如果没有找到主模块文件夹。我发现这违反直觉,因为我希望清单中的任何相对路径总是相对于 PSD1 文件,而不是当前位置。

    如果我然后尝试再次导入模块立即我得到这个:

    [D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule
    
    VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
    VERBOSE: Importing function '<function>'.
    ....
    

    即只有一行“加载模块”,而不是两行详细输出。然后我尝试了-Force 开关并得到以下结果:

    [D:\Dev\UserA\]> Import-Module D:\Dev\UserA\libs\PowerShell\MyModule -Force
    
    VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\MyModule.psd1'.
    VERBOSE: Removing the imported "<function>" function.
    ....
    VERBOSE: Loading module from path 'D:\Dev\UserA\libs\PowerShell\MyModule\.\MyModule2\MyModule.psm1'.
    VERBOSE: Exporting function '<function>'.
    ....
    VERBOSE: Importing function '<function>'.
    ....
    

    所以,似乎在模块首次导入或强制重新导入时出现了两行详细输出,但如果它已经是会话的一部分,那么您只会看到第一行。

    此外,我终于发现详细输出在 exporting 函数和 importing 它们之间存在差异。这些函数按它们在 PSM1 文件中定义的顺序导出,但按字母顺序导入。这表明使用一阶段或两阶段过程取决于是否从 PSM1 文件中重新读取函数定义,这与我们是否看到一两行详细输出有关。

    或者,为了更直接地回答这个问题,当它需要读取 .psm1 文件时,似乎有两行说“正在加载模块...”,而当 PowerShell 已经知道该模块和它的内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 2018-08-22
      • 2021-05-27
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 2013-02-04
      • 2011-07-27
      相关资源
      最近更新 更多