Since I installed Windows 8 I've noticed that a number of my applications appear to have problems opening URLs. That is when I click on a link inside of a Windows application, either nothing happens or there's an error that occurs. It's happening both to my own applications and a host of Windows applications I'm running. At first I thought this was an issue with my default browser (Chrome) but after switching the default browser to a few others and experimenting a bit I noticed that the errors occur - oddly enough - only when I run an application as an Administrator. I also tried switching to FireFox and Opera as my default browser and saw exactly the same behavior.

The scenario for this is a bit bizarre:

  • Running on Windows 8
  • Call Process.Start() (or ShellExecute() in Win32 API) with a URL or an HTML file
  • Run 'As Administrator' (works fine under non-elevated user account!) or with UAC off
  • A browser other than Internet Explorer is set as your Default Web Browser

Talk about a weird scenario: Something that doesn't work when you run as an Administrator which is supposed to have rights to everything on the system! Instead running under an Admin account - either elevated with a User Account Control prompt or even when running as a full Administrator fails.

It appears that this problem does not occur for everyone, but when I looked for a solution to this, I saw quite a few posts in relation to this with no clear resolutions. I have three Windows 8 machines running here in the office and all three of them showed this behavior.

Lest you think this is just a programmer's problem - this can affect any software running on your system that needs to run under administrative rights.

Try it out

Now, in order for this next example to fail, any browser but Internet Explorer has to be your default browser and even then it may not fail depending on how you installed your browser.

To see if this is a problem create a small Console application and call Process.Start() with a URL in it:

namespace Win8ShellBugConsole
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Launching Url...");
            Process.Start("http://microsoft.com");
            Console.Write("Press any key to continue...");
            Console.ReadKey();

            Console.WriteLine("\r\n\r\nLaunching image...");
            Process.Start(Path.GetFullPath(@"..\..\sailbig.jpg"));
            Console.Write("Press any key to continue...");
            Console.ReadKey();
        }
    }
}

Compile this code. Then execute the code from Explorer (not from Visual Studio because that may change the permissions).

If you simply run the EXE and you're not running as an administrator, you'll see the Web page pop up in the browser as well as the image loading.

Now run the same thing with Run As Administrator:

RunAsAdministratorExplorer

Now when you run it you get a nice error when Process.Start() is fired:

AdminCrash

The same happens if you are running with User Account Control off altogether - ie. you are running as a full admin account.

Now if you comment out the URL in the code above and just fire the image display - that works just fine in any user mode. As does opening any other local file type or even starting a new EXE locally (ie. Process.Start("c:\windows\notepad.exe"). All that works, EXCEPT for URLs.

The code above uses Process.Start() in .NET but the same happens in Win32 Applications that use the ShellExecute API. In some of my older Fox apps ShellExecute returns an error code of 31 - which is No Shell Association found.

What's the Deal?

It turns out the problem has to do with the way browsers are registering themselves on Windows. Internet Explorer - being a built-in application in Windows 8 - apparently does this correctly, but other browsers possibly don't or at least didn't at the time I installed them. So even Chrome, which continually updates itself, has a recent version that apparently has this registration issue fixed, I was unable to simply set IE as my default browser then use Chrome to 'Set as Default Browser'. It still didn't work.

Neither did using the Set Program Associations dialog which lets you assign what extensions are mapped to by a given application.

Associations

Each application provides a set of extension/moniker mappings that it supports and this dialog lets you associate them on a system wide basis. This also did not work for Chrome or any of the other browsers at first. However, after repeated retries here eventually I did manage to get FireFox to work, but not any of the others.

What Works? Reinstall the Browser

In the end I decided on the hard core pull the plug solution: Totally uninstall and re-install Chrome in this case. And lo and behold, after reinstall everything was working fine. Now even removing the association for Chrome, switching to IE as the default browser and then back to Chrome works. But, even though the version of Chrome I was running before uninstalling and reinstalling is the same as I'm running now after the reinstall now it works.

Of course I had to find out the hard way, before Richard commented with a note regarding what the issue is with Chrome at least:

http://code.google.com/p/chromium/issues/detail?id=156400

As expected the issue is a registration issue - with keys not being registered at the machine level. Reading this I'm still not sure why this should be a problem - an elevated account still runs under the same user account (ie. I'm still rickstrahl even if I Run As Administrator), so why shouldn't an app be able to read my Current User registry hive? And also that doesn't quite explain why if I register the extensions using Run As Administrator in Chrome when using Set as Default Browser). But in the end it works…

Epilog - Chrome

It's now a few days later and I'm still seeing problems although now the issues clearly have to do with Chrome, rather than Windows.

So, Chrome actually has two different installers - one for regular user install and administrative install. The Admin install installs Chrome for all users and requires admin privileges where the regular installer does not. This seems to make sense now: When using the regular installer none of the HKLM keys can be set, so most likely this is the real cause of the problems I saw previously.

However, once I installed the admin install (how that happened I don't know because I didn't explicitly realize that I was) I ended up with all sorts of other problems. Chrome seemed to continually lose its settings, forcing me to log in with my Google account frequently, losing some of my installed plugins, and occasionally throwing up error dialogs on ShellExecute links that the browser about to be launched was the admin version that couldn't be launched from the current user environment. In other words the Admin version had lots of problems for me.

After some more headscratching I uninstalled completely again, then reinstalled under the non-Admin installer. Now finally I seem to have a stable Chrome install that's keeping my settings and configuration as well as properly launching with ShellExecute.

On another machine, however, I followed the basic uninstall Chrome and reinstall chrome as a regular user, and on that machine everything now also seems to work. I'm still not sure how this works since the regular user install does not prompt for the administrative UAC dialog, but yet somehow manages to write the HKLM keys that ShellExecute needs to launch the browser under elevated rights. It's all very puzzling, but at least resolved.

No doubt this is all an artifact of Chrome and other browsers wanting to play nice in Windows 8 and RT and judging from the failures I saw from all the browsers, this is proving harder than expected to get right. I suspect we're going to see a lot more of this kind of craziness in configurations and associations in applications in the future and I'm not looking forward to having to fight that sort of thing in our own apps. Thanks Windows 8 - for making a process that was already a PITA even more convoluted.

Not so fast

Did I mention that I freaking hate UAC precisely because of this kind of bullshit. You can never tell exactly what account your app is running under, and apparently apps also have a hard time trying to put data into the right place that works for both scenarios. And as my recent post on using Windows Live accounts shows it's yet another level of abstraction on top of the underlying system identity that can cause all sort of small side effect headaches like this.

Hopefully, most of you are skirting this issue altogether - having installed more recent versions of your favorite browsers. If not, hopefully this post will take you straight to reinstallation to fix this annoying issue.