Saturday 14 December 2013

WP7 Run Under Lock Screen Mystery

My son just returned from the Varsity Ski Trip, and used Skied Demon on a Windows Phone 7.  Now I know there aren’t many people out there who actually have one of these phones, and we rewrote the software to work while making phone calls on WP8, however, it still irks me when code we wrote doesn’t work for some of our customers.

The problem goes like this:

My son starts logging in the app, and then presses the power button to lock the screen and save power.

Later, he sees something that requires a photo and presses the camera button to wake up the phone.

After he backs out of the camera, he finds that the program is no longer running.

Of course, while on holiday, he had better things to do than tell his father an app isn’t working like he thinks it should be, but now he’s back, I’ve looked into the cause (30 minutes from bug report to investigation.  That’s how we like to treat all bug reports, so if one of our apps crashes, let us know, and we’ll investigate).

It turns out that the software is  getting a RootFrame_Obscured message, when he presses the lock screen.

When the camera button is pressed, an Application_Deactivated event is raised, my state is stored, and that’s the last my code ever sees of any execution time.

The program does have a background XNA thread for audio that’s raising a System.Threading.ThreadAbortException in Microsoft.Xna.Framework.dll before it exits however.

Any suggestions?

Sunday 1 December 2013

NullReferenceException in AdDuplex

We recently switched over to AdDuplex in our trial apps to get some extra promotion, as using the Microsoft PubCenter.

Last night, while waiting around, I started playing with one of them, and found that the app would crash, with the following call stack when connected to BTOpenZone, but not logged in.

System.NullReferenceException
Object reference not set to an instance of an object.
   at AdDuplex.AdControl.OnNetworkManagerAdLoaded(Object sender, AdLoadedEventArgs e)
   at AdDuplex.Models.NetworkManager.OnAdLoaded(TextAdInfo newAd)
   at AdDuplex.Models.NetworkManager.<>c__DisplayClass2.<LoadNewAdCallback>b__0()

I vaguely remembered seeing an update to the AdDuplexW8 nuget package midway through my updates that said that it fixed a null reference problem.

Obviously, this was it.

So, if you’re not using AdDuplex.WindowsPhone version 2.8.0.4 or later, you’ll need to rebuild your apps and resubmit, or else your app too will crash.

Friday 29 November 2013

Where’d my interface go?

One of the joys of modern development is that you get to work in pretty much any language there is.

I’ve been doing a lot of C# development lately (Phone, WinRT and WPF desktop), but occasionally have to drop back to some C++/MFC software.

Yesterday, I had to refactor some code, that made some glaring assumptions about it’s use (yes, I used reinterpret_cast to convert a CWnd derived object to a class derived from CPropertyPage so that I could call one of it’s public members).

So here’s what I did:

First, I declared an interface that represented exactly what I wanted to do:

interface IDoSomethingAwesome
{
public:
virtual void DoSomethingAwesome()=0;
};


Next, I modified my class, which needed to expose the interface


public class MyAwsomePropertyPage : 
public CPropertyPage, IDoSomethingAwesome
{
/// ... etc.
virtual void DoSomethingAwesome() override;
}


and provided an implementation in the class.


Then in an unrelated class, I made a call like this


CChildOfAwsome::SomeEventHander()
{
IDoSomethingAwesome *pInt = dynamic_cast<IDoSomethingAwesome>(GetParent());
if (pInt != NULL)
{
pInt->DoSomethingAwesome();
}
}


Only one problem:  pInt was always NULL!  That was odd, because looking at the pointer returned by GetParent() gave me an object that the debugger knew was of type MyAwesomePropertyPage, yet I couldn’t for the life of me figure out why this wasn’t working.


I started writing this up as a question on StackOverflow, but while doing so, ended up talking to the duck and discovered the error in my ways.


My C# had blinded me to the joys of C++ inheritance.


I had inadvertently declared my IDoSomethingAwesome interface not public.  As a result, asking for the interface dutifully returns null, as private inheritance is an implementation detail, and not visible in the inheritance tree.


So, the correct declaration is

public class MyAwsomePropertyPage : 
public CPropertyPage, public IDoSomethingAwesome
{
/// ... etc.
virtual void DoSomethingAwesome() override;
}

Friday 22 November 2013

Tap My App! Share your App with NFC!

As part of the DVLUP challenges, you can gain up to 500 points by adding NFC to your app.

Thanksgiving’s coming up very soon, so I thought sharing our Wishbone application between Windows phones would be a really cool way to do it.

If you read the documentation, you’ll find something promising in the ProximityDevice.PublishBinary documentation named LaunchArgs.WriteTag

