Why do files get placed in "C:\Users\<username>AppData\Local\VirtualStore\Program Files(x86)"?

I recently updated my Visual Basic 6.0 application and now include an exe.manifest file to prevent UAC Virtualization. After applying this update, some users can't find their data files (Access MDB files) and after a system search they end up finding it in C:\Users\<username>AppData\Local\VirtualStore\Program Files(x86).

What is this folder area for and how/when do files get moved to this area? How do we prevent it? I'm hoping now that my application uses a .manifest this won't happen again. Did the files get placed there before the manifest was used as the application was being placed in UAC Virtualization?


Solution 1:

An application that is not running with raised privileges should does not have access to the Program Files and Program Files (x86) directories. This is good for safety. In addition, in most cases when a developer tells his program to save data in the Program Files folder, for example, program settings, he has completely forgotten that program settings should be a per-user thing! That is, every user on the local computer should be able to use the program without affecting the other users. In other words, a well-behaved application should instead save its settings in the

C:\Users\<User Name>\AppData\Local\<Manufacturer>\<Product>\<Product Version> 

directory.

For instance, my AlgoSim software writes to

C:\Users\<User Name>\AppData\Local\Rejbrand\AlgoSim\2.0

Of course, the

C:\Users\<User Name>\AppData\Local\

path must be looked-up dynamically at runtime. Use

SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0, SHGFP_TYPE_CURRENT, @path);

for this.

Ever since Windows Vista, applications that are not running with raised privileges that try to write to the Program Files (or Program Files (x86)) folder will in fact write to the VirtualStore folder, unknowingly. Microsoft thought that this would be better than a program failure (caused by the access restriction). And indeed, thanks to this, most old programs that save their settings in the Program Files folder will continue to work with Windows Vista+, and each user will get her own settings, as a bonus, even though the original software manufacturer did not think of this.

You can use a manifest to tell Windows that your application is aware of VirtualStore and that Windows should not change any paths during runtime. But if you really want to be able to write to the Program Files folder, then I think that you have to run the application with raised privileges, every time, which is inadvisable in general.

The details on how to create manifests to make your program display the UAC prompt on each execution, and how to disable VirtualStore, have been addressed at several previous Stack Overflow questions. Feel free to use the search box!

Solution 2:

My guess is that your manifest says asInvoker, and that your app tries to write to Program Files. When the users ran it without a manifest, it wrote to the virtual store for Program Files, which is the path where they found some files later. When they ran with a manifest, it failed to write at all (with access denied) but either your application hid the error from them, or they didn't understand the error so they didn't mention it to you.

Short term fix - use a requireAdministrator manifest. This will irritate the users but the writes will succeed. Longer term fix - don't write to ProgramFiles. There are better per-user options, like AppData.