Windows HOME - SHGet (Известно) FolderPath - PullRequest
1 голос
/ 27 февраля 2012

Я пытаюсь написать функцию, чтобы получить Windows-эквивалент HOME.Мои навыки C ржавые, поэтому не против того, что мой пример кода не компилируется.Я пытаюсь использовать SHGetKnownFolderPath в Windows Vista и более поздних версиях и SHGetFolderPath в Server 2003 и более ранних версиях.Поскольку я ожидаю встретить пользователей, работающих под управлением 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 ]

7 голосов
/ 27 февраля 2012

Вот небольшое приложение, которое показывает, как использовать 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: \ Users \ admin

1 голос
/ 27 февраля 2012

Вы всегда можете использовать getenv("HOMEDRIVE") и getenv("HOMEPATH") и объединять результаты.

std::string home = std::string(getenv("HOMEDRIVE")) + getenv("HOMEPATH");
0 голосов
/ 27 февраля 2012

Windows-эквивалент HOME равен USERPROFILE. Это обычная переменная среды, как в Linux. Вы можете сделать следующий вызов, чтобы получить его:

char *profilepath = getenv("USERPROFILE");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...