There are some magic parts to this documentation that are a little bit difficult to work out, as I’ll soon describe, so your journey down this route will be frought, and unfortunately, after a lot of pain, I finally realized that this would not work, as it only writes to static tags.

I’ve ordered some of them like this, and they’re in the post.  I can't wait for the fun I'll have with these, but I digress.

The important thing to realize is that there aren’t any static tags on your phone.  I for some reason thought that what was happening is that you could write to them from your code, and appear as a tag.  That is most definitely not true.

So how do you launch your app?

I’ve come up with a class that makes all of this really easy.  Here’s the code that I add to my Application_Launching event handler.

mgr = NFCManager.Default;
if (mgr.NFCSupportedOnDevice) {
mgr.DisplayName = "Wieser Software Wishbone";
mgr.AddAlternateIdentity(platform: "Windows",
appid: "WieserSoftwareLtd.BouncingBalls_38031z1jk36d6!BouncingBalls.App");
mgr.Enabled = true;
}


Now if you tap your WP8 app against a Windows Tablet with NFC, it will attempt to launch our BouncingBalls App (Wishbone does not yet have a W8 version, though it’s in the pipeline for a Tidy 250 XP in the double challenge)


The format of the appid is difficult to determine.  The first part before the “!” character can be found when editing Package.appxmanifest.


The second part is really badly documented.  It is in fact the name of the class that contains the entry point of your App.  Now, we obfuscate using EazFuscator, and as a result, the namespace and class names are probably obfuscated.


As a result, when you tap, and the app isn’t installed, the user is asked if they want to get the app from the store.


On the other hand, if the app is installed, nothing appears to happen.  I can’t decide if this is because my app doesn’t claim that it supports Proximity, or that it doesn’t support networking at the moment, so some investigation is still required.


-update-
After further investigation, it appears that the part after the ! should just say App in my case.


Full source code of the class is available here:


#define NFC_DEBUG_STATUS_MESSAGES
using System;
using System.Diagnostics;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
using Windows.Networking.Proximity;

namespace Framework
{
public class NFCManager : IDisposable
{
static NFCManager _instance;
ProximityDevice _nfcdev;
DispatcherTimer dt;

[Conditional("NFC_DEBUG_STATUS_MESSAGES")]
private void Trace(string s)
{
Debug.WriteLine(s);
}

public void Dispose()
{
if (this == Interlocked.Exchange(ref _instance, null))
{
// this is us.
if (_nfcdev != null)
{
_nfcdev.DeviceDeparted -= _nfcdev_DeviceDeparted;
_nfcdev.DeviceArrived -= _nfcdev_DeviceArrived;
PeerFinder.AlternateIdentities.Clear(); // clear anything we added
Deployment.Current.Dispatcher.BeginInvoke(() => dt.Stop());
_nfcdev = null;
GC.SuppressFinalize(this);
}
}
}

~NFCManager()
{
if (_nfcdev != null) Dispose();
}

private NFCManager()
{
_nfcdev = ProximityDevice.GetDefault();
if (_nfcdev != null)
{
_nfcdev.DeviceArrived += _nfcdev_DeviceArrived;
_nfcdev.DeviceDeparted += _nfcdev_DeviceDeparted;
dt = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) }; // tick once per second
dt.Tick += dt_Tick;
}
}

bool bPeerFinderRunning = false;
DateTime dtExpiry;
private void StartPeerFinder()
{
if (!Enabled) return;

if (bPeerFinderRunning) StopPeerFinder();
dtExpiry = DateTime.UtcNow.AddSeconds(15); // don't leave this on too long.
bPeerFinderRunning = true;
Deployment.Current.Dispatcher.BeginInvoke(() => dt.Start());
PeerFinder.Start();
Trace("Started Peerfinder");
}

private void StopPeerFinder()
{
if (Enabled && bPeerFinderRunning)
{
bPeerFinderRunning = false;
// now get onto UI thread to stop the timer
Deployment.Current.Dispatcher.BeginInvoke(() => dt.Stop());
PeerFinder.Stop();
Trace("Stopped Peerfinder");
}
}

// check if we've overrun, and if so, Switch it off.
void dt_Tick(object sender, EventArgs e)
{
if (dtExpiry < DateTime.UtcNow) StopPeerFinder();
}

// this runs on some arbitrary thread
void _nfcdev_DeviceDeparted(ProximityDevice sender)
{
StopPeerFinder();
}

// this runs on some arbitrary thread
void _nfcdev_DeviceArrived(ProximityDevice sender)
{
StartPeerFinder();
}

public static NFCManager Default
{
get
{
if (_instance == null)
{
_instance = new NFCManager();
}
return _instance;
}
}

public bool NFCSupportedOnDevice { get { return _nfcdev != null; } }

