“Device Not Functioning” Exception on Invalid PrimaryLanguageOverride Value in Windows Store Apps

Oh, what a title for a post. The correct title is “‘A device attached to the system is not functioning. (Exception from HRESULT: 0x8007001F)’ Exception Occurs When Showing A TextBox and ApplicationLanguages.PrimaryLanguageOverride Is Set To An Invalid Value in Windows Store Apps on Windows 8.1“.

Symptom

Building the Factory Commander, I was using ApplicationLanguages.PrimaryLanguageOverride to set the culture-correct date and number formatting. This is how the implementation in App.OnLaunched looked like:

ApplicationLanguages.PrimaryLanguageOverride 
  = new GeographicRegion().CodeTwoLetter;

Unfortunately, I can’t recall where I found this approach.

The development of Factory Commander was started on Windows 8, where this approach worked well. But after upgrading the development machine to Windows 8.1, the Commander crashed whenever I tried to rename, copy, or move a single item.

I figured out that, whenever the apps wants to show a TextBox, an exception with the description “A device attached to the system is not functioning. (Exception from HRESULT: 0x8007001F)” was thrown. The exception did not contain any further information. Well, what kind of device is used by a TextBox that is not used by other common controls of a Windows Store app?

A newly created Windows Store app on the same machine, which did contain a TextBox only, did not threw this exception. Was the Commander not compatible with Windows 8.1? I tested it on a machine having Windows 8.1 initially installed, so no upgrade was made: no problem! Did the upgrade corrupted the development machine?

Then I installed the Commander on a Windows RT device that was upgraded to Windows 8.1: no problem! Was it an issue with upgrading the x64 version of Windows 8? That seems to be the fact, because on another x64 machine that was upgraded to Windows 8.1, the same problem occurs. So I installed Windows 8 x64 on a new virtual machine, upgraded it to Windows 8.1: no problem.

The Reason

As you might assume from the description above, it took me some time to figure out what the cause was. The exception thrown was not really helpful – in other words: absolutely misleading – and the fact that the implementation worked fine on Windows 8, but partially did not on Windows 8.1, wasn’t helpful too. At least the “good” old step-by-step comparison approach made it.

Looking at the docs, ApplicationLanguages.PrimaryLanguageOverride expects a BCP-47 language tag. Valid values are for example “en”, “en-US”, “de”, “de-DE”, and so forth. The Commander set the value to GeographicRegion.CodeTwoLetter, which “… returns the two-letter ISO 3166-1 alpha-2 code for this region“.

If you are lucky, the region’s ISO code will match to the (or at least one) BCP-47 language code. In case you have the region set to “United States” (search for “region and language”), you do not have luck. The return value of GeographicRegion.CodeTwoLetter is “US”, which does not seem to be a valid BCP-47 code.

The Solution

I completely removed the setting of ApplicationLanguages.PrimaryLanguageOverride. The docs mention that “the … setting is persisted between sessions“. Means, the app needs to be uninstalled to have the change take effect.

To format the date and number values according to the user’s regional settings, I am using the CultureInfo of the user’s first configured language now. I was not able to figure out how to get the date and time formatting settings from the system.

// Get all installed languages
IReadOnlyList<string> languages 
  = Windows.System.UserProfile.GlobalizationPreferences.Languages;

// In case we have at least one, set the culture info from it.
// The result will be used later on as parameter 
// of String.Format calls.
CultureInfo = languages.Count > 0 
  ? new CultureInfo(languages[0])
    : CultureInfo.DefaultThreadCurrentUICulture;

I think there should be one language defined at minimum, but who knows what might happen.

Advertisement Side Effects

A side effect of the change was that the Microsoft advertising services started to deliver ads. Before the change, I was wondering why the fill rate (quota number of items delivered by number of requests) was exactly zero. I.e. no ad was delivered at all.

After the change, ads were retrieved. This means that the app’s primary language is used to request ads in the matching language. And having an invalid language set, there will be no advertisement.

Expected Behavior

Letting the user of an API set invalid values without giving any feedback is not really helpful from my point of view.

What I expect from ApplicationLanguages.PrimaryLanguageOverride is to throw an ArgumentOutOfRangeException in case I try to set an invalid value. This would have saved me a lot of time.

