2016-01-21 68 views
0

我在非标准路径下有一个模块(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'. 

我想明白为什么导入模块出现要加载模块两次,尤其是当第二个路径不正确时。


更详细地:

用于模块的文件夹结构是:

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

注(1)I在一个MyModule1子文件夹下保持该模块的旧 “版本1”并将我更新后的“版本2”文件放入MyModule2子文件夹中,以及(2)自定义模块测试脚本使用.xml文件列出测试用例。我很确定后者可以被忽略。

我的模块清单(的.psd1)文件包含以下,与所有其他行是空白或注解:

@{ 
    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' 
) 
} 

的文件显然我已经使用相对路径,ESP。 RootModule key;这是必要的,因为我无法确定模块在分享时将被复制到何处。回到Verbose输出,我可以看到两行显示(1)PSD1文件的正确路径和(2)PSM1文件的无效路径。我确实注意到第二条路径的用户名是小写的,这正是我在测试之前碰巧输入的名称。因此,看起来第一个路径是通过将MyModule.psd1附加到给定的Import-Module cmdlet的路径来实现的,第二个路径是(Get-Location)和RootModule路径的串联。

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

回答

0

嗯。好。我可能已经完成了,至少部分是...

我不小心在我运行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>'. 
.... 

所以,似乎详细输出的两行出现在模块首次被导入,或强行重新进口,但如果它已经的一部分届时你只会看到第一行。

而且,我终于发现了那出口功能和进口他们之间的区别详细输出。这些功能是导出的,它们是按照它们在PSM1文件中定义的顺序排列的,但按字母顺序依次导入。这表明使用一个或两个阶段的过程,取决于是否从PSM1文件重新读取函数定义,与我们是否看到一行或两行详细输出相关。

或者,为了更直接地回答这个问题,当需要读取.psm1文件时,似乎有两行显示“加载模块...”,并且PowerShell已经知道该模块时只有一行及其内容。