Z0q
Z0q

Reputation: 1893

How to get %AppData% path as std::string?

I've read that one can use SHGetSpecialFolderPath(); to get the AppData path. However, it returns a TCHAR array. I need to have an std::string.

How can it be converted to an std::string?

Update

I've read that it is possible to use getenv("APPDATA"), but that it is not available in Windows XP. I want to support Windows XP - Windows 10.

Upvotes: 1

Views: 3741

Answers (4)

Cheers and hth. - Alf
Cheers and hth. - Alf

Reputation: 145429

The T type means that SHGetSpecialFolderPath is a pair of functions:

  • SHGetSpecialFolderPathA for Windows ANSI encoded char based text, and

  • SHGetSpecialFolderPathW for UTF-16 encoded wchar_t based text, Windows' “Unicode”.

The ANSI variant is just a wrapper for the Unicode variant, and it can not logically produce a correct path in all cases.

But this is what you need to use for char based data.


An alternative is to use the wide variant of the function, and use whatever machinery that you're comfortable with to convert the wide text result to a byte-oriented char based encoding of your choice, e.g. UTF-8.

Note that UTF-8 strings can't be used directly to open files etc. via the Windows API, so this approach involves even more conversion just to use the string.


However, I recommend switching over to wide text, in Windows.

For this, define the macro symbol UNICODE before including <windows.h>.

That's also the default in a Visual Studio project.

Upvotes: 2

MikeCAT
MikeCAT

Reputation: 75062

You should use SHGetSpecialFolderPathA() to have the function deal with ANSI characters explicitly.

Then, just convert the array of char to std::string as usual.

/* to have MinGW declare SHGetSpecialFolderPathA() */
#if !defined(_WIN32_IE) || _WIN32_IE < 0x0400
#undef _WIN32_IE
#define _WIN32_IE 0x0400
#endif

#include <shlobj.h>
#include <string>

std::string getPath(int csidl) {
    char out[MAX_PATH];
    if (SHGetSpecialFolderPathA(NULL, out, csidl, 0)) {
        return out;
    } else {
        return "";
    }
}

Upvotes: 1

Dendi Suhubdy
Dendi Suhubdy

Reputation: 3225

Typedef String as either std::string or std::wstring depending on your compilation configuration. The following code might be useful:

#ifndef UNICODE  
  typedef std::string String; 
#else
  typedef std::wstring String; 
#endif

Upvotes: 0

IOB Toolkit Team
IOB Toolkit Team

Reputation: 161

https://msdn.microsoft.com/en-gb/library/windows/desktop/dd374131%28v=vs.85%29.aspx

#ifdef UNICODE
    typedef wchar_t TCHAR;
#else
    typedef unsigned char TCHAR;
#endif

Basically you can can convert this array to std::wstring. Converting to std::string is straightforward with std::wstring_convert.

http://en.cppreference.com/w/cpp/locale/wstring_convert

Upvotes: 1

Related Questions