# Wednesday, 14 July 2010

Here is something I've been asked more than once, and seen asked on various forums as well. I'll paraphrase rather than quote one specific asker:

We have an application written 15 years ago that's been working flawlessly. But when we run it on Windows 7, the users can't find the files it writes. Worse, there are no error messages, so they think they've saved the files, but when they go to C:\Program Files\MyGreatSoftware\UserExports - the files aren't there! 

Often, the question trails off into a rant about how sneaky and mean Windows 7 is to somehow prevent access to Program Files but not give error messages. The rant might also include a paean to how amazing the lost files were and how many workyears of productivity have been lost now that these files cannot be found, and why this means you can't trust Windows to do something as simple as write a file to the hard drive. Sometimes, the asker has established that this is related to UAC and they are recommending everyone turn it off to avoid this disaster. I thought I would make some less drastic suggestions.

First, your files are not lost. A few people know this, but they then claim the files are almost impossible to find and no end user will ever find them. Let's tackle this one first because if you know this trick you may be able to get by without changing anything else about your application. Tell the user to go to the place they expect to find the files, say C:\Program Files\MyGreatSoftware\UserExports. Then have them look in the toolbar for a button that says Compatibility Files. Click it. Ta-da!

Ok, now the next thing is, why the heck are your files being written there? Because you are trying to write to a protected area and you don't have a manifest. You have several things you can do about this, and they boil down to two main things:

One, don't write to a protected area. You can get this by installing somewhere other than Program Files (not a good idea) or by changing the application to write to a better place. Two, get permission to write to the protected area. This means running as administrator. Train the users to right-click Run As Administrator when they run the app, or train them to set the Compatibility Settings for the app (neither very likely) or ship the application with a manifest that includes requireAdministrator. Now matter how you arrange this second thing, your users are not going to like agreeing to the UAC prompt every darn time. So really, that brings you back to number one, don't write to a protected area. Use AppData instead - there's a simple function call to get that path on any machine (including older XP machines) and you'll be in fine shape. If you think your users can't find that, and the files are for the users and not just some internal settings, then use a folder under Documents - again, there's a simple function call that will get you the path.

If virtualization makes you nuts - that your code thinks it's writing to C:\Program Files\whatever but really it's writing somewhere else, and the OS is cheerfully lying to it and saying all the writes succeeded - then put a manifest on your app. Doesn't matter whether it's requireAdministrator or asInvoker. Doesn't matter whether it's embedded (VS will embed them for you from 2008 on easily, and there are tools that do just manifest adding) or just a file of XML in the same folder as the exe. Once the app has a manifest, virtualization stops. Of course this may mean the users get all kinds of Access Denied errors that they don't like. Now you see why virtualization was invented.

Should you rely on it? No. For one thing, it may go away in some future version of Windows. And it goes away when you add a manifest, which for many people happened when they migrated to a new version of Visual Studio. What you should do is understand it, including how to find the virtual store, so it doesn't make you quite so crazy.

Now go turn UAC back on,

Kate

Wednesday, 14 July 2010 09:25:20 (Eastern Daylight Time, UTC-04:00)  #