Reputation: 684
I want to get FOLDERID_ProgramFiles
by SHGetKnownFolderPath
and copy current running file to it by this code:
char ModuleFileName[24];
GetModuleFileName(NULL, ModuleFileName, MAX_PATH) ;
PWSTR path = NULL;
SHGetKnownFolderPath(FOLDERID_ProgramFiles,0,NULL,&path);
CopyFile(ModuleFileName,path,FALSE);
But i had no lock because , PWSTR
is a wchar_t*
and CopyFile
needs const char*
, I have tried to put star before Path
and convert it by using wcstombs
function but no lock!
How can i fix it?
PS: I've got this error:
error: cannot convert ‘PWSTR {aka wchar_t*}’ to ‘LPCSTR {aka const char*}’ for argument ‘2’ to ‘WINBOOL CopyFileA(LPCSTR, LPCSTR, WINBOOL)’
And i should mention I'am using Mingw g++
compiler so printing out these variable is a bit challenging by using wprintf(L"%ls\n",[STR] );
and i get a lot of bad chars in output.
Upvotes: 0
Views: 457
Reputation: 596041
You are calling the ANSI version of CopyFile()
and passing it a Unicode string in the second parameter. That is why you are getting a compiler error. Use the Unicode version of GetModuleFileName()
and CopyFile()
instead.
Also, your ModuleFileName
is only 24 char
s in size, but you are telling GetModuleFileNameW()
that it is MAX_PATH
(260) chars in size.
Also, CopyFile()
expects file paths, not folder paths. You need to extract the filename from ModuleFileName
and append it to the end of path
when passing it to the 2nd parameter.
Try something more like this:
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);
There are other alternatives to PathCombine()
, eg:
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...
Upvotes: 2
Reputation: 15162
Use the *W variants of the API functions (GetModuleFileNameW, CopyFileW etc) and use wchar_t characters rather than char throughout.
Your other option would be to take the returned path from SHGetKnownFolderPath and use WideCharToMultiByte to translate the path to chars but the first way is much preferable (it doesn't dpend on the characters matching the user locale for example).
Upvotes: 4