Как передать SHGetKnownFolderPath вывод в CopyFile в C ++? - PullRequest
0 голосов
/ 01 ноября 2019

Я хочу получить FOLDERID_ProgramFiles на SHGetKnownFolderPath и скопировать текущий запущенный файл в него с помощью этого кода:

char ModuleFileName[24];
GetModuleFileName(NULL, ModuleFileName, MAX_PATH) ;

PWSTR path = NULL;
SHGetKnownFolderPath(FOLDERID_ProgramFiles,0,NULL,&path);

CopyFile(ModuleFileName,path,FALSE);

Но у меня не было блокировки, потому что PWSTR - это wchar_t* иCopyFile нужно const char*, я пытался поставить звездочку перед Path и преобразовать ее, используя функцию wcstombs, но без блокировки!

Как я могу это исправить?

PS: У меня есть эта ошибка:

error: cannot convert ‘PWSTR {aka wchar_t*}’ to ‘LPCSTR {aka const char*}’ for argument ‘2’ to ‘WINBOOL CopyFileA(LPCSTR, LPCSTR, WINBOOL)’

И я должен упомянуть, что я использую компилятор Mingw g++, так что вывод этих переменных немного сложен с использованием wprintf(L"%ls\n",[STR] );, и я получаю много плохогосимволы на выходе.

Ответы [ 2 ]

3 голосов
/ 01 ноября 2019

Используйте * W варианты API-функций (GetModuleFileNameW, CopyFileW и т. Д.) И используйте символы wchar_t, а не char.

Другой вариант - взять возвращенный путь из SHGetKnownFolderPath и использовать WideCharToMultiByte для перевода. путь к символам, но первый способ намного предпочтительнее (например, он не зависит от символов, соответствующих языку пользователя).

1 голос
/ 02 ноября 2019

Вы вызываете версию ANSI CopyFile() и передаете ей строку Unicode во втором параметре. Вот почему вы получаете ошибку компилятора. Вместо этого используйте Unicode-версию GetModuleFileName() и CopyFile().

Кроме того, ваш ModuleFileName имеет размер только 24 char с, но вы говорите GetModuleFileNameW(), что он MAX_PATH (260) символов в размере.

Кроме того, CopyFile() ожидает пути к файлам, а не к папкам. Вам нужно извлечь имя файла из ModuleFileName и добавить его в конец path при передаче его второму параметру.

Попробуйте что-то более похожее на это:

WCHAR ModuleFileName[MAX_PATH] = {};
GetModuleFileNameW(NULL, ModuleFileName, MAX_PATH);

PWSTR path = NULL;
SHGetKnownFolderPath(FOLDERID_ProgramFiles, 0, NULL, &path);

WCHAR NewFileName[MAX_PATH] = {};
PathCombineW(NewFileName, path, PathFindFileNameW(ModuleFileName));

CoTaskMemFree(path);

CopyFileW(ModuleFileName, NewFileName, FALSE);

ТамЕсть другие альтернативы PathCombine(), например:

WCHAR NewFileName[PATHCCH_MAX_CCH] = {};
PathCchCombine(NewFileName, PATHCCH_MAX_CCH, path, PathFindFileNameW(ModuleFileName));
// use NewFileName as needed...
PWSTR NewFileName = NULL;
PathAllocCombine(path, PathFindFileNameW(ModuleFileName), 0, &NewFileName);
// use NewFileName as needed...
LocalFree(NewFileName);
#include <string>
std::wstring NewFileName(path);
if (NewFileName.back() != L'\\')
    NewFileName += L'\\';
NewFileName += PathFindFileNameW(ModuleFileName);
// use NewFileName as needed...
#include <filesystem>
std::wstring NewFileName = (std::filesystem::path(path) / PathFindFileNameW(ModuleFileName)).wstring();
// use NewFileName as needed...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...