/// <summary>
/// Adds an alternate launch string, depending on your platform.
/// Sample values are for Windows 8
/// platform:"Windows", appid:"WieserSoftwareLtd.BouncingBalls_38031z1jk36d6!BouncingBalls.App"
/// where the part before the ! is your package ID, and the last part is the
/// namespace of your Application Object (full namespace). This is despite obfuscation.
///
/// For Windows Phone 8: The GUID is your app ID.
/// platform:"WindowsPhone", appid:"{41004b9e-eab4-4784-94d6-d1bdd219e4de}"
///
/// Don't add an alternate identity for the platform you're on, or you'll get an exception
/// </summary>
/// <param name="platform">see strings above</param>
/// <param name="appid">see strings above</param>
public void AddAlternateIdentity(string platform, string appid)
{
PeerFinder.AlternateIdentities.Add(platform, appid);
}

public string DisplayName
{
get { return PeerFinder.DisplayName; }
set { PeerFinder.DisplayName = value; }
}

private bool _bEnabled;
public bool Enabled {
get { return _bEnabled; }
set
{
if (!NFCSupportedOnDevice) throw new NotSupportedException("There is no NFC support on this device");
if (value != _bEnabled)
{
StopPeerFinder();
_bEnabled = value;
}
}
}
}
}


A couple of comments on the code:


First, you’ll need to enable ID_CAP_PROXIMITY on your app.


You’ll also note some code that uses a dispatcher timer that fires once a second once a device has come in range.  This code is there to switch it off if a connection isn’t made in time.


Have fun, and follow me on @WieserSoftware

Sunday 17 November 2013

AdDuplex requires ID_CAP_PHONEDIALER

We’ve recently started using AdDuplex in our trial apps to get some extra promotion, as using the Microsoft PubCenter. 

We previously had the Microsoft Ad Control in the app, and it required a lot of capabilities that frankly I think scares off users.

So, I was very happy to learn that AdDuplex required only ID_CAP_NETWORKING

One of the apps we updated was a WP7 app, and as part of the submission Capabilities are automatically detected (this is no longer the case on WP8), and I was surprised that it flagged up ID_CAP_PHONEDIALER.  I suspected that I had done something wrong with remove of the old ad control.  ID_CAP_PHONEDIALER is added when you use the PhoneCallTask API

So I fired up JustDecomple from Telerik and did a search for that in my xap project.

Eventually, that led me to the AdDuplex.Models.NetworkManager class and it’s DisplayPhone method, which is called by AdDuplex.HandleAdClick

It turns out that if a phone number is supplied by the ad, that is the preferred mechanism for serving the ad!  I contacted AdDuplex about this, and I was told that the server currently will not serve these ads.

What DOES this mean for users of the control?

In the case that it does in the future, you will be pleased to know that your app will crash if you haven’t added the capability to your app if the user clicks on one of these links.  This also means that a man in the middle attack on AdDuplex’s servers could also cause your app to crash.

I contacted AdDuplex to ask about this and was told:

“We will consider removing the capability from the SDK. It’s only there for some future feature which is unlikely to materialize any time soon and we don’t actually want to serve ads like that. Thank you for bringing this to our attention.”

In the meantime, it’s still there in the latest November 14th update, 2.8.0.4

Saturday 16 November 2013

Slider and IsDirectionReversed–Why doesn’t my app work on WP8 (part 6 of N)

Just when you thought all the bugs must have been ironed out by now, you stumble across a new one.

I’ve recently been updating all of my apps to Visual Studio 2013 so support will be simpler in future, and as a result started porting to WP8 from our old WP7 codebase.

Of course, everything is supposed to just work.  Today we’ll focus on the IsDirectionReversedProperty, which as will see should really be called IsDirectionReversedProperly!

Try sticking this in your WP app:

<Slider Orientation="Horizontal" Maximum="10" IsDirectionReversed="True" />

Can you see where this is going?

Now add Minimum="5" and be amazed that this slipped through testing.

It’s broken on the 720p emulator.  It’s broken on my Lumia 920 with GDR3.  It’s not broken in a WP7 app though.

So, I wonder how Microsoft can fix this out in the wild, (though it only seems to work in any kind of reasonable way if Minimum is set to 0).  Someone may be depending on this behavior.

Sunday 10 November 2013

RateMyApp challenge on DVLUP code defects and gotchas

If you’re trying to run the RateMyApp challenge over at DVLUP (if you haven’t signed up, you should.  Click the link), you may be interested in a few problems I’ve stumbled across.

First, your app bar will still be active, even if the rating window is open. 

To fix that, you’ll need to wire up to the feedback controls VisibilityChanged event, and then in the handler, set

