53

Possible Duplicate:
What is the cross-platform way of obtaining the path to the local application data directory?

I'm looking for a way to get the location of the local application data folder, which is a special Windows folder, in Java. Unfortunately, the following only works for English versions of Windows XP with default settings:

System.getProperty("user.home") + "\\Local Settings\\Application Data"

What I'd like to have is something like this in .NET:

System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)

Is there a way to do it without having to call SHGetSpecialFolderLocation of the Windows Shell API?

Community
  • 1
  • 1
smf68
  • 988
  • 1
  • 9
  • 16
  • The same question but cross-platform: http://stackoverflow.com/questions/11113974/what-is-the-cross-platform-way-of-obtaining-the-path-to-the-local-application-da – Mechanical snail Jan 14 '13 at 22:46
  • What do you need it for? There are more Java-y ways to store persistent information, such as the Preferences API or using the temporary file mechanisms (possibly combined :) – Christoffer Jul 29 '09 at 09:21
  • My application needs to read configuration data from another application (which I cannot move) that's stored in this special folder. – smf68 Jul 29 '09 at 19:02
  • Ah, then it's more clear why you want this. – Christoffer Jul 30 '09 at 07:14

7 Answers7

84
System.getenv("APPDATA")

(there seems to be no env variable for the "Local Settings" folder, but this will give you the 'Application Data' folder)

Ryan Fernandes
  • 8,238
  • 7
  • 36
  • 53
  • 4
    just understand that the APPDATA environmental variable is a windows only construct, but the app in question is java, so it should ostensibly be cross platform. – Chii Jul 29 '09 at 11:02
  • 28
    The questioner is asking for something which is "a special Windows folder". So I'm not convinced this needs to be cross platform – Brian Agnew Jul 29 '09 at 11:23
  • 1
    It doesn't need to be cross platform. I'm just looking for a way to get the location of this special Windows folder for the current user. – smf68 Jul 29 '09 at 19:04
  • About the APPDATA environment variable: I know about that one, but need the local Application Data folder which doesn't always seem to be inside the Application Data folder. Just noticed there is a LOCALAPPDATA, I'll check if that's the right one and if it's always available. – smf68 Jul 29 '09 at 19:07
  • 6
    Just checked, LOCALAPPDATA is not available in Windows XP, unfortunately. – smf68 Jul 30 '09 at 08:05
  • 8
    Note that the APPDATA environment variable is not available in applications that has been started via "Run As ..." – Robert Dec 09 '10 at 08:47
  • APPDATA is not available? – gumuruh Oct 18 '20 at 15:33
  • FWIW this returns null on macOS Big Sur. – Saket Jul 03 '21 at 19:49
  • what if we want it to be applicable for all users...? is there any solution for it instead of specific 1 single user location? – gumuruh Apr 21 '23 at 04:26
22

what about the following

String dataFolder = System.getenv("LOCALAPPDATA");

I have a situation where this is NOT under "user.home"

ashutosh raina
  • 9,228
  • 12
  • 44
  • 80
Charles Godwin
  • 339
  • 3
  • 2
13

Reading the "Shell Folders" registry key is deprecated starting from Windows 95. The registry key contains a note saying "!Do not use this registry key. Use the SHGetFolderPath or SHGetKnownFolderPath instead." I had to find this out the hard way on a Vista system where all the keys were missing except for the warning note.

This related stackoverflow answer solves this problem on Windows using JNA, which is the solution I'm currently using.

Community
  • 1
  • 1
Frederik
  • 14,156
  • 10
  • 45
  • 53
  • 7
    The key was deprecated starting from Windows 95. the "Shell Folders" key exists solely to permit four programs written in 1994 to continue running on the RTM version of Windows 95 http://blogs.msdn.com/b/oldnewthing/archive/2003/11/03/55532.aspx – Sheng Jiang 蒋晟 Jun 30 '12 at 14:58
3

I would like to use the following two ways:

String dataFolder = System.getenv("APPDATA");

String dataFolder = System.getProperty("user.home") + "\\Local Settings\\ApplicationData";
user
  • 6,567
  • 18
  • 58
  • 85
jianinz
  • 163
  • 1
  • 11
1

You could read the path from the registry: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\* where * is one of those Keys:

  • Local AppData (C:\Documents and Settings\USER\Local Settings\Application Data)
  • Local Settings (C:\Documents and Settings\USER\Local Settings)
  • AppData (C:\Documents and Settings\USER\Application Data)

Note: Those example paths are from an english Windows XP installation

Gregor
  • 1,691
  • 1
  • 20
  • 22
  • 1
    I'm now reading it with the SWT Win32 Extension (http://feeling.sourceforge.net/) and it works fine. Thanks! – smf68 Jul 31 '09 at 07:02
  • 10
    [Do not read the registry key directly](http://blogs.msdn.com/b/oldnewthing/archive/2003/11/03/55532.aspx). It does not do what you think it does. – Raymond Chen Feb 11 '12 at 15:02
  • And in fact, though the *Local Settings* actual folder is still [kind of there](https://web.archive.org/web/20120819162958/http://msdn.microsoft.com/en-us/library/bb756982.aspx) for backwards compatibility, the registry value is no more at all since Vista. – mirh Nov 07 '20 at 10:47
0

I resolved in this way

private static File getAppData(){
    ProcessBuilder builder = new ProcessBuilder(new String[]{"cmd", "/C echo %APPDATA%"});

    BufferedReader br = null;
    try {
        Process start = builder.start();
        br = new BufferedReader(new InputStreamReader(start.getInputStream()));
        String path = br.readLine();
        // TODO HACK do not know why but I get an extra '"' at the end
        if(path.endsWith("\"")){
            path = path.substring(0, path.length()-1);
        }
        return new File(path.trim());


    } catch (IOException ex) {
        Logger.getLogger(Util.class.getName()).log(Level.SEVERE, "Cannot get Application Data Folder", ex);
    } finally {
        if(br != null){
            try {
                br.close();
            } catch (IOException ex) {
                Logger.getLogger(Util.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    return null;
}
-1

It would be possible to spawn a process to query the key and then parse the output:

REG QUERY "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders" /v "Local AppData"

Honestly, though, I'd be more inclined to use JNA or JNI.

McDowell
  • 107,573
  • 31
  • 204
  • 267
  • I also think that the way to go would be calling the native function of Windows, as it should be the one which does not change in the near future. – Gregor Jul 30 '09 at 10:47