我在非标准路径下有一个模块(MyModule),即不在$env:PSModulePath -split ";"
中列出的常用位置下。但是,我已经将MyModule的"生产"路径添加到该环境变量中,同时我继续处理"开发"副本。
在尝试调试某些内容时,我使用以下命令加载了模块(带有$VerbosePreference = "Continue"
),并立即看到两行看似矛盾的详细输出:
[D:DevUserA]> Import-Module D:DevUserAlibsPowerShellMyModule
VERBOSE: Loading module from path 'D:DevUserAlibsPowerShellMyModuleMyModule.psd1'.
VERBOSE: Loading module from path 'D:DevuseraMyModule2MyModule.psm1'.
我想了解为什么 Import-Module 似乎加载了两次模块,尤其是当第二条路径不正确时。
更多详情:
该模块的文件夹结构为:
MyModuleMyModule.psd1
MyModuleMyModule.Test-Module.xml
MyModuleMyModule1MyModule.psm1
MyModuleMyModule2MyModule.psm1
注意 (1) 我在 MyModule1 子文件夹中保留了此模块的较旧"版本 1",并将更新的"版本 2"文件放在 MyModule2 子文件夹中,以及 (2) 自定义模块测试脚本使用该.xml文件列出测试用例。我很确定后者可以忽略不计。
我的模块清单 (.psd1) 文件包含以下内容,所有其他行均为空白或注释:
@{
RootModule = '.MyModule2MyModule.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'
'.MyModule1MyModule.psm1'
'.MyModule2MyModule.psm1'
'.MyModule2ExamplesArchive-FilesWithCompression.ps1'
)
}
显然,我已经为文件使用了相对路径,尤其是 RootModule 键; 这是必要的,因为我无法确定在共享模块时将模块复制到何处。
回到详细输出,我可以看到这两行显示 (1) PSD1 文件的正确路径和 (2) PSM1 文件的无效路径。我确实注意到第二条路径的用户名是小写的,这就是我在测试前Set-Location
时碰巧输入它的方式。因此,看起来第一条路径是通过将 MyModule.psd1 追加到提供给Import-Module
cmdlet 的路径来采用的,第二条路径是 (获取位置) 和根模块路径的串联。
这似乎只发生在这个模块上。我在同一个"根"文件夹下有其他人没有表现出这种行为。
嗯,好的。我可能已经解决了,至少部分...
我不小心在运行导入模块 cmdlet 的位置下创建了 MyModule2 子文件夹的副本。删除该文件夹后,详细的输出开始更有意义:
[D:DevUserA]> Import-Module D:DevUserAlibsPowerShellMyModule
VERBOSE: Loading module from path 'D:DevUserAlibsPowerShellMyModuleMyModule.psd1'.
VERBOSE: Loading module from path 'D:DevUserAlibsPowerShellMyModule.MyModule2MyModule.psm1'.
VERBOSE: Exporting function '<function>'.
....
我想这意味着当 PowerShell 解析清单文件中的 RootModule 时,它会首先在当前路径下查找,如果未找到任何内容,则先查看主模块文件夹。我发现这有悖常理,因为我希望清单中的任何相对路径始终是相对于 PSD1 文件,而不是当前位置。
如果我立即尝试再次导入模块,我会得到这个:
[D:DevUserA]> Import-Module D:DevUserAlibsPowerShellMyModule
VERBOSE: Loading module from path 'D:DevUserAlibsPowerShellMyModuleMyModule.psd1'.
VERBOSE: Importing function '<function>'.
....
也就是说,只有一个"加载模块"行,而不是两行详细输出。然后我尝试了-Force
开关,得到了以下内容:
[D:DevUserA]> Import-Module D:DevUserAlibsPowerShellMyModule -Force
VERBOSE: Loading module from path 'D:DevUserAlibsPowerShellMyModuleMyModule.psd1'.
VERBOSE: Removing the imported "<function>" function.
....
VERBOSE: Loading module from path 'D:DevUserAlibsPowerShellMyModule.MyModule2MyModule.psm1'.
VERBOSE: Exporting function '<function>'.
....
VERBOSE: Importing function '<function>'.
....
因此,似乎在首次导入模块或强制重新导入模块时会出现两行详细输出,但如果它已经是会话的一部分,那么您只能看到第一行。
此外,我终于发现详细输出区分了导出函数和导入函数。函数按在 PSM1 文件中定义的顺序导出,但按字母顺序导入。这表明使用一个或两个阶段的过程,具体取决于是否从 PSM1 文件中重新读取函数定义,这与我们是否看到一行或两行详细输出相关联。
或者,为了更直接地回答这个问题,似乎有两行说"加载模块..."当它需要读取 .psm1 文件时,当 PowerShell 已经知道模块及其内容时,只有一行。