Thursday, 28 June 2012

Burnt by a faulty WPF install

Over the past couple of days, we’ve been trying to debug a problem reported by a customer of our WPF program, Payslips for PAYE Tools.

The customer was reporting that the program was crashing, and not generating any error reports (internally, we hook into the unhandled exception handler, and generate an email message containing the report, so we can examine the flaw).

Eventually after connecting to his machine remotely, we discovered that there were events in the event log, and they were TypeInitializationExceptions.

That exception is thrown when a static constructor fails for some reason.

Unfortunately, that implied that some of our static members were failing to initialize correctly.  So, we took the initialization and moved it into the instance constructor (as it was the App class), hooked up the error handler at the beginning of the class constructor, and crossed my fingers that it would catch the error.

But it didn’t work!  So I added a message box at the beginning of the class constructor.  That didn’t show either on the afflicted system.  With hundreds of working installs, it had to be something to do with the installation, so another connection to the remote PC was made, and we noticed that there were outstanding Windows updates for .NET 4.0

We left the customer to install them, but he told us that the updates also failed.

Eventually, he told us that the error messages led him to the .NET removal tool (link to follow).

We suggested that he should run that, reinstall our program, and let it download the .NET framework.

And what a surprise, our program now works correctly.

But what a horrible experience for the end user!  How does an install get into that state, and how can we diagnose it?

Tuesday, 12 June 2012

WPF window rendering woes

Today, I started adding some functionality to a new WPF app, and noticed that as I resized my window to be larger, there were black strips appearing on the bottom and right sides of the client area, that were eventually filled with the controls on the page.

This looked horrible, and it appears I’m not the first one to run across this, however, there still seems to be no resolution.

As I’m an old school MFC/C++ guy, I figured there had to be a way to do this.

My first strategy was to hook in a new WndProc handler, and process WM_ERASEBKGND messages.  I thought, claiming I’d erased it would do the job, but that made no difference.

So, I actually implemented code to fill the clip region with the WINDOW_COLOR brush, and that did fix the problem.  No more black edges, but that was all a little bit unsatisfactory.  What I really wanted to do was register my own class for the WPF window, and set the background brush correctly to match the window.

That doesn’t appear to be possible, but it is possible to PInvoke and call SetClassLong on the background brush.

So my preferred solution is set the class background brush, and watch WPF draw it correctly. It appears that WPF creates a new class for each application so this should be safe, though if it’s not the previously described solution would definitely work.

Back to the Desktop and WPF, no WinRT for me

I’ve been working pretty much full time lately on Windows Phone 7 apps, and making pretty much no money.  As I have a house and a family, this isn’t a situation that can continue for very much longer.  One of our previous WPF apps is doing quite well on the desktop, and makes more in a single sale than I make in a month of Windows Phone App sales and ad revenue.

I have considered porting some of my apps to WinRT for Windows 8, but based on what Josh Smith says here I think my gut feel that it is a lot of work, and it will probably come with more pain than gain for me is probably spot on.

I was one of first into WP7 development, and the theory was that we’d be discoverable and get early sales.  What happened instead is that others got in on the bandwagon, and produced similar apps, so in my view, there’s no benefit to showing my hand early. 

If it really is that good of an environment, it shouldn’t be that hard to port the apps to the new platform.