It throws an ArgumentException telling the value does not fall within the expected range when I try to set it to a value like “abcd”. But as long as the format of the value matches to the BCP-47 language tag structure, like “ab” or “ab-cd”, no exception is thrown by the setter.

Try It Yourself

Are you curious and want to try it yourself? This is how I was able to reproduce the behavior:

  • Use Windows 8.1
  • Create a Blank Windows Store App, name it as you like (e.g. PrimaryLanguageOverrideTest)
  • Add ApplicationLanguages.PrimaryLanguageOverride = "US"; as the first line of App.OnLaunched
  • Insert <TextBox> into the Grid of MainPage.xaml
  • Start the app in debug mode (press F5)

This will cause the app to crash with the exception described above.

To make the positive test, follow these steps:

  • Uninstall the app (search for it, right-click, choose uninstall)
  • Change ApplicationLanguages.PrimaryLanguageOverride = "US"; to ApplicationLanguages.PrimaryLanguageOverride = "en-US";
  • Start the app in debug mode (press F5)

The app should start now without any problems.

Links

ApplicationLanguages.PrimaryLanguageOverride

BCP-47 language tag

WinRT apps and Regional settings. The correct way to format dates and numbers based on the user’s regional settings?

Factory Commander Updated to Ver. 1.1.0.6

The Factory Commander was updated:

Ver. 1.1.0.6: Fixed item #324 – app crashes when clicking the rename button and then a different item while renaming an item

Ver. 1.1.0.5: Fixed item #322 – app might crash when renaming / copying / moving single item on machines with US region settings; uninstall and re-install might be required for this fix to take effect

Download the latest version from the Windows Store.

Use Publicize.exe to Create Private Accessors for Visual Studio 2012+

Preface

Starting with Visual Studio 2012, private accessors cannot be created any more by the IDE. The post Home-made Private Accessor for Visual Studio 2012+ presents an approach on how to create private accessors using the class Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.

Axel Mayer noted in the MSDN forums post How to create private accessors in VS 2012 that one can use the command line tool publicize.exe to create private accessors too.

Usage Of Publicize.exe

The usage of publicize.exe is quite simple. Open a command prompt, or a “VS2013 x86 Native Tools Command Prompt” to have the search path already set up, and run publicize.

In case you do not have the path set up correctly, the tool can be found at %Program Files (x86)%\Microsoft Visual Studio 11.0\Common7\IDE for Visual Studio 2012 or %Program Files (x86)%\Microsoft Visual Studio 12.0\Common7\IDE for VS 2013. At least, the tool is located there for the Ultimate edition of Visual Studio. I can’t tell which other editions contain it. Just have a look.

For a complete reference please refer to Using Publicize to Create a Private Accessor.

The usage in short: publicize.exe [options] input-assembly

The created assembly needs to be referenced by the test project. Of course, the source assembly – the assembly containing the classes to be tested – has to be referenced by the test project too.

publicize.exe creates classes named NameOfTheSourceClass_Accessor. In case the class to be tested is called MyClass, the accessor is named MyClass_Accessor.

publicize did work well for .NET 4.0 and .NET 4.5 assemblies in my tests. It also covered async and static methods.

Limitations

The docs mention that publicize does not support delegates or events.

From my tests I can add another limitation: publicize does not support Windows Store app assemblies (or I was not able to use it correctly). Running it against such an assembly I received these error messages (and a few more of the same type):

Cannot resolve dependency to Windows Runtime type ‘Windows.UI.Xaml.Application’. When using the ReflectionOnly APIs, dependent Windows Runtime assemblies must be resolved on demand through the ReflectionOnlyNamespaceResolve event.

Cannot resolve dependency to assembly ‘System.Runtime, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ because it has not been preloaded. When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event.

Maybe you can give a hint on how this can be resolved. If so, please add a comment below. Thanks!

Resumé

As long as I don’t need accessors for Windows Store app assemblies, the usage of publicize.exe is my preferred way to generate private accessors.

In case publicize.exe does not support the source assembly type, I will created the private accessor myself as described by Home-made Private Accessor for Visual Studio 2012+.

Links

Home-made Private Accessor for Visual Studio 2012+

How to create private accessors in VS 2012

publicize.exe documentation