4

Hey, I'm a bit new to C++ and am writing a simple program. My program will be using some folders in


Windows 7 path: C:\Users\%username%\Appdata\Local...

Windows XP path: C:\Documents and Settings\%username%\Local Settings\Application Data...

Unix: /home/%username%/.hiddenfolder/...


now the problem is windows. In my header file, I can do a nice

#ifdef _WIN32

to differentiate from windows and unix versions of the program, but during runtime I need to find if the user is useing XP or Vista/7 to set a correct path. Is there a standard way of doing this?

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Ignoreme
  • 193
  • 1
  • 2
  • 11
  • I believe you should just be using whatever win32 API call it is that gets the current user's directory(I know there is one) and wrapping that in `#ifdef _WIN32` – Earlz Feb 14 '11 at 05:21
  • One method would be to check if a specific file that is exclusive to Vista exists... But there should be another way. I wonder, where are the System Properties stored? – Mateen Ulhaq Feb 14 '11 at 05:23
  • 1
    Within each OS this will require a special method of doing this -- e.g. look for "how does one determine the current users local application data directory in windows?" In general there are already such solutions *per* particular operating systems and variations. –  Feb 14 '11 at 05:23
  • For instance do a search on SO for "windows application data path" which will return results like: http://stackoverflow.com/questions/2899013/how-do-i-get-the-application-data-path-in-windows-using-c –  Feb 14 '11 at 05:25

4 Answers4

8

You don't need OS version at all.

On *nixes (well, on Linux and OSX for sure, but should be on others too) you can use HOME environment variable. On Windows, you must (yes, must, because paths can be remapped/localised and hard-coding them is nice way to having more work than necessary) use SHGetFolderPath function (it's marked as deprecated, but it's not going anywhere any time soon, and newer SHGetKnownFolderPath is >=Vista), e.g.

TCHAR buffer[MAX_PATH];
HRESULT res = SHGetFolderPath(
    NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, buffer
);

if (SUCCEEDED(res)) {
    // ...
}
Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224
  • using this code, i only get 1 compile error. `char* get_appdata(){ char *path; char szPath[256]; if(SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, 256))) { path = szPath; return path; } }` ERROR: 'SHGFP_TYPE_CURRENT' was not declared in this scope. Does anyone know what SHGFP_TYPE_CURRENT is and how to use it? – Ignoreme Feb 14 '11 at 06:57
  • @Kronos: are you including shlobj.h? Also, last parameter of this function is the pointer to buffer, not integer. – Cat Plus Plus Feb 14 '11 at 09:27
  • yes, i'm including shlobj.h in the program. char* get_appdata() is just a function. I had a `#ifdef _WIN32 #include #include #define get_path() get_appdata() #else #include #define get_path() get_ENV(HOME) #endif` My problem is SHGFP_TYPE_CURRENT, not sure what it is or what it does. I can't find any references on it either. – Ignoreme Feb 14 '11 at 22:14
  • @Kronos: read `SHGetFolderPath` docs. http://msdn.microsoft.com/en-us/library/bb762181%28VS.85%29.aspx – Cat Plus Plus Feb 14 '11 at 22:21
  • @PiotrLegnica, I've read it. It says its a DWORD which i believe is the same as an unsigned long, however, it doesn't what the default values are. I can't say unsigned long type_current = 1; b/c i don't know what to put to get type current instead of default. – Ignoreme Feb 15 '11 at 02:17
  • @PiotrLegnica This is the way it is right now, it's kind of hacked together, but I can't see a better way of doing it. .cpp: [link](http://www.filefactory.com/file/b56a331/n/test.cpp) .exe: [link](http://www.filefactory.com/file/b56a332/n/test.exe) Compiled with g++ from gcc. Do you have any suggestions on how to improve it? – Ignoreme Feb 15 '11 at 02:35
1

Version detection is neither necessary nor sufficient, since these settings can be changed from their defaults. Use SHGetKnownFolderPath(FOLDERID_RoamingAppData, ...).

Marcelo Cantos
  • 181,030
  • 38
  • 327
  • 365
0

Those values are environment variables. You're looking at either %appdata% or $HOME/.app (not sure the MAC method, they may have "packages"). Since you're going to have to know what your target is at compile time (win vs. other), you can know which environment variable to look for. Then use getenv to fetch the value.

Edward Strange
  • 40,307
  • 7
  • 73
  • 125
0

you can use WINVER to detect windows version

  • 1
    No. That's what you use to tell the compiler what minimum version of Windows you require, so it knows not to complain when you call Vista-only functions. – MSalters Feb 14 '11 at 09:42