Compiled Python writing to Program Files

2.6k views Asked by At

I have written a program that creates several sqlite3 database temp files. In development, I just stored them in a folder in the same folder with the src package. I overlooked the fact that you need admin access when the code is compiled and run from Program Files. (I know temp files in Program Files is bad practice, too)

The issue is: there is no issue. I don't get an IOError: [Errno 13] Permission denied: or warning of any kind. Furthermore, if I go to the folder where there should be temp files, there aren't any.

If I add a line like

print os.path.exists(r'C:\Program Files (x86)\ProgramName\temp\filename.db')

or

print os.listdir(r'C:\Program Files (x86)\ProgramName\temp')

to my program, it shows that the files are there, but the don't exist in explorer, cmd or idle. They do, however, show up in cygwin.

I've shown hidden file/folders and they don't show up.

If I copy the temp folder using explorer, the files do not tag along. If I copy the folder using cygwin, they do. They also become visible to explorer.

Has anyone else experienced this or know what's going on?

1

There are 1 answers

0
abarnert On BEST ANSWER

You're right that you should not be writing into your Program Files directory. And really, that's the solution to your program: change your script to stop doing that.

But if you want to know where your files are going, when you try to write to Program Files (on Vista or later, with UAC not disabled):

  • If you're being run as Administrator, and not with XP/2003 or earlier emulation, the files get written directly to the path specified.
  • If your app fits the magic triggers to look like an installer program (see here for the Vista docs), the files get written directly to the path specified.
  • If your app is in Microsoft's compatibility database, the paths are mapped through the entires in the compatibility database (which doesn't seem to be documented anywhere).
  • Otherwise, your paths are passed through UAC file virtualization, which means attempts to write to protected directories like Program Files end up somewhere under the user's app data directory—to your program, it looks like Program Files, but to, say, Explorer or cmd.exe it doesn't.

I believe the location is not guaranteed nor documented, and at one point it moved from the app's app data directory for the user to a per-app directory under a different special app data directory for the user, but at least on one Windows 7 machine it's this:

C:\Users\horriblyUnpythonic\AppData\Local\VirtualStore\Program Files (x86)\ProgramName\temp\filename.db


There are a lot of blog posts out there if you search for "UAC file virtualization". Most of them are written from the point of view of building custom installers, like this one (because, as you can imagine, this is a serious problem for a custom installer), but they mostly all get the ideas across, and provide lots of details, and add links for further reading.

If you only experienced this problem migrating from Vista to 7, or from 32-bit Vista to 64-bit Vista, this Microsoft blog is the only place I've seen that got that far into the details… except that the images and most of the discussion seem to have disappeared at some point.