ApplicationBar.IsVisible = FeedbackOverlay.GetIsNotVisible(feedbackctrl);

Secondly, you’ll find that if you have any touch events, they may be handled as well.  This includes ListBox manipulation and scrolling, so you’ll need to turn that off in the handler too.

And finally, the bug.

If your app has multiple pages you’ll find that on the 5th and 10th run, your user will continue to be pestered every time you navigate back to the main page of your app.

To fix this, I suggest you do the following:

In FeedbackOverlay.xaml.cs add the following to the SetVisibility(bool visible) function inside the bottom of the else statement:

FeedbackHelper.Default.State = FeedbackState.Inactive;

If you don’t, the state will remain the same, even though the FeedbackOverlay was dismissed, so it will continue to be shown.

In addition, you must also change the yesButton_Click handler to SetVisibility(false) at the end of the function, rather than the beginning.

Wednesday 6 November 2013

Detecting .NET 4.5.1

According to Microsoft on this page, this is how you detect .NET 4.5.1

However, on both of the Windows 8.1 machines I currently have, I see a version for release of 378675.

I wonder if they’ve got it wrong.

UPDATE:

After further investigation, on my 32 bit windows 8.1 machines, I’m seeing 378675, including after installing the packages.

On 64 bit windows 8.1 machines, I also see 378675.

However on 64 bit windows 7 machines, after installing the packages, I see the correct version of 378758.

This is especially humorous in light of yesterday’s post where an 8.1 app will report that it’s 8, causing the installer to repeatedly try to install 4.5.1.

Tuesday 5 November 2013

GetVersionEx won’t help you now!

If like me, you’ve built some crash handling code into your app so you can find out where your application is crashing in the wild, and find that WER isn’t the most effective way to get your crash dumps, you might be in for a suprise.

Since the Windows 8.1 update, you’ll no longer be able to find any machines that run a version later than Windows 8?

Why?  Because of this change they made on Windows 8.1.  Apparently, since we developers can’t be trusted to get version checks right, they’ve deprecated GetVersionEx, and to add insult to injury, make it lie and claim that it’s only Windows 8.

So, if you want to retarget for Windows 8.1, and actually find out what version it is, you’ll need to add this to your app manifest.

<!-- Windows 8.1 -->
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>

along with all the previous versions.

I wonder if 8.2 or whatever will lie, and say it’s 8.1 without the correct manifest too?

Upgrading a C++/CLI project to VS2013 from VS2010

Today, I begin to update an old C++ project to the latest compiler, and while building got this error message:

1>stdafx.cpp : fatal error C1107: could not find assembly 'mscorlib.dll': please specify the assembly search path using /AI or by setting the LIBPATH environment variable

That’s all very well, but it wasn’t obvious what to do.

Here’s how I solved it:

First, I created a new CLR Class Library project with C++, and examined the vcxproj file generated.

I then took my project that wouldn’t build, and right clicked and said, unload project, followed by edit on the same project.

Looking for differences I spotted this:

<TargetFrameworkProfile>Client</TargetFrameworkProfile>

Of course, .NET 4.5 doesn’t support the client profile, and surprise surprise, it now works once I remove that line.

It looks like the VS2013 project upgrade doesn’t quite get this one right.

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.

Tuesday 18 June 2013

Some lines may be missing printing to OneNote

In one of the applications I work on with my Peach Innovations hat on, we have recently discovered how useful it is to print directly to One Note for generating reports.

However we discovered today that pen’s created like this

HPEN hp = ExtCreatePen(PS_GEOMETRIC|PS_JOIN_BEVEL|PS_ENDCAP_FLAT, thickness, &lbr, 0, NULL);

with a thickness of zero don’t actually show up when sent to one note, although they show up on screen, and on every printer we’ve ever used, as well as printing to XPS.

I can’t find anywhere that documents that this shouldn’t work, but setting the pen to thickness 1 solves the issue.

Monday 17 June 2013

MouseMove Event - Why doesn’t my app work on WP8 (part 6 of N)

Continuing to port our app Where's my Tent to WP8, I ran into a problem with the rating control we built—It just wasn’t working correctly on WP8.

It turns out that on WP7, when you tap on a control, you also get a LeftMouseDown event, immediately followed by a MouseMove event.

This is no longer the case.  You no longer get the MouseMove event automatically, so must handle the position of the LeftMouseDown separately.

Sunday 16 June 2013

Wow, that’s a tall image–Why doesn’t my app work on WP8 (part 5 of N)

I’m getting ready to port our app Where's my Tent to WP8, and as a start, I thought I’d rebuild it with the latest libraries, and incorporate some changes from our other apps.

