Search code examples
c++windowsvisual-studio-2017wininet

Using std::filesystem output as LPCWSTR


I'm making a program which recursively lists all files in a certain directory and uploads each file separately to an FTP server using WinINet. The problem I'm encountering is using filesystem::path::filename in the FtpPutFile() function because a LPCWSTR is needed. Whats the best and easiest way to convert it (or somehow use it as is)?

    std::string path = "C:\\Programs";
    for (const auto & entry : std::experimental::filesystem::recursive_directory_iterator(path))
        FtpPutFile(hIConnect, entry.path().filename(), entry.path().filename(), FTP_TRANSFER_TYPE_BINARY, 0);

The error I get is: no suitable conversion function from "const std::experimental::filesystem::v1::path" to "LPCWSTR" exists

EDIT: Here is a solution that worked for me, by following Lightness solution:

    std::string path = "C:\\Programs";
    for (const auto & entry : std::experimental::filesystem::recursive_directory_iterator(path))
        FtpPutFile(hIConnect, entry.path().wstring().c_str(), entry.path().filename().wstring().c_str(), FTP_TRANSFER_TYPE_BINARY, 0);

Solution

  • LPCWSTR is Microsoft's obfuscation of the const wchar_t* type, and filesystem paths conveniently have a wstring() member function. As you may recall, C++ strings give you access to their character buffer, too, via c_str().

    So, entry.path().filename().wstring().c_str() is a LPCWSTR you can use (ugh!). Be careful to use that immediately, or store the result of wstring() somewhere for as long as you need the LPCWSTR to survive, because wstring() returns by value and you don't want a dangling pointer.

    // Untested, but a logical adaptation of your code
    const std::string path = "C:\\Programs";
    std::experimental::filesystem::recursive_directory_iterator it(path);
    for (const auto& entry : it)
    {
        const std::wstring filename = entry.path().filename().wstring();
    
        FtpPutFile(
           hIConnect,
           filename.c_str(),
           filename.c_str(),
           FTP_TRANSFER_TYPE_BINARY,
           0
        );
    }