views:

584

answers:

4

Hi,

when running a Java application as service with the user 'LocalService', the temp directory ("java.io.tmpdir") points to 'c:/windows/temp' (for example).

Running a Java application normally gives 'c:/documents and settings/user/local settings/temp' instead.

How can I determine the user independent temp folder 'c:/windows/temp' when my application runs normally?

Thanks and greetings, GHad

A: 

Java system property java.io.tmpdir just point to system variable %TMP%. For normal user %TMP% points to %HOMEPATH%\temp, for other account - can be another path. You can try to use %SYSTEMROOT%\temp instead of java.io.tmpdir - %SYSTEMROOT% points to directory, where windows is installed.

St.Shadow
I would really like to use this method, but what if a user changed that value under System/Extended/Environment Variables? That would brake the approach. Thanks anyway
GHad
When you decide to work with system variables - you should believe, that your app will be used or by noob user, that do not touch system variables at all, or by advanced users, which know what they do. Otherwise you will get hell :)
St.Shadow
Yeah, I know it's hell, but this one must work under any thinkable circumstances...
GHad
A: 

I'm not sure there is a 'clean' way of doing this.

In this situation, I would probably create a directory specifically for the Java app and refer to it in a properties file.

Phill Sacre
See comment Lastnico for details
GHad
A: 

You can simply create your own temporary folder, add use the deleteOnExit() method to ensure this folder will be removed at the exit of your application.

Lastnico
Thanks, but I need to find files from other programes that are running as service. My Java app may or may not run as service but must find those files either way
GHad
+1  A: 

You could:

  • as suggested by St Shadow, rely on some environment variable such as %WINDIR% or %SYSTEMROOT%, append "\temp" on the end, and use this.
  • or pass in this value to your app as a variable using a commandline argument to the JVM, e.g.

    -Dmytempdir=%WINDIR%\temp

As you mention, the user could change the values of either of these variables using System -> Environment Variables, but I don't think they'd have any affect on the system until a reboot anyway (...?).

Or...

  • try and read the value from the registry using some nasty use of java.util.prefs.Preferences or something -- On my machine it looks like the value you're after is held in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\TEMP.

This would likely have to be quite messy and I don't know if the Preferences class will get you access to the key you'd need to read. Again, there's not much you could do about the user changing the registry value either, if they really wanted to, but again I doubt it would have any affect until after a reboot, and would probably have an impact on more than just your app.

Cheers, --J

John
«they'd have any affect on the system until a reboot anyway» - wrong. They take affect to any new process in system.
St.Shadow
True - they'd be visible to new processes that chose to read the environment variables, but I know whether Windows itself would pick up the changes until after a reboot? And I don't know how this affects the environment for processes running as a service...
John
Processes, running as services, work the same way: after restarting of them (not home system) they pick up new variables. During running they can not pick up new variables (*by default*). Of course, you can write service, which will check for changes at variables by timer or something else.
St.Shadow
*home mean hole :)
St.Shadow
Thanks for the suggestion. The registry way is the way to go. I have a solution right now, I'll be posting tomorrow. BTW: With hacked Preferences, this cannot work as the reg key is type REG_EXPAND_SZ and the hacked Preferences is only able to read REG_SZ. This is implemented on the native side afaik.
GHad
Solution is to read the registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\TEM with a VBScript and write the value to a temporary file that is then read by Java. VBScript works for XP, Vista and Win7 without UAC interference. The Windows Scripting Host is available out of the box for all this versions, so you won't run into compatibility issues. After reading I split up the path and look for %...% environment varables that are the determined via System.getenv(). As it is save to cache the value, speed does only matter on first invocation. Greetz
GHad