After hooking in the new code, I ran it on my WP8 device, and had a big surprise.

On WP7, it appears that photos returned from the CameraCaptureTask are always in Landscape mode, though you can figure out what orientation they really are in using a technique described by Tim Heuer.

Unfortunately for me, my app was coded to assume Landscape, so when an image is actually delivered in portrait mode, my assumptions break due to this breaking change.

If you’ve made the same assumption, you’ll have the same problem.

I suspect Tim’s code might not work either

Because now his code that rotates the image may now fail because it returns portait, and then he rotates the pixels.

Update 17 June 2013

It turns out that on WP8, the Exif data doesn’t exist at all in the stream returned by the Photo Chooser, so Tim’s code will crash, as it doesn’t check for an exception or null.

Saturday 8 June 2013

WebView Z Order Again–This time with AdControl

Back in October, when I was trying to get our Travel Advisories app release we ran across a problem with flyouts and z-order.

What happened was that when you popped open a flyout, our HTML views would appear on top of the flyout, as we’re working in XAML and not Javascript (Javascript have a flyout that works on the other hand, apparently)

It’s probably old news to some of you, but today we tried to add advertising to a Windows Store app, and came across the same problem.  The flyout has the advertisement floating on top of it.

I started with the samples Developer Walkthroughs (XAML) on the MSDN site, and sure enough my control suffered.  I was certain there had to be a solution, but as is typical for Windows development, it’s never easy to find it.

You end up on pages like this that fleetingly suggest UseStaticAnchor which is of course the actual solution, but the list of properties doesn’t even show it.

Other documentation around the web suggests Resume and Suspend which has now been superseded.

The moral of the story:  Set UseStaticAnchor=”True”  in your XAML.

What Microsoft Should Do

Maybe we’ll be lucky and in 8.1, they’ll get rid of this problem with the WebView Z Order.  I’m not holding my breath, and you probably shouldn’t either.

Storage Full on Windows Phone 7.8

I’ve been lucky enough to have received a fair few phones from Microsoft and Nokia for developing on the platform, and have passed them around my extended family.

I gave one of my Lumia 710 devices to my 86 year old father-in-law, who I’ve been slowly dragging into the modern age of computing over the past 25 years.  Don’t get me wrong: He worked at Ferranti working some of the earliest commercial computers, but things have changed a bit since the days of 1024x40 bits of core memory.

But you still run out of memory even today.  We found that something on the phone was using up all of the storage on the phone.  It got to the stage, where nothing was working, because no-one was able to update their isolated storage files. Worse, uninstalling apps one by one didn’t enlighten us.  There was still about 3gb unaccounted for.

In the end, we did a total reset of the phone, and then re-downloaded everything.  After that we had a reasonable amount of memory free, but I don’t have any confidence that we won’t be doing all of this again in the future.

It’s a shame that there isn’t more transparent access to the storage on being used on Windows Phone 7.x, so that users can find out which app is being a bad citizen and spoiling the Windows Phone party for everyone.

If a WP8 Lock Screen image changes…

and there’s no-one there to see it, did it really happen?

Our app, Terminator has been updated for Windows Phone 8, and now supports wide tiles, and can also be the lock screen provider.

However, we’ve noticed that if you don’t look at the lock screen every half an hour, occasionally, the image displayed is out of date, but if you download the images stored in isolated storage has been updated.

We believe this is caused by the A/B switching algorithm suggested on MSDN.

Let’s say it’s 9:00, and the first image runs, so we update image A
At 9:30, the run again, and generate image B.

This continues every half an hour, so when I go to bed at 23:00, when I get up and look at my screen at 6:00 I see the image generated at 23:00.

Looks like we need to find another algorithm, probably creating a new file based on clock ticks, and then deleting all of the old files, so we generate a new file each time.

Of course, we now have the problem that we may fill up the users phone with abandoned files if anything goes wrong, which is a subject I’ll discuss soon.

Wednesday 29 May 2013

Could not load satellite assembly - Why doesn’t my app work on WP8 (part 4 of N)

While beginning to port our app Terminator to WP8, we were faced with an exception in App.InitializeComponent of the type MissingSatelliteAssemblyException

We started terminator way back in the Windows Mobile 6.5 days, and it was one of the first apps we produced for WP7.

At some point in the distant past, (November 2011 to be a bit more precise) the store changed so that you needed to add something like this to your assembly attributes:

[assembly: NeutralResourcesLanguage(“en”)] or as suggested by some here:

http://stackoverflow.com/questions/6741455/the-neutralresourcelanguage-attribute-is-missing-on-the-entry-assembly
[assembly: NeutralResourcesLanguage(“en”), UltimateResourceFallbackLocation.Satellite)]

