views:

259

answers:

3

Here is the scenario. I have an application which writes a configuration file in its directory (user.dir). When the user cannot write to that directory due to UAC issues, I would like to change that to write to user.home/.appname/. The problem is that Windows really lies to my application and writes to user.dir which is in the Program Files directory, but although it allows the write and the read (even after restarts) it doesn't store it there, it stores it in a hidden directory (the home directory/AppData/Local/VirtualStore/Program Files/appname), making it hard/impossible for the user to find if they want to edit the file.

However, I don't want to just change my application to write to user.home and be done with it because some users run the application off of a USB drive, at which point I want to use user.dir if it is available, because it would not be helpful to leave things around the user home directory in that scenario (on a guest computer).

So after that rather long winded background, is there a way from java to know if the local directory is really truly directly writable from Java or if vista is going to instead virtualize the directory writes to another location?

A: 

After writing your file, can you just check that the file suddenly appeared in virtualized directory? I'd do a small "touch" file at app start to set a global boolean variable userUserHome.

Vladimir Dyuzhev
A: 
  1. Prepare a native EXE that loads the JVM in process (java.exe does this but you will need your own).

  2. Add a manifest file (or in RC data) that specifies UAC as invoker.

  3. Try writing to the folder to see if it works.

Or decide this is too much work and use a config file.

Joshua
Indeed too much work for this case, but wouldn't that trigger a request for elevation to the user?
Yishai
@Yishai: No, the manifest for RunAsInvoker makes sure you do not.
Joshua
+1  A: 

This problem occurs if the Java executable is not marked as Vista compatible (using the manifest). The current release from Sun is marked as compatible. So the simplest solution is to use the latest release. This means that now neither files nor registry entries are virtualised.


Edit from author of OP:

Java 6 Update 10 (bug 6722527) added the manifest to the relevant files. Bug 6737858 addressed further issues, and is recorded as fixed in Release 12, although it is not in the release notes. For JDK 1.5, the installer was fixed in Update 11, however there will be no manifests added to the exe by Sun. You can add one yourself by putting the manifest file in the same directory as the exe if it is important enough.

Mark Thornton
Thanks Mark, do you know of any place that documents the specific releases that are marked Vista compatable? Specifically I'm looking if any of the 1.5 releases are (maybe the last one from November 3rd), or is it only 1.6?
Yishai
No I don't know of any such documentation. There are even related bugs which haven't been closed.
Mark Thornton
As best as I can determine, the manifest was added in 1.6 update 10.
Mark Thornton