Monday, 4 November 2013

We’ll make an exception, just for you! Fun with accelerometers on Windows 8.1

I've been getting repeated failures on one of my apps that uses accelerometers, and I've been guessing where the failure was.  As the cert team wouldn't send me crash reports, I ended up building a version that I had no intention of releasing, but puts up in your face stack traces.

This time, I got a result, but the findings are extremely worrying.

I have code in my app that goes like this:

Accelerometer _accelerometer;

void NewReading(object sender, AccelerometerReadingChangedArgs e)
{
  ... nothing of interest here...
}

private void Initialize()
{
    _accelerometer = Accelerometer.GetDefault();
   if (_accelerometer != null)
   {
        // the next line throws an exception!
        _accelerometer.ReadingChanged += NewReading;
   }
}

This throws an exception as follows:

The object identifier does not represent a valid object: (Exception from HRESULT 0x800710D8)
Call Stack
  at Windows.Devices.Sensors.Accelerometer.add_ReadingChanged(TypedEventHandler`2 handler)
at
System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal.NativeOrStaticEventRegistr...(Func`2 addMethod, Action`1 removeMethod, T handler)
at System.Runtime.InteropServices.WindowsRuntime.WindowRuntimeMarshal.AddEventHandler[T](Func`2 addMethod, Action`1 removeMethod, T handler)

This looks like a hardware driver problem to me, and anyone who is tested on this particular computer will fail.

The event log said it was:
BEI-AC75

Any other developers out there seeing cert failures on Windows 8.1 like this?

Friday, 1 November 2013

How to make SuspensionManager.RestoreAsync in W8.1 app throw

One of the requirements for the store is that the application shouldn't close unexpectedly. So your app catches an exception, but then what?

One of the things I find really troublesome about the modern style of development is knowing what to do after an exception is thrown. Most API's don't even mention that an exception is thrown, let alone what state you might be in afterward.

For instance, many of you may be upgrading your apps from 8 to 8.1. I did, and found a very odd exception.
SuspensionManager failed
at Common.SuspensionManager.<RestoreAsync>d__9.MoveNext()
This exception had an internal exception as follows:
System.Exception
Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))
at Windows.UI.Xaml.Controls.Frame.SetNavigationState(String navigationState)
at Common.SuspensionManager.RestoreFrameNavigationState(Frame frame)
at Common.SuspensionManager.<RestoreAsync>d__9.MoveNext()

The reason for the exception boils down to Windows.UI.Xaml.Controls.Frame.SetNavigationState being passed a serialization string that has changed format between versions of my code (for example the main window class name changed in between).

I think what actually happened was this in my specific case: I had an app that had been suspended and terminated, and then I upgraded that same app from the store. When I launched the app it failed.

This exception managed to bring my code down, and fall into the unhandled exception handler because I'd modified the internal code in my app for the logic calling SuspensionManager.RestoreAsync()


In the new vs2013 wizards, you get code like this:

if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) 
{
// Restore the saved session state only when appropriate
try
{
await SuspensionManager.RestoreAsync();
}
catch (SuspensionManagerException)
{
//Something went wrong restoring state.
//Assume there is no state and continue
}
}




Now, given that my app saw a SuspensionManagerException, how can anyone know what the state of the rootFrame is? The code in the current App.xaml.cs generated by the wizard will blindly carry on, and do this (in the SplitApp)


if (rootFrame.Content == null) 
{
// When the navigation stack isn't restored navigate to the first page,
// configuring the new page by passing required information as a navigation
// parameter
rootFrame.Navigate(typeof(ItemsPage), e.Arguments);
}



in the grid app it does a similar comparison, and creates a GroupedItemsPage.


But how can we know this is safe? Could we not have a partially restored navigation stack, which will lead to another crash later? Or should I just "stop worrying and learn to love the bomb"?

Sunday, 27 October 2013

Error 0x80073CFF trying to install apps from Windows 8.1 store

Yesterday, I finally go round to trying to update the apps on my wife’s computer, and found that the Windows Phone app wouldn’t update, and returned the error

0x80073CFF (ERROR_INSTALL_POLICY_FAILURE)

Looking that up, it says that you need to have a developer license.

That’s a bit odd, because, that app isn’t being sideloaded, it’s being loaded from the store.

However, I hadn’t debugged on her machine for awhile, and as a result, it transpires that my developer license had expired.  Acquiring a new license magically fixed the problem.

It appears that removing the license might also have fixed the job.

You can do that with powershell by using this command (source http://msdn.microsoft.com/en-us/library/windows/apps/hh974578.aspx)

C:\PS> Unregister-WindowsDeveloperLicense

Windows 8.1 Api Changes : DisplayInformation.OrientationChanged

 

I wasted quite a bit of time this morning trying to figure out how to migrate from the old DisplayProperties.Orientation changed to this new api.

The crux of the confusion is the inconsistent implementation:  The old implementation was static, where the new event is on an instance.

That begs the question, where do I get the instance from?

Looking around the various samples, it appears that the best location is

DisplayInformation.GetForCurrentView(); which returns a DisplayInformation that I can wire up.

Now, the worry was, what happens when I move the CurrentView to another screen?  How do I get that new instance?

I made a couple of wrong guesses, including hooking up to the only static that looks like it might fire on DisplayInformation.DisplayContentsInvalidated.  In there, I checked to see if my new DisplayInformation was equal to one I had saved earlier from GetForCurrentView.

To my surprise, using object equality, they were always the same, even though the had different values!

So, GetForCurrentView*( appears to always return the same object, with different values.

As a consequence, it appears that the correct way to wire up is to hook up to the OrientationChanged event on the DisplayInformation from DisplayInformation.GetForCurrentView() which isn’t exactly obvious.

Hope this helps someone else.

Update:
It’s worse that it appeared.  DisplayContentsInvalidated appears to pass a null DisplayInformation when the device is actually rotated.

Thursday, 24 October 2013

Sky High CPU Usage for Explorer on Windows 8.1

Most of today was spent trying to track down why one of my PCs was running so slowly.

I set up a scan of my pc to try and track it down with defender, but it ran for hours, and still had only completed 20% of the scan.

I also noticed that a network drive (containing music and photos) was also seeking a lot, and there didn’t appear to be anything actively opening the files.

So I started the sysinternals process explorer, and confirmed that the music and photos folders on that network drive were indeed being accessed.

Eventually I tracked it down to change I made about a year ago to do with the music and photos app.

http://answers.microsoft.com/en-us/windows/forum/windows_8-pictures/network-share-locations-do-not-appear-in-music-app/210616b9-98ae-430b-a12e-fc95b36eaadb

I’d created a symbolic link to the network locations from c:/apps/network/music and c:/apps/network/photos to the network locations.

I’d then added these locations to the network.  Apparently I’d also set them to be available offline too, and then added them to the respective libraries.

After the update, it appeared that the afflicted machine was attempting to sync all of the files from the network to my local drive, and while progress was being made, it still hadn’t completed.

Wednesday, 2 October 2013

SQLite and Foreign Keys

While trying to build our latest database, I ran into a couple of problems with the foreign key support.   I eventually managed to create tables that had a foreign key with an ON DELETE CASCADE attribute applied.

This in itself wasn’t easy.  The table designer doesn’t seem to allow you to change anything to do with the deletes or updates, so you need to run a command that alters your table (or drops it and recreates it with the correct constraints).

I did that by going to the design view, and choosing

Generate Change Script…

then edited the script to append ON DELETE CASCADE to the relevant CONSTRAINT lines.

Having succeeded with that, I went to my sample data I’ve been playing with and deleted one, only to find that the related records were orphaned in the database!

What’s going on?  Why don’t the foreign key constraints in SQLite work?

A little bit of searching turns up that you have to actually turn on foreign key support!  This is done by executing

PRAGMA foreign_keys = ON

statement for every connection.

So I tried this in a SQL window in the designer, every time I tried to turn it on with a PRAGMA command it wouldn’t stick.  Of course:  It’s creating a new connection!

The secret then is to alter your connection string to include

foreign keys=True;

at the beginning of it.

Et Voila!  It now works.

This was a result of the VS201X designer opening a new connection each time.

Working with SQLite with both VS2012 and VS2010

I’ve recently started building a new component that needs database access, and when once again faced with a choice of database technology (the existing codebase is using SQL CE 3.5) I chose SQLite this time, for the following reasons

  • SQLCE can’t seem to work with the entity framework and create autonumbered entries
  • SQLite is supported on other platforms.

So, I began designing my tables, following the instructions here: https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki

I downloaded the 32 bit installer for VS2010, and installed it, but was surprised to find that VS2012 support wasn’t included, so I downloaded the vs2012 installer too, and installed that, using the defaults of the installer.

That didn’t work, giving me errors when I tried to open the VS2012 designer, so I uninstalled from Programs & Features and started again with the 2012 installer.

That then worked for 2012, but no support was installed for VS2010 this time.  So, I ran the installer again for VS2010, and made sure to change the installation folder to something other than the defaults.

And then it worked.