Unfortunately, I chose this second option, and that’s the source of the error.

Removing it solved the problem.

Why does System.GetType return null–Why doesn’t my app work on WP8 (part 3 of N)

While porting our Skied Demon Ski logger app to Windows Phone 8 to support background location services and new wide tiles, we stumbled across a problem calling

System.GetType(“typename, assemblyname”) where it would always return null.

While GetType worked with a fully qualified assembly name, that struck me as bad for maintainability as I’d have to remember to change it whenever something changed, and because it was loaded by reflection, it wasn’t likely to go away completely.

After some investigation, I finally came up with this helper method:

static Type GetTypeEx(string typename, string assemblyname)
{
foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
{
if (a.GetName().Name == assemblyname) return a.GetType(typename);
}
return null;
}


So I now call it like this:


GetTypeEx(“typename”, “assemblyname”);


I only do this a couple of places in the software, but if I were to make heavy use of reflection, I’d probably cache the assembly references into a dictionary to save the iteration.

Friday 17 May 2013

What an obscure bug - Why doesn’t my app work on wp8 (part 2 of n)

We’ve just submitted a new update for Skied Demon, our GPS logger for Windows Phone, and while testing by cycling, we noticed that the top speeds weren’t updating.

But we also noticed that this only happened on Windows Phone 8.  The exact same program running on WP7 works fine.

Originally, we thought there was some problem with our data notifications, and then we noticed that the updates failed only after running behind the lock screen.

It turns out, that on WP8, calls to Obscured and Unobscured events are not balanced as they were on WP7.  Why exactly my app would care that it’s been obscured even though it’s already had the message is a bit beyond me, but that’s the way the new API rolls, I guess.

We’ve now submitted an update to the store.

Friday 10 May 2013

Why doesn’t my app work on wp8 (part 1 of n)

We recently switched over to a Lumia 920 for testing our apps, and have found that some of our apps just don’t work correctly.

For instance, our popular Skied Demon ski logging app exhibits problems on Windows 8 on a Lumia 920.

It turns out that the problem is caused by setting up BitmapCache as the CacheMode on some of the controls to improve performance.  The ironic thing is that this fails on Windows Phone 8 and not on Windows Phone 7.

This may also be caused by the increased screen resolution on this particular phone though I haven’t yet been able to verify that.  I suspect that what’s happening is that a bitmap is being constructed for the size of the zoomed area.  As that size grows, eventually the entire thing falls apart.

However, I would have expected WP8 to behave at least as well as WP7.

So, that’s one (of presumably many to follow pitfalls, as we know at least one more of our apps is currently not working, probably caused by a store issue)

Monday 6 May 2013

How to use Microsoft.Bcl.Async correctly on XP

We recently updated our Terminator for Windows Desktop application to use the async/await features and still target .NET 4.0 so our XP customers can continue running the program.

So, first we updated our copy of Visual Studio 2012 to the latest and greatest release 2, and installed NuGet too.  So far so good.

Our installer is based on WiX, so we also updated to version 3.7, but we built our own bootstrapper, so we ported that to VS 2012.

Unfortunately, that led us to discover that a regression causes VS2012 Rel 2 to produce programs that don’t actually run on XP, as described here on connect, but luckily there’s a solution that works on the workaround page

That’s the first hurdle down.  So, we then added support for Microsoft.Bcl.Async by typing into the NuGet Package Manager Console:

Install-Package Microsoft.Bcl.Async

From there we could target.net and declare async entry points and await them to our hearts content.

So it came time to obfuscate.  We use EazFUSCATOR.net, which lets you trial for free for 30 days.  We’ve found it well worth the investment to purchase this package, which also gives support.  Unfortunately, VS2012 and Microsoft.Bcl.Async broke Eazfuscator 3.7, but the team there pulled out all of the stops and got us a beta that fixed the problems we’ve had within 24 hours of each problem.

So, we were good to go.  We tested it all and everything seemed hunky dory.  The only thing was, we started to notice that the async routines seemed to be very async.

how ASYNC?

Well, so async that they never, ever completed.  This was a bit of a puzzle.  It appeared that the methods were never completing at all.  So what went wrong?

It turns out that you must actually install some new DLL’s when you install your package, or it will just fail silently (which was the real surprise).

  • Microsoft.Threading.Tasks.dll
  • Microsoft.Threading.Tasks.Extensions.Desktop.dll
  • Microsoft.Threading.Tasks.Extensions.dll
  • System.Runtime.dll
  • System.Threading.Tasks.dll

Needless to say, we’d forgotten to add these into our WiX installer, and as a result the machines that were using the installer were failing to fetch the cloud overlay, until we added them.

