Beispiel #1
0
        // Returns the CultureInfo representing the first language in the list that we can construct a CultureInfo for or null if
        // no such culture exists.
        private static unsafe CultureInfo GetBestFitCultureFromLanguageList(List <string> languages)
        {
            char *localeNameBuffer = stackalloc char[Interop.Kernel32.LOCALE_NAME_MAX_LENGTH]; // LOCALE_NAME_MAX_LENGTH includes null terminator

            for (int i = 0; i < languages.Count; i++)
            {
                if (WindowsRuntimeResourceManagerBase.IsValidCulture(languages[i]))
                {
                    return(new CultureInfo(languages[i]));
                }

                int result = Interop.Kernel32.ResolveLocaleName(languages[i], localeNameBuffer, Interop.Kernel32.LOCALE_NAME_MAX_LENGTH);
                if (result != 0)
                {
                    string localeName = new string(localeNameBuffer, 0, result - 1); // result length includes null terminator

                    if (WindowsRuntimeResourceManagerBase.IsValidCulture(localeName))
                    {
                        return(new CultureInfo(localeName));
                    }
                }
            }

            return(null);
        }
        // Returns the CultureInfo representing the first language in the list that we can construct a CultureInfo for or null if
        // no such culture exists.
        private static CultureInfo GetBestFitCultureFromLanguageList(List <string> languages)
        {
            StringBuilder localeNameBuffer = new StringBuilder(Interop.Kernel32.LOCALE_NAME_MAX_LENGTH);

            for (int i = 0; i < languages.Count; i++)
            {
                if (WindowsRuntimeResourceManagerBase.IsValidCulture(languages[i]))
                {
                    return(new CultureInfo(languages[i]));
                }

                if (Interop.Kernel32.ResolveLocaleName(languages[i], localeNameBuffer, localeNameBuffer.MaxCapacity) != 0)
                {
                    string localeName = localeNameBuffer.ToString();

                    if (WindowsRuntimeResourceManagerBase.IsValidCulture(localeName))
                    {
                        return(new CultureInfo(localeName));
                    }
                }
            }

            return(null);
        }
