From 12f9f0f507ea45f4ec62dc9fcd9783cc26a4ab9c Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 14 Jan 2019 17:04:33 +0100 Subject: [PATCH 1/6] Make ResourceManager use Assembly instead of RuntimeAssembly internally. --- .../src/System/Reflection/RuntimeAssembly.cs | 21 +++--- .../ManifestBasedResourceGroveler.cs | 74 ++++++++++++------- .../src/System/Resources/ResourceManager.cs | 34 +++++---- 3 files changed, 78 insertions(+), 51 deletions(-) diff --git a/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs index 3035117b9e53..14929d660983 100644 --- a/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs @@ -335,7 +335,7 @@ internal static RuntimeAssembly InternalLoadAssemblyName( bool throwOnFileNotFound, IntPtr ptrLoadContextBinder = default) { - return InternalLoadAssemblyName(assemblyRef, reqAssembly, ref stackMark, IntPtr.Zero, true /*throwOnError*/, ptrLoadContextBinder); + return InternalLoadAssemblyName(assemblyRef, reqAssembly, ref stackMark, IntPtr.Zero, throwOnFileNotFound, ptrLoadContextBinder); } internal static RuntimeAssembly InternalLoadAssemblyName( @@ -646,15 +646,13 @@ public override Assembly GetSatelliteAssembly(CultureInfo culture, Version versi if (culture == null) throw new ArgumentNullException(nameof(culture)); - string name = GetSimpleName() + ".resources"; - return InternalGetSatelliteAssembly(name, culture, version, true); + return InternalGetSatelliteAssembly(culture, version, true); } [System.Security.DynamicSecurityMethod] // Methods containing StackCrawlMark local var has to be marked DynamicSecurityMethod - internal RuntimeAssembly InternalGetSatelliteAssembly(string name, - CultureInfo culture, - Version version, - bool throwOnFileNotFound) + internal Assembly InternalGetSatelliteAssembly(CultureInfo culture, + Version version, + bool throwOnFileNotFound) { // This stack crawl mark is never used because the requesting assembly is explicitly specified, // so the value could be anything. @@ -670,13 +668,18 @@ internal RuntimeAssembly InternalGetSatelliteAssembly(string name, an.Version = version; an.CultureInfo = culture; - an.Name = name; + an.Name = GetSimpleName() + ".resources"; RuntimeAssembly retAssembly = nLoad(an, null, this, ref stackMark, IntPtr.Zero, throwOnFileNotFound); - if (retAssembly == this || (retAssembly == null && throwOnFileNotFound)) + if (retAssembly == this) + { + retAssembly = null; + } + + if (retAssembly == null && throwOnFileNotFound) { throw new FileNotFoundException(string.Format(culture, SR.IO_FileNotFound_FileName, an.Name)); } diff --git a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs index 42b601336a55..8aee3417c2e6 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -58,7 +58,7 @@ public ResourceSet GrovelForResourceSet(CultureInfo culture, Dictionary UltimateResourceFallbackLocation.Satellite) { @@ -228,7 +226,7 @@ internal ResourceSet CreateResourceSet(Stream store, Assembly assembly) // resMgrHeaderVersion is older than this ResMgr version. // We should add in backwards compatibility support here. - throw new NotSupportedException(SR.Format(SR.NotSupported_ObsoleteResourcesFile, _mediator.MainAssembly.GetSimpleName())); + throw new NotSupportedException(SR.Format(SR.NotSupported_ObsoleteResourcesFile, _mediator.MainAssemblySimpleName)); } store.Position = startPos; @@ -306,7 +304,7 @@ internal ResourceSet CreateResourceSet(Stream store, Assembly assembly) } } - private Stream GetManifestResourceStream(RuntimeAssembly satellite, string fileName) + private Stream GetManifestResourceStream(Assembly satellite, string fileName) { Debug.Assert(satellite != null, "satellite shouldn't be null; check caller"); Debug.Assert(fileName != null, "fileName shouldn't be null; check caller"); @@ -323,8 +321,8 @@ private Stream GetManifestResourceStream(RuntimeAssembly satellite, string fileN // Looks up a .resources file in the assembly manifest using // case-insensitive lookup rules. Yes, this is slow. The metadata // dev lead refuses to make all assembly manifest resource lookups case-insensitive, - // even optionally case-insensitive. - private Stream CaseInsensitiveManifestResourceStreamLookup(RuntimeAssembly satellite, string name) + // even optionally case-insensitive. + private Stream CaseInsensitiveManifestResourceStreamLookup(Assembly satellite, string name) { Debug.Assert(satellite != null, "satellite shouldn't be null; check caller"); Debug.Assert(name != null, "name shouldn't be null; check caller"); @@ -360,7 +358,7 @@ private Stream CaseInsensitiveManifestResourceStreamLookup(RuntimeAssembly satel return satellite.GetManifestResourceStream(canonicalName); } - private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture) + private Assembly GetSatelliteAssembly(CultureInfo lookForCulture) { if (!_mediator.LookedForSatelliteContractVersion) { @@ -368,8 +366,7 @@ private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture) _mediator.LookedForSatelliteContractVersion = true; } - RuntimeAssembly satellite = null; - string satAssemblyName = GetSatelliteAssemblyName(); + Assembly satellite = null; // Look up the satellite assembly, but don't let problems // like a partially signed satellite assembly stop us from @@ -377,7 +374,7 @@ private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture) // Yet also somehow log this error for a developer. try { - satellite = _mediator.MainAssembly.InternalGetSatelliteAssembly(satAssemblyName, lookForCulture, _mediator.SatelliteContractVersion, false); + satellite = InternalGetSatelliteAssembly(_mediator.MainAssembly, lookForCulture, _mediator.SatelliteContractVersion); } // Jun 08: for cases other than ACCESS_DENIED, we'll assert instead of throw to give release builds more opportunity to fallback. @@ -390,14 +387,14 @@ private RuntimeAssembly GetSatelliteAssembly(CultureInfo lookForCulture) int hr = fle._HResult; if (hr != Win32Marshal.MakeHRFromErrorCode(Interop.Errors.ERROR_ACCESS_DENIED)) { - Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle); + Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetName().Version.ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssemblySimpleName + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle); } } // Don't throw for zero-length satellite assemblies, for compat with v1 catch (BadImageFormatException bife) { - Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetVersion().ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetSimpleName() + Environment.NewLine + "Exception: " + bife); + Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetName().Version.ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssemblySimpleName + Environment.NewLine + "Exception: " + bife); } return satellite; @@ -436,24 +433,15 @@ private bool CanUseDefaultResourceClasses(string readerTypeName, string resSetTy return true; } - private string GetSatelliteAssemblyName() - { - string satAssemblyName = _mediator.MainAssembly.GetSimpleName(); - satAssemblyName += ".resources"; - return satAssemblyName; - } - private void HandleSatelliteMissing() { - string satAssemName = _mediator.MainAssembly.GetSimpleName() + ".resources.dll"; + string satAssemName = _mediator.MainAssemblySimpleName + ".resources.dll"; if (_mediator.SatelliteContractVersion != null) { satAssemName += ", Version=" + _mediator.SatelliteContractVersion.ToString(); } - AssemblyName an = new AssemblyName(); - an.SetPublicKey(_mediator.MainAssembly.GetPublicKey()); - byte[] token = an.GetPublicKeyToken(); + byte[] token = _mediator.MainAssembly.GetName().GetPublicKeyToken(); int iLen = token.Length; StringBuilder publicKeyTok = new StringBuilder(iLen * 2); @@ -489,11 +477,45 @@ private void HandleResourceStreamMissing(string fileName) if (_mediator.LocationInfo != null && _mediator.LocationInfo.Namespace != null) resName = _mediator.LocationInfo.Namespace + Type.Delimiter; resName += fileName; - throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssembly.GetSimpleName())); + throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssemblySimpleName)); + } + + // Internal version of GetSatelliteAssembly that avoids throwing FileLoadException + private Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, + CultureInfo culture, + Version version) + { + if (mainAssembly is RuntimeAssembly runtimeMainAssembly) + { + return runtimeMainAssembly.InternalGetSatelliteAssembly(culture, version, throwOnFileNotFound: false); + } + + try + { + return mainAssembly.GetSatelliteAssembly(culture, version); + } + catch (FileLoadException) + { + return null; + } } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation); + + internal static bool GetNeutralResourcesLanguageAttribute(Assembly assemblyHandle, ref string cultureName, out short fallbackLocation) + { + if (assemblyHandle is RuntimeAssembly runtimeAssemblyHandle) + { + return GetNeutralResourcesLanguageAttribute(runtimeAssemblyHandle.GetNativeHandle(), + JitHelpers.GetStringHandleOnStack(ref cultureName), + out fallbackLocation); + } + + // Not currently supported on custom Assembly types or AssemblyBuilder + fallbackLocation = 0; + return false; + } } } diff --git a/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs b/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs index 69d8e5fc505a..726ab9df16ee 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs @@ -225,9 +225,6 @@ public ResourceManager(string baseName, Assembly assembly) if (null == assembly) throw new ArgumentNullException(nameof(assembly)); - if (!(assembly is RuntimeAssembly)) - throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); - MainAssembly = assembly; BaseNameField = baseName; @@ -243,9 +240,6 @@ public ResourceManager(string baseName, Assembly assembly, Type usingResourceSet if (null == assembly) throw new ArgumentNullException(nameof(assembly)); - if (!(assembly is RuntimeAssembly)) - throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); - MainAssembly = assembly; BaseNameField = baseName; @@ -664,7 +658,7 @@ internal static WindowsRuntimeResourceManagerBase GetWinRTResourceManager() // // b) For any other non-FX assembly, we will use the modern resource manager with the premise that app package // contains the PRI resources. - private bool ShouldUseSatelliteAssemblyResourceLookupUnderAppX(RuntimeAssembly resourcesAssembly) + private bool ShouldUseSatelliteAssemblyResourceLookupUnderAppX(Assembly resourcesAssembly) { bool fUseSatelliteAssemblyResourceLookupUnderAppX = typeof(object).Assembly == resourcesAssembly; @@ -706,11 +700,9 @@ private void SetAppXConfiguration() bool bUsingSatelliteAssembliesUnderAppX = false; - RuntimeAssembly resourcesAssembly = (RuntimeAssembly)MainAssembly; - - if (resourcesAssembly != null) + if (MainAssembly != null) { - if (resourcesAssembly != typeof(object).Assembly) // We are not loading resources for mscorlib + if (MainAssembly != typeof(object).Assembly) // We are not loading resources for mscorlib { if (ApplicationModel.IsUap) { @@ -731,7 +723,7 @@ private void SetAppXConfiguration() if (!bUsingSatelliteAssembliesUnderAppX) { - _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(resourcesAssembly); + _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(MainAssembly); if (_bUsingModernResourceManagement) { @@ -749,7 +741,7 @@ private void SetAppXConfiguration() try { - _PRIonAppXInitialized = _WinRTResourceManager.Initialize(resourcesAssembly.Location, reswFilename, out _PRIExceptionInfo); + _PRIonAppXInitialized = _WinRTResourceManager.Initialize(MainAssembly.Location, reswFilename, out _PRIExceptionInfo); // Note that _PRIExceptionInfo might be null - this is OK. // In that case we will just throw the generic // MissingManifestResource_NoPRIresources exception. @@ -801,7 +793,7 @@ private void SetAppXConfiguration() } } } - // resourcesAssembly == null should not happen but it can. See the comment on Assembly.GetCallingAssembly. + // MainAssembly == null should not happen but it can. See the comment on Assembly.GetCallingAssembly. // However for the sake of 100% backwards compatibility on Win7 and below, we must leave // _bUsingModernResourceManagement as false. #endif // FEATURE_APPX @@ -1069,9 +1061,19 @@ internal UltimateResourceFallbackLocation FallbackLoc set { _rm._fallbackLoc = value; } } - internal RuntimeAssembly MainAssembly + internal Assembly MainAssembly + { + get { return _rm.MainAssembly; } + } + + internal string MainAssemblySimpleName { - get { return (RuntimeAssembly)_rm.MainAssembly; } + get + { + if (_rm.MainAssembly is RuntimeAssembly runtimeAssembly) + return runtimeAssembly.GetSimpleName(); + return _rm.MainAssembly.GetName().Name; + } } // this is weird because we have BaseNameField accessor above, but we're sticking From 8d2b63eb3fe07c974836eb2e8bb1ca800b7b382e Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 14 Jan 2019 17:10:04 +0100 Subject: [PATCH 2/6] Fix exception name. --- .../src/System/Resources/ManifestBasedResourceGroveler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs index 8aee3417c2e6..b47f645d927d 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -480,7 +480,7 @@ private void HandleResourceStreamMissing(string fileName) throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssemblySimpleName)); } - // Internal version of GetSatelliteAssembly that avoids throwing FileLoadException + // Internal version of GetSatelliteAssembly that avoids throwing FileNotFoundException private Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, CultureInfo culture, Version version) @@ -494,7 +494,7 @@ private Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, { return mainAssembly.GetSatelliteAssembly(culture, version); } - catch (FileLoadException) + catch (FileNotFoundException) { return null; } From a5a1fc246dc5d937367ca738f84f768f8379899a Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 15 Jan 2019 00:11:58 +0100 Subject: [PATCH 3/6] Fix method qualifiers. --- .../System/Resources/ManifestBasedResourceGroveler.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs index b47f645d927d..793ac42b473d 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -481,9 +481,9 @@ private void HandleResourceStreamMissing(string fileName) } // Internal version of GetSatelliteAssembly that avoids throwing FileNotFoundException - private Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, - CultureInfo culture, - Version version) + private static Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, + CultureInfo culture, + Version version) { if (mainAssembly is RuntimeAssembly runtimeMainAssembly) { @@ -502,9 +502,9 @@ private Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] - internal static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation); + private static extern bool GetNeutralResourcesLanguageAttribute(RuntimeAssembly assemblyHandle, StringHandleOnStack cultureName, out short fallbackLocation); - internal static bool GetNeutralResourcesLanguageAttribute(Assembly assemblyHandle, ref string cultureName, out short fallbackLocation) + private static bool GetNeutralResourcesLanguageAttribute(Assembly assemblyHandle, ref string cultureName, out short fallbackLocation) { if (assemblyHandle is RuntimeAssembly runtimeAssemblyHandle) { From 4f6f30aea5026b4636b5079a2f3d6aa464c6ccf7 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Tue, 15 Jan 2019 11:40:27 +0100 Subject: [PATCH 4/6] Add generic implementation of GetNeutralResourcesLanguageAttribute. --- .../System/Resources/ManifestBasedResourceGroveler.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs index 793ac42b473d..91e36163593a 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -513,7 +513,14 @@ private static bool GetNeutralResourcesLanguageAttribute(Assembly assemblyHandle out fallbackLocation); } - // Not currently supported on custom Assembly types or AssemblyBuilder + var nrlAttribute = assemblyHandle.GetCustomAttribute(); + if (nrlAttribute != null) + { + fallbackLocation = (short)nrlAttribute.Location; + cultureName = nrlAttribute.CultureName; + return true; + } + fallbackLocation = 0; return false; } From a343b920d239f3da7732ddb13e37ecdeec553697 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Fri, 25 Jan 2019 18:17:10 +0100 Subject: [PATCH 5/6] PR feedback (removed SimpleName optimization, added back restriction to runtime types/assemblies). --- .../shared/System/Reflection/Assembly.cs | 4 ++ .../ManifestBasedResourceGroveler.cs | 44 ++++--------------- .../src/System/Resources/ResourceManager.cs | 18 +++----- 3 files changed, 18 insertions(+), 48 deletions(-) diff --git a/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs b/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs index bc8b4cdaf966..b57af5865715 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs @@ -208,5 +208,9 @@ public static Assembly LoadWithPartialName(string partialName) public static Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); } public virtual SecurityRuleSet SecurityRuleSet => SecurityRuleSet.None; + + // Exists to faciliate code sharing between CoreCLR and CoreRT. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal bool IsRuntimeImplemented() => this is RuntimeAssembly; } } diff --git a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs index 91e36163593a..26a601a34ab1 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ManifestBasedResourceGroveler.cs @@ -226,7 +226,7 @@ internal ResourceSet CreateResourceSet(Stream store, Assembly assembly) // resMgrHeaderVersion is older than this ResMgr version. // We should add in backwards compatibility support here. - throw new NotSupportedException(SR.Format(SR.NotSupported_ObsoleteResourcesFile, _mediator.MainAssemblySimpleName)); + throw new NotSupportedException(SR.Format(SR.NotSupported_ObsoleteResourcesFile, _mediator.MainAssembly.GetName().Name)); } store.Position = startPos; @@ -387,14 +387,14 @@ private Assembly GetSatelliteAssembly(CultureInfo lookForCulture) int hr = fle._HResult; if (hr != Win32Marshal.MakeHRFromErrorCode(Interop.Errors.ERROR_ACCESS_DENIED)) { - Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetName().Version.ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssemblySimpleName + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle); + Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetName().Version.ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetName().Name + " with error code 0x" + hr.ToString("X", CultureInfo.InvariantCulture) + Environment.NewLine + "Exception: " + fle); } } // Don't throw for zero-length satellite assemblies, for compat with v1 catch (BadImageFormatException bife) { - Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetName().Version.ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssemblySimpleName + Environment.NewLine + "Exception: " + bife); + Debug.Fail("[This assert catches satellite assembly build/deployment problems - report this message to your build lab & loc engineer]" + Environment.NewLine + "GetSatelliteAssembly failed for culture " + lookForCulture.Name + " and version " + (_mediator.SatelliteContractVersion == null ? _mediator.MainAssembly.GetName().Version.ToString() : _mediator.SatelliteContractVersion.ToString()) + " of assembly " + _mediator.MainAssembly.GetName().Name + Environment.NewLine + "Exception: " + bife); } return satellite; @@ -435,7 +435,7 @@ private bool CanUseDefaultResourceClasses(string readerTypeName, string resSetTy private void HandleSatelliteMissing() { - string satAssemName = _mediator.MainAssemblySimpleName + ".resources.dll"; + string satAssemName = _mediator.MainAssembly.GetName().Name + ".resources.dll"; if (_mediator.SatelliteContractVersion != null) { satAssemName += ", Version=" + _mediator.SatelliteContractVersion.ToString(); @@ -477,7 +477,7 @@ private void HandleResourceStreamMissing(string fileName) if (_mediator.LocationInfo != null && _mediator.LocationInfo.Namespace != null) resName = _mediator.LocationInfo.Namespace + Type.Delimiter; resName += fileName; - throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssemblySimpleName)); + throw new MissingManifestResourceException(SR.Format(SR.MissingManifestResource_NoNeutralAsm, resName, _mediator.MainAssembly.GetName().Name)); } // Internal version of GetSatelliteAssembly that avoids throwing FileNotFoundException @@ -485,19 +485,7 @@ private static Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, CultureInfo culture, Version version) { - if (mainAssembly is RuntimeAssembly runtimeMainAssembly) - { - return runtimeMainAssembly.InternalGetSatelliteAssembly(culture, version, throwOnFileNotFound: false); - } - - try - { - return mainAssembly.GetSatelliteAssembly(culture, version); - } - catch (FileNotFoundException) - { - return null; - } + return ((RuntimeAssembly)mainAssembly).InternalGetSatelliteAssembly(culture, version, throwOnFileNotFound: false); } [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] @@ -506,23 +494,9 @@ private static Assembly InternalGetSatelliteAssembly(Assembly mainAssembly, private static bool GetNeutralResourcesLanguageAttribute(Assembly assemblyHandle, ref string cultureName, out short fallbackLocation) { - if (assemblyHandle is RuntimeAssembly runtimeAssemblyHandle) - { - return GetNeutralResourcesLanguageAttribute(runtimeAssemblyHandle.GetNativeHandle(), - JitHelpers.GetStringHandleOnStack(ref cultureName), - out fallbackLocation); - } - - var nrlAttribute = assemblyHandle.GetCustomAttribute(); - if (nrlAttribute != null) - { - fallbackLocation = (short)nrlAttribute.Location; - cultureName = nrlAttribute.CultureName; - return true; - } - - fallbackLocation = 0; - return false; + return GetNeutralResourcesLanguageAttribute(((RuntimeAssembly)assemblyHandle).GetNativeHandle(), + JitHelpers.GetStringHandleOnStack(ref cultureName), + out fallbackLocation); } } } diff --git a/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs b/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs index 726ab9df16ee..aefe94eb628d 100644 --- a/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs +++ b/src/System.Private.CoreLib/src/System/Resources/ResourceManager.cs @@ -221,9 +221,10 @@ public ResourceManager(string baseName, Assembly assembly) { if (null == baseName) throw new ArgumentNullException(nameof(baseName)); - if (null == assembly) throw new ArgumentNullException(nameof(assembly)); + if (!assembly.IsRuntimeImplemented()) + throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); MainAssembly = assembly; BaseNameField = baseName; @@ -239,6 +240,8 @@ public ResourceManager(string baseName, Assembly assembly, Type usingResourceSet throw new ArgumentNullException(nameof(baseName)); if (null == assembly) throw new ArgumentNullException(nameof(assembly)); + if (!assembly.IsRuntimeImplemented()) + throw new ArgumentException(SR.Argument_MustBeRuntimeAssembly); MainAssembly = assembly; BaseNameField = baseName; @@ -254,8 +257,7 @@ public ResourceManager(Type resourceSource) { if (null == resourceSource) throw new ArgumentNullException(nameof(resourceSource)); - - if (!(resourceSource is RuntimeType)) + if (!resourceSource.IsRuntimeImplemented()) throw new ArgumentException(SR.Argument_MustBeRuntimeType); _locationInfo = resourceSource; @@ -1066,16 +1068,6 @@ internal Assembly MainAssembly get { return _rm.MainAssembly; } } - internal string MainAssemblySimpleName - { - get - { - if (_rm.MainAssembly is RuntimeAssembly runtimeAssembly) - return runtimeAssembly.GetSimpleName(); - return _rm.MainAssembly.GetName().Name; - } - } - // this is weird because we have BaseNameField accessor above, but we're sticking // with it for compat. internal string BaseName From dba3e802248a57a1c86affcdf2fdf8c7033f11e7 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Sat, 26 Jan 2019 04:43:58 +0100 Subject: [PATCH 6/6] Move function accidentally added to shared partition. --- .../shared/System/Reflection/Assembly.cs | 4 ---- .../src/System/Reflection/Assembly.CoreCLR.cs | 4 ++++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs b/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs index b57af5865715..bc8b4cdaf966 100644 --- a/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs +++ b/src/System.Private.CoreLib/shared/System/Reflection/Assembly.cs @@ -208,9 +208,5 @@ public static Assembly LoadWithPartialName(string partialName) public static Assembly ReflectionOnlyLoadFrom(string assemblyFile) { throw new PlatformNotSupportedException(SR.PlatformNotSupported_ReflectionOnly); } public virtual SecurityRuleSet SecurityRuleSet => SecurityRuleSet.None; - - // Exists to faciliate code sharing between CoreCLR and CoreRT. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal bool IsRuntimeImplemented() => this is RuntimeAssembly; } } diff --git a/src/System.Private.CoreLib/src/System/Reflection/Assembly.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Reflection/Assembly.CoreCLR.cs index d6f50cde4297..68818902b786 100644 --- a/src/System.Private.CoreLib/src/System/Reflection/Assembly.CoreCLR.cs +++ b/src/System.Private.CoreLib/src/System/Reflection/Assembly.CoreCLR.cs @@ -253,5 +253,9 @@ public static Assembly GetEntryAssembly() GetEntryAssembly(JitHelpers.GetObjectHandleOnStack(ref entryAssembly)); return entryAssembly; } + + // Exists to faciliate code sharing between CoreCLR and CoreRT. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal bool IsRuntimeImplemented() => this is RuntimeAssembly; } }