diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData.cs
index c8d0b26ae..a098b08f1 100644
--- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData.cs
+++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayDescriptionData.cs
@@ -574,6 +574,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
{
internal DatabaseLoadingInfo loadingInfo = null;
internal string assemblyName = null;
+ internal string assemblyLocation = null;
internal string baseName = null;
internal string resourceId = null;
}
diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayResourceManagerCache.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayResourceManagerCache.cs
index 04cbdf9a1..84dac0626 100644
--- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayResourceManagerCache.cs
+++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/displayResourceManagerCache.cs
@@ -77,7 +77,10 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
result = LoadingResult.AssemblyNotFound;
return null;
}
-
+ else
+ {
+ resourceReference.assemblyLocation = loadResult.a.Location;
+ };
// load now the resource from the resource manager cache
try
diff --git a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataXmlLoader.cs b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataXmlLoader.cs
index 81bb4148f..b5ef5a277 100644
--- a/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataXmlLoader.cs
+++ b/src/System.Management.Automation/commands/utility/FormatAndOutput/common/DisplayDatabase/typeDataXmlLoader.cs
@@ -1832,8 +1832,7 @@ namespace Microsoft.PowerShell.Commands.Internal.Format
{
case DisplayResourceManagerCache.AssemblyBindingStatus.FoundInPath:
{
- assemblyDisplayName =
- System.IO.Path.Combine(resource.loadingInfo.fileDirectory, resource.assemblyName);
+ assemblyDisplayName = resource.assemblyLocation;
}
break;
case DisplayResourceManagerCache.AssemblyBindingStatus.FoundInGac:
diff --git a/src/System.Management.Automation/utils/ResourceManagerCache.cs b/src/System.Management.Automation/utils/ResourceManagerCache.cs
index 11c72b60b..cc9db9bae 100644
--- a/src/System.Management.Automation/utils/ResourceManagerCache.cs
+++ b/src/System.Management.Automation/utils/ResourceManagerCache.cs
@@ -177,8 +177,38 @@ namespace System.Management.Automation
throw PSTraceSource.NewArgumentException("resourceId");
}
- ResourceManager resourceManager = GetResourceManager(assembly, baseName);
- string text = resourceManager.GetString(resourceId);
+ ResourceManager resourceManager = null;
+ string text = string.Empty;
+
+ // For a non-existing resource defined by {assembly,baseName,resourceId}
+ // MissingManifestResourceException is thrown only at the time when resource retrieval method
+ // such as ResourceManager.GetString or ResourceManager.GetObject is called,
+ // not when you instantiate a ResourceManager object.
+ try
+ {
+ // try with original baseName first
+ // if it fails then try with alternative resource path format
+ resourceManager = GetResourceManager(assembly, baseName);
+ text = resourceManager.GetString(resourceId);
+ }
+ catch (MissingManifestResourceException)
+ {
+ const string resourcesSubstring = ".resources.";
+ int resourcesSubstringIndex = baseName.IndexOf(resourcesSubstring);
+ string newBaseName = string.Empty;
+ if (resourcesSubstringIndex != -1)
+ {
+ newBaseName = baseName.Substring(resourcesSubstringIndex + resourcesSubstring.Length); // e.g. "FileSystemProviderStrings"
+ }
+ else
+ {
+ newBaseName = string.Concat(assembly.GetName().Name, resourcesSubstring, baseName); // e.g. "System.Management.Automation.resources.FileSystemProviderStrings"
+ }
+
+ resourceManager = GetResourceManager(assembly, newBaseName);
+ text = resourceManager.GetString(resourceId);
+ }
+
if (String.IsNullOrEmpty(text) && s_DFT_monitorFailingResourceLookup)
{
Diagnostics.Assert(false,
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Update-FormatData.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Update-FormatData.Tests.ps1
index 3e679a49b..3c54917f6 100644
--- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Update-FormatData.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Update-FormatData.Tests.ps1
@@ -14,16 +14,16 @@ Describe "Update-FormatData" -Tags "CI" {
}
Context "Validate Update-FormatData update correctly" {
- It "Should not throw upon reloading previous formatting file" {
- { Update-FormatData } | Should Not throw
- }
+ It "Should not throw upon reloading previous formatting file" {
+ { Update-FormatData } | Should Not throw
+ }
- It "Should validly load formatting data" {
- Get-FormatData -typename System.Diagnostics.Process | Export-FormatData -Path $path
+ It "Should validly load formatting data" {
+ Get-FormatData -typename System.Diagnostics.Process | Export-FormatData -Path $path
$null = $ps.AddScript("Update-FormatData -prependPath $path")
$ps.Invoke()
$ps.HadErrors | Should be $false
- }
+ }
}
}
@@ -32,7 +32,7 @@ Describe "Update-FormatData basic functionality" -Tags "CI" {
$testfilename = "testfile.ps1xml"
$testfile = Join-Path -Path $TestDrive -ChildPath $testfilename
- $xmlContent=@"
+ $xmlContent=@"
AnyName
@@ -48,12 +48,60 @@ Describe "Update-FormatData basic functionality" -Tags "CI" {
"@
- $xmlContent > $testfile
+ $xmlContent > $testfile
}
- It "Update-FormatData with WhatIf should work"{
+ It "Update-FormatData with WhatIf should work"{
{ Update-FormatData -Append $testfile -WhatIf } | Should Not Throw
{ Update-FormatData -Prepend $testfile -WhatIf } | Should Not Throw
- }
+ }
+}
+
+
+Describe "Update-FormatData with resources in CustomControls" -Tags "CI" {
+
+ BeforeAll {
+ $templatePath = Join-Path $PSScriptRoot (Join-Path 'assets' 'UpdateFormatDataTests.format.ps1xml')
+ $formatFilePath = Join-Path $TestDrive 'UpdateFormatDataTests.format.ps1xml'
+ $ps = [powershell]::Create()
+ $iss = [system.management.automation.runspaces.initialsessionstate]::CreateDefault2()
+ $rs = [system.management.automation.runspaces.runspacefactory]::CreateRunspace($iss)
+ $rs.Open()
+ $ps.Runspace = $rs
+ }
+ AfterAll {
+ $rs.Close()
+ $ps.Dispose()
+ }
+ Context "Validate Update-FormatData" {
+ It "Resources in WindowsPS syntax should be loaded successfully" {
+ $format = Get-Content -Path $templatePath -Raw
+ $format.Replace("%BaseName%","FileSystemProviderStrings") | Set-Content -Path $formatFilePath -Force
+ $null = $ps.AddScript("Update-FormatData -PrependPath $formatFilePath")
+ $ps.Streams.Error.Clear()
+ $ps.Invoke()
+ $ps.Streams.Error | Should BeNullOrEmpty
+
+ }
+ It "Resources in CorePS syntax should be loaded successfully" {
+ $format = Get-Content -Path $templatePath -Raw
+ $format.Replace("%BaseName%","System.Management.Automation.resources.FileSystemProviderStrings") | Set-Content -Path $formatFilePath -Force
+ $null = $ps.AddScript("Update-FormatData -PrependPath $formatFilePath")
+ $ps.Streams.Error.Clear()
+ $ps.Invoke()
+ $ps.Streams.Error | Should BeNullOrEmpty
+ }
+ It "Verify assembly path in error message when resource is Not found" {
+ $format = Get-Content -Path $templatePath -Raw
+ $format.Replace("%BaseName%","NonExistingResource") | Set-Content -Path $formatFilePath -Force
+ $null = $ps.AddScript("Update-FormatData -PrependPath $formatFilePath")
+ $ps.Streams.Error.Clear()
+ $ps.Invoke()
+ $sma = [appdomain]::CurrentDomain.GetAssemblies() | ? { if ($_.Location) {$_.Location.EndsWith("System.Management.Automation.dll")}}
+ $smaLocation = $sma.Location
+ $ps.Streams.Error | %{ $_.Exception.Message.Contains($smaLocation) | Should be $true }
+ $ps.Streams.Error | %{ $_.FullyQualifiedErrorId | Should Match 'FormatXmlUpdateException' }
+ }
+ }
}
diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/UpdateFormatDataTests.format.ps1xml b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/UpdateFormatDataTests.format.ps1xml
new file mode 100644
index 000000000..8d4091035
--- /dev/null
+++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/assets/UpdateFormatDataTests.format.ps1xml
@@ -0,0 +1,31 @@
+
+
+
+ TestTypes
+
+ NonExistingTestType
+
+
+
+
+
+
+ TestTypes-GroupingFormat
+
+
+
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+