nick
nick

Reputation: 25

Getting path to the desktop for current user in C using WinAPI

I'm very new to WinAPI programming. I was wondering how I could get the path of the user's Desktop and then print out the full path to the console. This is my current code:

TCHAR* path = 0;
HRESULT result = SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
if (result == S_OK)
{
    printf("%s\n", path);
}
CoTaskMemFree(path)

It does find the path, but it prints out "C" for the path rather than the entire path with slashes. What am I missing?

Thanks!

Upvotes: 0

Views: 356

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 598134

SHGetKnownFolderPath() outputs a wchar_t* pointer, not a TCHAR* pointer. There is no ANSI version of SHGetKnownFolderPath(), so you should not be using TCHAR at all in this situation. In fact, your code will not compile unless UNICODE is defined so TCHAR maps to wchar_t.

The reason you only see the 1st character is because you are passing a wchar_t* where a char* is expected. On Windows, wchar_t is 16-bit, and so wchar_t* strings are encoded in UCS-2 or UTF-16LE. All ASCII characters in UCS-2/UTF-16LE have their high 8 bits set to 0. Your use of printf() is expecting a null terminated char* string, so the high 0x00 byte of the 1st wchar_t character gets misinterpreted as a null terminator.

To do what you want, you need to print out the returned path as-is as a wide string, not as a (misinterpreted) narrow string.

You could use %S with printf(), eg:

PWSTR path;
if (SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path) == S_OK)
{
    printf("%S\n", path);
    CoTaskMemFree(path);
}

But this is not portable across compilers. You should use %s with wprintf() instead:

PWSTR path;
if (SHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path) == S_OK)
{
    wprintf(L"%s\n", path);
    CoTaskMemFree(path);
}

Upvotes: 3

Anders
Anders

Reputation: 101764

It prints a single character because you tried to print a wide string as a narrow string. You probably have UNICODE/_UNICODE defined so TCHAR is WCHAR.

If you insist on using TCHAR you should use the correct printing function from tchar.h:

_tprintf(_T("%s\n"), path);

Otherwise you can use the wide version:

wprintf(L"%s\n", path);

Or the worst solution, convert the string to a narrow codepage string:

printf("%ls\n", path); // This might not display all Unicode characters correctly

Upvotes: 0

Related Questions