Beispiel #3
0
        // Only call SetAppXConfiguration from ResourceManager constructors, and nowhere else.
        // Throws MissingManifestResourceException and WinRT HResults

        private void SetAppXConfiguration()
        {
            Contract.Assert(_bUsingModernResourceManagement == false); // Only this function writes to this member
#if FEATURE_APPX
            Contract.Assert(_WinRTResourceManager == null); // Only this function writes to this member
            Contract.Assert(_PRIonAppXInitialized == false); // Only this function writes to this member
            Contract.Assert(_PRIExceptionInfo == null); // Only this function writes to this member

            bool bUsingSatelliteAssembliesUnderAppX = false;

            RuntimeAssembly resourcesAssembly = (RuntimeAssembly)MainAssembly;

            if (resourcesAssembly == null)
                resourcesAssembly = m_callingAssembly;

            if (resourcesAssembly != null)
            {
                if (resourcesAssembly != typeof(Object).Assembly) // We are not loading resources for mscorlib
                {
                    // Cannot load the WindowsRuntimeResourceManager when in a compilation process, since it
                    // lives in System.Runtime.WindowsRuntime and only mscorlib may be loaded for execution.
                    if (AppDomain.IsAppXModel() && !AppDomain.IsAppXNGen)
                    {
                        s_IsAppXModel = true;

                        // If we have the type information from the ResourceManager(Type) constructor, we use it. Otherwise, we use BaseNameField.
                        String reswFilename = _locationInfo == null ? BaseNameField : _locationInfo.FullName;

                        // The only way this can happen is if a class inherited from ResourceManager and
                        // did not set the BaseNameField before calling the protected ResourceManager() constructor.
                        // For other constructors, we would already have thrown an ArgumentNullException by now.
                        // Throwing an ArgumentNullException now is not the right thing to do because technically
                        // ResourceManager() takes no arguments, and because it is not documented as throwing
                        // any exceptions. Instead, let's go through the rest of the initialization with this set to
                        // an empty string. We may in fact fail earlier for another reason, but otherwise we will
                        // throw a MissingManifestResourceException when GetString is called indicating that a
                        // resW filename called "" could not be found.
                        if (reswFilename == null)
                            reswFilename = String.Empty;

                        WindowsRuntimeResourceManagerBase WRRM = null;
                        bool bWRRM_Initialized = false;
                        
                        if (AppDomain.IsAppXDesignMode())
                        {
                            WRRM = GetWinRTResourceManager();
                            try {
                                PRIExceptionInfo exceptionInfo; // If the exception info is filled in, we will ignore it.
                                bWRRM_Initialized = WRRM.Initialize(resourcesAssembly.Location, reswFilename, out exceptionInfo);
                                bUsingSatelliteAssembliesUnderAppX = !bWRRM_Initialized;
                            }
                            catch(Exception e)
                            {
                                bUsingSatelliteAssembliesUnderAppX = true;
                                if (e.IsTransient)
                                    throw;
                            }
                        }

                        if (!bUsingSatelliteAssembliesUnderAppX)
                        {
                            // See AssemblyNative::IsFrameworkAssembly for details on which kinds of assemblies are considered Framework assemblies.
                            // The Modern Resource Manager is not used for such assemblies - they continue to use satellite assemblies (i.e. .resources.dll files).
                            _bUsingModernResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(resourcesAssembly); 

                            if (_bUsingModernResourceManagement)
                            {
                                // Only now are we certain that we need the PRI file.

                                // Note that if IsAppXDesignMode is false, we haven't checked if the PRI file exists.
                                // This is by design. We will find out in the call to WindowsRuntimeResourceManager.Initialize below.

                                // At this point it is important NOT to set _bUsingModernResourceManagement to false
                                // if the PRI file does not exist because we are now certain we need to load PRI
                                // resources. We want to fail by throwing a MissingManifestResourceException
                                // if WindowsRuntimeResourceManager.Initialize fails to locate the PRI file. We do not
                                // want to fall back to using satellite assemblies anymore. Note that we would not throw
                                // the MissingManifestResourceException from this function, but from GetString. See the
                                // comment below on the reason for this.

                                if (WRRM != null && bWRRM_Initialized)
                                {
                                    // Reuse the one successfully created earlier
                                    _WinRTResourceManager = WRRM;
                                    _PRIonAppXInitialized = true;
                                }
                                else 
                                {
                                    _WinRTResourceManager = GetWinRTResourceManager();
                                    
                                    try {
                                        _PRIonAppXInitialized = _WinRTResourceManager.Initialize(resourcesAssembly.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.
                                        // See the implementation of GetString for more details.
                                    }
                                    // We would like to be able to throw a MissingManifestResourceException here if PRI resources
                                    // could not be loaded for a recognized reason. However, the ResourceManager constructors
                                    // that call SetAppXConfiguration are not documented as throwing MissingManifestResourceException,
                                    // and since they are part of the portable profile, we cannot start throwing a new exception type
                                    // as that would break existing portable libraries. Hence we must save the exception information
                                    // now and throw the exception on the first call to GetString.
                                    catch(FileNotFoundException)
                                    {
                                        // We will throw MissingManifestResource_NoPRIresources from GetString
                                        // when we see that _PRIonAppXInitialized is false.
                                    }
                                    catch(Exception e)
                                    {
                                        // ERROR_MRM_MAP_NOT_FOUND can be thrown by the call to ResourceManager.get_AllResourceMaps
                                        // in WindowsRuntimeResourceManager.Initialize.
                                        // In this case _PRIExceptionInfo is now null and we will just throw the generic
                                        // MissingManifestResource_NoPRIresources exception.
                                        // See the implementation of GetString for more details.
                                        if (e.HResult != __HResults.ERROR_MRM_MAP_NOT_FOUND)
                                            throw; // Unexpected exception code. Bubble it up to the caller.
                                    }
                                    // Allow all other exception types to bubble up to the caller.

                                    // Yes, this causes us to potentially throw exception types that are not documented.

                                    // Ultimately the tradeoff is the following:
                                    // -We could ignore unknown exceptions or rethrow them as inner exceptions
                                    // of exceptions that the ResourceManager class is already documented as throwing.
                                    // This would allow existing portable libraries to gracefully recover if they don't care
                                    // too much about the ResourceManager object they are using. However it could
                                    // mask potentially fatal errors that we are not aware of, such as a disk drive failing.


                                    // The alternative, which we chose, is to throw unknown exceptions. This may tear
                                    // down the process if the portable library and app don't expect this exception type.
                                    // On the other hand, this won't mask potentially fatal errors we don't know about.
                                }
                            }
                        }
                    }
                }
            }
            // resourcesAssembly == 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            
        }
Beispiel #4
0
        internal static bool SetCultureInfoForUserPreferredLanguageInAppX(CultureInfo ci)
        {
            // If running within a compilation process (mscorsvw.exe, for example), it is illegal to
            // load any non-mscorlib assembly for execution. Since WindowsRuntimeResourceManager lives
            // in System.Runtime.WindowsRuntime, caller will need to fall back to default Win32 value,
            // which should be fine because we should only ever need to access FX resources during NGEN.
            // FX resources are always loaded from satellite assemblies - even in AppX processes (see the
            // comments in code:System.Resources.ResourceManager.SetAppXConfiguration for more details).
            if (AppDomain.IsAppXNGen)
            {
                return false;
            }

            if (s_WindowsRuntimeResourceManager == null)
            {
                s_WindowsRuntimeResourceManager = ResourceManager.GetWinRTResourceManager();
            }

            return s_WindowsRuntimeResourceManager.SetGlobalResourceContextDefaultCulture(ci);
        }
Beispiel #5
0
        internal static CultureInfo GetCultureInfoForUserPreferredLanguageInAppX()
        {
            // If a call to GetCultureInfoForUserPreferredLanguageInAppX() generated a recursive
            // call to itself, return null, since we don't want to stack overflow.  For example, 
            // this can happen if some code in this method ends up calling CultureInfo.CurrentCulture
            // (which is common on check'd build because of BCLDebug logging which calls Int32.ToString()).  
            // In this case, returning null will mean CultureInfo.CurrentCulture gets the default Win32 
            // value, which should be fine. 
            if(ts_IsDoingAppXCultureInfoLookup)
            {
                return null;
            }

            // If running within a compilation process (mscorsvw.exe, for example), it is illegal to
            // load any non-mscorlib assembly for execution. Since WindowsRuntimeResourceManager lives
            // in System.Runtime.WindowsRuntime, caller will need to fall back to default Win32 value,
            // which should be fine because we should only ever need to access FX resources during NGEN.
            // FX resources are always loaded from satellite assemblies - even in AppX processes (see the
            // comments in code:System.Resources.ResourceManager.SetAppXConfiguration for more details).
            if (AppDomain.IsAppXNGen)
            {
                return null;
            }

            CultureInfo toReturn = null;

            try 
            {
                ts_IsDoingAppXCultureInfoLookup = true;

                if(s_WindowsRuntimeResourceManager == null)
                {
                    s_WindowsRuntimeResourceManager = ResourceManager.GetWinRTResourceManager();
                }

                toReturn = s_WindowsRuntimeResourceManager.GlobalResourceContextBestFitCultureInfo;
            } 
            finally 
            {
               ts_IsDoingAppXCultureInfoLookup = false;
            }
 
            return toReturn;
        }
        // Only call SetAppXConfiguration from ResourceManager constructors, and nowhere else.
        // Throws MissingManifestResourceException and WinRT HResults
        private void SetAppXConfiguration()
        {
            Debug.Assert(UseUapResourceManagement == false); // Only this function writes to this member
            Debug.Assert(_WinRTResourceManager == null);     // Only this function writes to this member
            Debug.Assert(_PRIonAppXInitialized == false);    // Only this function writes to this member
            Debug.Assert(_PRIExceptionInfo == null);         // Only this function writes to this member

            bool bUsingSatelliteAssembliesUnderAppX = false;

            if (MainAssembly != null)
            {
                if (MainAssembly != typeof(object).Assembly) // We are not loading resources for System.Private.CoreLib
                {
#if ENABLE_WINRT
                    WinRTInteropCallbacks callbacks = WinRTInterop.UnsafeCallbacks;
                    if (callbacks != null && callbacks.IsAppxModel())
#else
                    if (ApplicationModel.IsUap)
#endif
                    {
                        // If we have the type information from the ResourceManager(Type) constructor, we use it. Otherwise, we use BaseNameField.
                        string reswFilename = _locationInfo == null ? BaseNameField : _locationInfo.FullName;

                        // The only way this can happen is if a class inherited from ResourceManager and
                        // did not set the BaseNameField before calling the protected ResourceManager() constructor.
                        // For other constructors, we would already have thrown an ArgumentNullException by now.
                        // Throwing an ArgumentNullException now is not the right thing to do because technically
                        // ResourceManager() takes no arguments, and because it is not documented as throwing
                        // any exceptions. Instead, let's go through the rest of the initialization with this set to
                        // an empty string. We may in fact fail earlier for another reason, but otherwise we will
                        // throw a MissingManifestResourceException when GetString is called indicating that a
                        // resW filename called "" could not be found.
                        if (reswFilename == null)
                        {
                            reswFilename = string.Empty;
                        }

                        if (!bUsingSatelliteAssembliesUnderAppX)
                        {
                            UseUapResourceManagement = !ShouldUseSatelliteAssemblyResourceLookupUnderAppX(MainAssembly);

                            if (UseUapResourceManagement)
                            {
                                // Only now are we certain that we need the PRI file.

                                // At this point it is important NOT to set UseUapResourceManagement to false
                                // if the PRI file does not exist because we are now certain we need to load PRI
                                // resources. We want to fail by throwing a MissingManifestResourceException
                                // if WindowsRuntimeResourceManager.Initialize fails to locate the PRI file. We do not
                                // want to fall back to using satellite assemblies anymore. Note that we would not throw
                                // the MissingManifestResourceException from this function, but from GetString. See the
                                // comment below on the reason for this.

                                _WinRTResourceManager = GetWinRTResourceManager();

                                try
                                {
                                    _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.
                                    // See the implementation of GetString for more details.
                                }
                                // We would like to be able to throw a MissingManifestResourceException here if PRI resources
                                // could not be loaded for a recognized reason. However, the ResourceManager constructors
                                // that call SetAppXConfiguration are not documented as throwing MissingManifestResourceException,
                                // and since they are part of the portable profile, we cannot start throwing a new exception type
                                // as that would break existing portable libraries. Hence we must save the exception information
                                // now and throw the exception on the first call to GetString.
                                catch (FileNotFoundException)
                                {
                                    // We will throw MissingManifestResource_NoPRIresources from GetString
                                    // when we see that _PRIonAppXInitialized is false.
                                }
                                catch (Exception e)
                                {
                                    // ERROR_MRM_MAP_NOT_FOUND can be thrown by the call to ResourceManager.get_AllResourceMaps
                                    // in WindowsRuntimeResourceManager.Initialize.
                                    // In this case _PRIExceptionInfo is now null and we will just throw the generic
                                    // MissingManifestResource_NoPRIresources exception.
                                    // See the implementation of GetString for more details.
                                    if (e.HResult != HResults.ERROR_MRM_MAP_NOT_FOUND)
                                    {
                                        throw; // Unexpected exception code. Bubble it up to the caller.
                                    }
                                }

                                if (!_PRIonAppXInitialized)
                                {
                                    UseUapResourceManagement = false;
                                }
                                // Allow all other exception types to bubble up to the caller.

                                // Yes, this causes us to potentially throw exception types that are not documented.

                                // Ultimately the tradeoff is the following:
                                // -We could ignore unknown exceptions or rethrow them as inner exceptions
                                // of exceptions that the ResourceManager class is already documented as throwing.
                                // This would allow existing portable libraries to gracefully recover if they don't care
                                // too much about the ResourceManager object they are using. However it could
                                // mask potentially fatal errors that we are not aware of, such as a disk drive failing.


                                // The alternative, which we chose, is to throw unknown exceptions. This may tear
                                // down the process if the portable library and app don't expect this exception type.
                                // On the other hand, this won't mask potentially fatal errors we don't know about.
                            }
                        }
                    }
                }
            }
            // 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.
        }