Windows HOME - SHGet(已知)FolderPath

时间:2012-02-27 10:40:36

标签: c++ windows winapi

我正在尝试编写一个函数来获取与Windows相当的HOME。我的C技能很生疏,所以不要介意我的示例代码不能编译。我正在尝试在Windows Vista及更高版本上使用SHGetKnownFolderPath,在Server 2003及更早版本上使用SHGetFolderPath。由于我希望遇到运行Windows XP的用户(因为它仍然是Windows的第一个部署版本),我将避免在符号表中引用SHGetKnownFolderPath(因为这将导致二进制文件甚至不会在XP上加载)。我知道LoadLibrary()shell32和GetProcAddress()从那里开始,但我做函数指针的技巧至少可以说是垃圾。

当我编写功能并且难以处理时,我将它们隔离到一个单独的示例文件中。我到目前为止的破碎例子是:

#include <windows.h>
#include <stdio.h>

// Pointerizing this Vista-and-later call for XP/2000 compat, etc.
typedef HRESULT (WINAPI* lpSHGetKnownFolderPath)(
    REFKNOWNFOLDERID rfid,
    DWORD dwFlags,
    HANDLE hToken,
    PWSTR *ppszPath
) lpSHGetKnownFolderPath;

int main(int argc, char *argv[])
{
    // SHGet(Known)FolderPath() method.
    HMODULE hndl_shell32;
    lpSHGetKnownFolderPath pSHGetKnownFolderPath;
    hndl_shell32 = LoadLibrary("shell32");
    pSHGetKnownFolderPath = GetProcAddress(hndl_shell32, "SHGetKnownFolderPathW");
    if(pSHGetKnownFolderPath != NULL) {

    } else {

    }

}

我的问题是:知道我做错了,我该如何做到这一点?关于如何在未来正确行事的解释将不胜感激。感谢。

3 个答案:

答案 0 :(得分:7)

这是一个小应用程序,显示如何使用LoadLibrary()GetProcAddress()以及评论中提供的建议:

#include <windows.h>
#include <stdio.h>
#include <shlobj.h>

/* The name of the function pointer type is
    'lpSHGetKnownFolderPath', no need for
    additional token after ')'. */
typedef HRESULT (WINAPI* lpSHGetKnownFolderPath)(
    REFKNOWNFOLDERID rfid,
    DWORD dwFlags,
    HANDLE hToken,
    PWSTR *ppszPath
);

int main()
{
    HMODULE hndl_shell32;
    lpSHGetKnownFolderPath pSHGetKnownFolderPath;

    /* Always check the return value of LoadLibrary. */
    hndl_shell32 = LoadLibrary("shell32");
    if (NULL != hndl_shell32)
    {
        /* There is no 'SHGetKnownFolderPathW()'.
           You need to cast return value of 'GetProcAddress()'. */
        pSHGetKnownFolderPath = (lpSHGetKnownFolderPath)
            GetProcAddress(hndl_shell32, "SHGetKnownFolderPath");

        if(pSHGetKnownFolderPath != NULL)
        {
            PWSTR user_dir = 0;
            if (SUCCEEDED(pSHGetKnownFolderPath(
                            FOLDERID_Profile,
                            0,
                            NULL,
                            &user_dir)))
            {
                /* Use 'user_dir' - remember to:

                     CoTaskMemFree(user_dir);

                   when no longer required.
                 */
            }
        }
        else
        {
            fprintf(stderr, "Failed to locate function: %d\n",
                GetLastError());
        }

        /* Always match LoadLibrary with FreeLibrary.
           If FreeLibrary() results in the shell32.dll
           being unloaded 'pSHGetKnownFolderPath' is
           no longer valid.
         */
        FreeLibrary(hndl_shell32);
    }
    else
    {
        fprintf(stderr, "Failed to load shell32.dll: %d\n", GetLastError());
    }

    return 0;
}

这是在Windows XP上编译的。

Windows XP上的输出:

  

找不到功能:127

其中127表示无法找到指定的过程。

Windows Vista上的输出:

  

C:\用户\管理员

答案 1 :(得分:1)

您始终可以使用getenv("HOMEDRIVE")getenv("HOMEPATH")并连接结果。

std::string home = std::string(getenv("HOMEDRIVE")) + getenv("HOMEPATH");

答案 2 :(得分:0)

等效于HOME的Windows为USERPROFILE。它就像在Linux中一样是一个普通的环境变量。您可以进行以下调用以检索它:

char *profilepath = getenv("USERPROFILE");