Search code examples
c++windowsrenamemovefile

MoveFile function convert syntax / how to use MoveFile with variables to rename folders


This part of my programm tries to rename all folders and subfolders. All other functionality is in another code, here I'm just renaming a single folder by providing a path.

Since rename doesnt seem to work for me I tried using MoveFile.

I understand that it requires an LPCTSTR value.. but the paths I am currently providing (casted from std::filesystem::directory_entry -> std::filesystem::path) -> LPCTSTR) aren't accepted.

I'm getting that I'm not casting it the right way and I probably have to provide it with an "L" in front of the variable, but I can't find nor figure out the syntax.

enter image description here

bool renameFolder(std::string confirmStr3, auto dirEntry, std::string& replacedStr, std::string& insertStr, int& foldername_replacements)
{
    std::string path_string = dirEntry.path().string();

    path_string = std::filesystem::path(path_string).filename().string();

    replace_all(path_string, replacedStr, insertStr);

    path_string = getFolderPath(std::filesystem::path(dirEntry).string()) + "\\" + path_string;
 

    if (std::filesystem::path(dirEntry) != std::filesystem::path(path_string))
        foldername_replacements++;


    //std::filesystem::rename(std::filesystem::path(dirEntry), std::filesystem::path(path_string));
    MoveFile(LPCTSTR(std::filesystem::path(dirEntry)), LPCTSTR(std::filesystem::path(path_string)));

}

Solution

  • You can't type cast a std::filesystem::path object directly to a character pointer. That is exactly what the error message is telling you. And you can't use the L prefix with variables, only with compile-time literals.

    You need to call the path::c_str() method instead, eg:

    MoveFileW(std::filesystem::path(dirEntry).c_str(), std::filesystem::path(path_string).c_str());
    

    Or, call the path::(w)string() method, and then call c_str() on the returned std::(w)string object, eg:

    MoveFileW(std::filesystem::path(dirEntry).wstring().c_str(), std::filesystem::path(path_string).wstring().c_str());
    

    That being said, std::rename() is likely to be implemented on Windows using MoveFile/Ex() internally, so this is a possible XY Problem. std::rename() is the preferred solution, so you should focus your efforts on figuring out why it is not working for you.


    UPDATE:

    On a side note, the code you have shown makes repetitive use of temporary std::filesystem::path objects that are unnecessary. Try simplifying the code, like this:

    bool renameFolder(std::string confirmStr3, auto dirEntry, std::string& replacedStr, std::string& insertStr, int& foldername_replacements)
    {
        auto dirEntryPath = dirEntry.path();
        auto file_name = dirEntryPath.filename().string();
    
        replace_all(file_name, replacedStr, insertStr);
    
        auto newDirEntryPath = dirEntryPath / file_name;    
        if (dirEntryPath != newDirEntryPath)
        {
            ++foldername_replacements;
    
            //std::filesystem::rename(dirEntryPath, newDirEntryPath);
            MoveFileW(dirEntryPath.c_str(), newDirEntryPath.c_str());
        }
    }