Saturday 4 May 2013

A discrepancy between the solution’s source control information

Yes, I’ve been battling with my source control provider (Source Safe) and Visual Studio 2012 Pro.  I add my solution to source control with the menu item, and everything appears fine.

However, when I close my solution and then reopen it, I get this gem:

image

I’ve tried reconstructing my project from scratch, and keep bumping into this problem or variants of it.

Searching the net doesn’t really turn up much helpful.

After 5 hours, I’ve finally found what appears to be the problem.  In each .vcxproj and .vcproj you’ll find a line like this:

<SccProjectName>"%24/Products/WPF/education/DesktopTerminator.root/DesktopTerminator", FAUAAAAA</SccProjectName>


The problem is the %24.  Changing it manually to $ fixes the problem!  To fix it, right click each project, select unload, then select Edit, and make the changes, then select reload.


Now it turns out there is some other chatter about it here on social.msdn and here on connect


Notice that on connect it will be fixed in the next major version of Visual Studio.  So, for now, keep editing those projects.

Sunday 7 April 2013

BT 2-Wire Business Hub handing out wrong IP Address

One of our clients had a hard drive crash that prevented them booting into Windows.  As the machine was pretty old, and running XP, we agreed that it was a good time to upgrade to Windows 8 and snappy new hardware.

Everything went well, we managed to reinstall all of the software on the new machine, and transfer over all of the data.  We even managed to make a VHD image of the old broken hard drive, and copy that onto the new machine.

As the machine was the network server as well as one of the workstations, it seemed the best plan was to keep the machine name the same, so that the new machine could impersonate the old one.

The only problem was that the BT Hub was insisting on handing out the IP address of the old, dead machine (192.168.1.100) instead of the one assigned to the new machine via DHCP.  And there seemed to be no way to get the Hub to forget about the old machine.  Sometimes it returned 127.0.0.1 and others it returned 192.168.1.100, but never it seemed 192.168.1.64

This problem dragged on for a couple of weeks, until finally I noticed the problem.

The BT hub has case sensitive host names.  The old machine was STUDY, and the new machine was study.

When a lookup of a host name was requested, the old machine was first in the table, and a case insensitive comparision returned that, instead of the new lower case machine.  Why the Hub compares as case insensitive but inserts as case sensitive appears to be a bug in the firmware.

The FIX?

Simply rename the machine on the control panel to be the old upper case version.

1and1 changed my .htaccess file!

Over the last few months I’ve had sporadic random changes to the .htaccess files on my website.

I looked again today when I noticed that some of my sites I look after are behaving incorrectly.

The .htaccess file had been changed to this:

AddHandler x-mapp-php6 .php3 .php4 .php .phtml

More to the point, all of my changes were gone.

What caused it?

I have a hunch.  The changes that occurred at various places on my website occured at pretty much exactly the same time as I added an additional domain to my package.

So the moral is, if you’re using 1and1 for hosting, and ever add a domain, they’ll break the rest of your websites.

I haven’t had any useful help from 1and1 on this.  They’re claiming that someone is hacking my site, but the logs don’t show anything, so I think that’s unlikely to be the cause.  My money’s on the hunch at the moment.

Sunday 10 March 2013

Windows 8 Winhlp32.exe

It seems Microsoft just can’t get this one right.

Installing some old legacy apps that use Winhlp32 for their help leads you on an out of the box install of Windows 8 to this page:Windows Help program (WinHlp32.exe) for Windows 8, which is KB917607

Unfortunately, installing this update doesn’t actually help on a 64 bit system.

When you do try to launch the installed winhelp, you get a partial title bar describing the problem.

winhlp32

Digging out Spy++ reveals that the actual title continues:

“located in the System directory.”

Moving the file there unfortunately, doesn’t actually help.

So, for the moment, I’m uninstalling by running the downloaded msu file from the update from an elevated command prompt like this:

windows8-RT-kb917607-x64.msu /uninstall

Attempting to install the Windows8-RT-KB917607-x86.msu on either a 32 bit or a 64 bit system claims that “this update isn’t applicable to your computer”

Friday 1 February 2013

More Backup Woes: Error 0x81000037

Today, I was called out to a client who reported that their backups were failing.  They just use the standard Windows 7 backup, but after getting about 30% of the way through, the backup failed with the above error.

It turns out the problem was caused by the anti-virus software detecting a virus (some Java exploit) during the backup, and causing it to fail.  The virus was being reported in Microsoft Security Essentials in a shadow copy on the disk.

