diff --git a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs index 0a4e51fc74..f1f8aaff1f 100644 --- a/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs +++ b/src/System.Management.Automation/engine/Modules/ModuleCmdletBase.cs @@ -4379,7 +4379,7 @@ namespace Microsoft.PowerShell.Commands { try { - string fixedFileName = FixupFileName(moduleBase, s, extension, importingModule); + string fixedFileName = FixupFileName(moduleBase, s, extension, importingModule, skipLoading: true); var dir = Path.GetDirectoryName(fixedFileName); if (string.Equals(psHome, dir, StringComparison.OrdinalIgnoreCase) || @@ -4537,9 +4537,9 @@ namespace Microsoft.PowerShell.Commands /// /// A utility routine to fix up a file name so it's rooted and has an extension. /// - internal string FixupFileName(string moduleBase, string name, string extension, bool isImportingModule) + internal string FixupFileName(string moduleBase, string name, string extension, bool isImportingModule, bool skipLoading = false) { - return FixupFileName(moduleBase, name, extension, isImportingModule, pathIsResolved: out _); + return FixupFileName(moduleBase, name, extension, isImportingModule, pathIsResolved: out _, skipLoading); } /// @@ -4554,10 +4554,11 @@ namespace Microsoft.PowerShell.Commands /// The extension to use in case the given name has no extension. /// Indicate if we are loading a module. /// Indicate if the returned path is fully resolved. + /// Indicate if the resolved module should be loaded. /// /// The resolved file path. Or, the combined path of and when the file path cannot be resolved. /// - internal string FixupFileName(string moduleBase, string name, string extension, bool isImportingModule, out bool pathIsResolved) + internal string FixupFileName(string moduleBase, string name, string extension, bool isImportingModule, out bool pathIsResolved, bool skipLoading = false) { pathIsResolved = false; string originalName = name; @@ -4585,7 +4586,7 @@ namespace Microsoft.PowerShell.Commands // Return the path if successfully resolved. if (resolvedPath != null) { - if (isImportingModule && resolvedPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)) + if (isImportingModule && resolvedPath.EndsWith(".dll", StringComparison.OrdinalIgnoreCase) && !skipLoading) { // If we are fixing up an assembly file path and we are actually loading the module, then we load the resolved assembly file here. // This is because we process type/format ps1xml files before 'RootModule' and 'NestedModules' entries during the module loading. diff --git a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 index b6f40b0d5f..d7216720dd 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Core/Import-Module.Tests.ps1 @@ -361,3 +361,36 @@ Describe "Import-Module -Force behaviour" -Tag "CI" { { Test-Two } | Should -Throw -ErrorId 'CommandNotFoundException' } } + +Describe "Module with FileList" -Tag "CI" { + BeforeAll { + $src = @" + using System; + namespace ModuleCmdlets + { + public class FileListLoad + { + } + } +"@ + + $originalPSModulePath = $env:PSModulePath + New-Item -ItemType Directory -Path "$testdrive\Modules\FileListLoadTest\" -Force > $null + + $asmPath = "$TESTDRIVE\Modules\FileListLoadTest\FileListLoadTest.dll" + Add-Type -TypeDefinition $src -OutputAssembly $asmPath + + $env:PSModulePath += [System.IO.Path]::PathSeparator + "$testdrive\Modules" + New-ModuleManifest -Path "$testdrive\Modules\FileListLoadTest\FileListLoadTest.psd1" -FileList @("FileListLoadTest.dll") + } + + AfterAll { + $env:PSModulePath = $originalPSModulePath + } + + It "Assemblies in FileList are not loaded" { + Import-Module FileListLoadTest + $asms = [System.AppDomain]::CurrentDomain.GetAssemblies().Location + $asmPath | Should -Not -BeIn $asms + } +}