Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get SHGetKnownFolderPath() function working

I am having troubles using SHGetKnownFolderPath() function. I am getting the following error message: Type error in argument 1 to 'SHGetKnownFolderPath'; expected 'const struct _GUID *' but found 'struct _GUID'.

In the KnowFolders.h we have the following relevant definitions:

#define DEFINE_KNOWN_FOLDER(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
    EXTERN_C const GUID name
...
DEFINE_KNOWN_FOLDER(FOLDERID_ProgramFiles,0x905e63b6,0xc1bf,0x494e,0xb2,0x9c,0x65,0xb7,0x32,0xd3,0xd2,0x1a);

I am using Pelles C compiler .

This is my sample code:

#include <windows.h>
#include <wchar.h>
#include <KnownFolders.h>
#include <shlobj.h>

int wmain(int argc, wchar_t **argv) {

    PWSTR path = NULL;

    HRESULT hr = SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, NULL, &path);    

    if (SUCCEEDED(hr)){

        wprintf(L"%ls", path);
    }

    CoTaskMemFree(path);

    return 0;
}

How to fix this error message?

EDIT I have found code examples with SHGetKnownFolderPath(); all of them execute the function without the pointer. For instance:

hr = SHGetKnownFolderPath(FOLDERID_Public, 0, NULL, &pszPath);
if (SUCCEEDED(hr))
{
    wprintf(L"FOLDERID_Public: %s\n", pszPath);
    CoTaskMemFree(pszPath);
}

CppShellKnownFolders.cpp

like image 247
Jan Bodnar Avatar asked Dec 09 '22 00:12

Jan Bodnar


1 Answers

With the help from the comments of Jonathan Potter, I was able to correct the example.

The problem was very subtle. The following code line looks like C, but it is actually C++.

HRESULT hr = SHGetKnownFolderPath(FOLDERID_Documents, 0, NULL, &path);

The SHGetKnownFolderPath() function has the following prototype:

STDAPI SHGetKnownFolderPath(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);

Its first argument is REFKNOWNFOLDERID.

In the shtypes.h file we find the following:

#ifdef __cplusplus
#define REFKNOWNFOLDERID const KNOWNFOLDERID &
#else
#define REFKNOWNFOLDERID const KNOWNFOLDERID * /*__MIDL_CONST*/
#endif /* __cplusplus */

This means, that in C++ REFKNOWNFOLDERID is a reference and in C it is a pointer. As a consequence, we do not need an ampersand in C++ code for the first parameter. In Visual C++ C code is often compiled with C++ and the distinction between the languages is often blurred.

The second issue, the Unresolved external symbol 'FOLDERID_ProgramFiles'. error. error is fixed by adding #include <initguid.h> before #include <ShlObj.h>. The reason is explained in this article.

So the following code compiles on Pelles C.

#include <windows.h>
#include <initguid.h>
#include <KnownFolders.h>
#include <ShlObj.h>
#include <wchar.h>

int wmain(void) {

    PWSTR path = NULL;

    HRESULT hr = SHGetKnownFolderPath(&FOLDERID_Documents, 0, NULL, &path);

    if (SUCCEEDED(hr)) {
        wprintf(L"%ls\n", path);
    }

    CoTaskMemFree(path);

    return 0;
}
like image 119
Jan Bodnar Avatar answered Dec 15 '22 00:12

Jan Bodnar