So, my solution, was first, clean the account that was infected using Security Essentials.  That would probably be sufficient to let the backup complete, but I also took the following additional steps, just to be certain nothing was hanging around in a previous snapshot:

  1. Uninstall Java.  You know you want to anyway.
  2. Right click the C drive, and choose disk cleanup, go to the more options tab, and choose system restore and shadow copies.

Capture

After deleting, your disk should no longer contain any copies of the file security essentials is complaining about, and backups should be able to proceed as normal.

Wednesday 30 January 2013

Why I’ll never buy another Dell

I’m a windows developer, and have bought quite a few Dell PC’s over the years (since 1989 in fact), and have recommended them to clients.

Today, I was just about finished setting up the third Dell for a client, this one a Vostro 3360 running Windows 8.  My normal installation procedure is this.

  1. Make the set of system recover disks from the manufacturer’s program if they’re not included, or alternatively make a system image using Windows backup.
  2. Uninstall any vendor supplied anti-virus, and then install Microsoft Security Essentials
  3. Install all of the Windows updates on the machine.
  4. Install any additional software the client purchased (e.g. Office)
  5. Install Windows Live Essentials
  6. Keep applying Windows Updates, until there are none left, restarting after each.

When all of the Windows Updates have completed, make a final system image, using the Windows supplied software.  On Windows 8 this is called, the Windows 7 File Recovery (I’m not kidding).

Now, I used not to do step one, but an HP machine I wrote about a few months back made me glad I do, as the system was basically unusable after a Windows Update, but that’s another story.

This time though I made the choice not to take step 1 first, and once again regretted it.

Everything went fine, the system updated ok, and when I got to the stage of making a final system image, everything went wrong.  The system was unable to make a system image.  Without a DVD drive, we’re pretty much stuck.

What Went Wrong?

It appears the the out of factory configuration has created a partition that’s too small to create a snapshot using the Shadow Copy Service, and therefore the backup could not be made.  Initially the error message indicated that a drive was too small, and I assumed there was some problem with the external USB drive, being only 467 GB on a 500 GB system, so I removed the other partitions, and tried again, with nearly 1GB free.

No Joy.  So I tried to backup across a network.  Again, no joy. 

In the end, the nice Dell support man told me that they don’t support Windows 8’s built in backup and I’d have to pay another £31 + VAT to get the Dell backup utility.  But when asked they also said that it used the volume shadow copy service (as most programs will when making a backup).  Not wanting to throw good money after bad, we called the sales rep, who said they could issue us a code free to get the backup software.

But when we called the number, they wouldn’t.

Had I gone straight to step 1 instead of skipping it before installing everything else, I would have saved myself hours of time, and gigabytes of bandwidth. Had the customer not chosen a Dell Vostro 3360, I also would have saved hours of time, as the other two Dells I set up this week worked fine (with Windows 7 though, not Windows 8).

So, all in all pretty unsatisfactory.  I’ve wasted time, the customer doesn’t want to pay for the lost time and send the machine back as unmerchantable, but it’s also vulnerable to failure now.

Hopefully, Dell will find a resolution for us, but for now, I know what systems I’ll be telling people to avoid.  You’ve been warned.

Thursday 24 January 2013

Using a 32 GB Surface

I managed to get my hands on a Surface, and was looking into ways to expand the memory using a 64 GB SD card.  There are quite a few suggestions on the web that you can mount the card into an empty folder, and then add these folders to various libraries.

This though doesn’t deal with how to install applications to another folder.

I found several references around the web, that suggests changing a registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Appx

I did this by changing the owner to my account from trusted installer, then afterward, set the owner back by using “NT SERVICE\TrustedInstaller”

However, this doesn’t behave exactly as you might expect, as any existing apps on your machine cannot be updated after this.  More interestingly, I found that I had multiple copies of apps like “Sport” installed on the machine, because they hadn’t all been updated.

So, I’ve now paved the surface, to try again from scratch, knowing what I do now.

After the pave

I created a single user with using a local account, and tried to uninstall the Travel and Sport Apps.  Much to my surprise the apps were still present on the disk.  So I went to the store to see my apps, but it insisted that I sign in with a live account, so I did.

I then decided to try to update just one of the apps (maps) to see what happened to the existing app.  What happens is that the update app is added to the system, but in addition, the old original version stays there.

So, it looks like there’s no way to remove these old versions.  I assume this is to allow users to create a new user, and still get the default apps.

It gets worse

I uninstalled all of the default apps (apart from internet explorer), and all of the pre-installed apps were still present.  So, I decided to see what windows update had in for me.

When I first got my hands on the surface, it informed me it needed a firmware update.  I was a little surprised that I needed to install this too, as I had assumed firmware was firmware.  Obviously a pave wipes absolutely everything, so I now have 21 updates to reinstall.

Fingers crossed.