Howdy,
I'm trying to write a program that will copy files from one destination to another. After some reasearch it was suggested that I use SHFileOperation, and SHFILEOPSTRUCT.

I'm trying to set the struct members accordance with MSDN, however, I run into a problem with pTo and pFrom.
The error given by Intellisense is "a value of type "const char *" cannot be assigned to an entity of type "LPCWSTR""

What should I do?
I've tried using a std::wstring instead, and that didn't work. I don't really understand the what the LPCWSTR is, and how to actually use it.

Code is below.
I want to be able to use the program to back up data from one server location to another - should I be doing this another way?
Other reference: Here

class Backup {
    //Private Members
    std::string dateLastRun;
    std::ifstream inFile;
    std::ofstream outFile;
    std::string sourcePath;
    std::string destPath;

    //Private Functions
    bool runBackup(std::string source, std::string dest);
    void writeToLogfile(std::string sysBeingBackedUp, std::string fileName);

public:
    //Public Members
    std::string currDate;
    std::vector<std::string> errorMessages;
    std::string sysBeingBackedUp;

    //Public Functions
    bool isError();
    bool isModified();
    void checkDateLastRun();
    std::string getDateLastRun();
    void setDateLastRun();
    void setCurrDate();
    void getSourcePath();
    void getDestPath();
    void setSourcePath();
    void setDestPath();
}

//Responsible for running backup program
bool Backup::runBackup(std::string source, std::string dest)
{
    //LPCWSTR source = _T(sourcePath);
    destPath = dest;
    sourcePath = source;

    //SHFile Struct
    SHFILEOPSTRUCT fileStruct = { 0 }; 
    //fileStruct.hwnd = hwnd; 
    fileStruct.wFunc = FO_COPY;
    fileStruct.pTo = destPath.c_str(); //Here is where the errors are
    fileStruct.pFrom = sourcePath.c_str(); 
    fileStruct.fFlags = FOF_NOCONFIRMMKDIR;//, FOF_SIMPLEPROGRESS;
    //...
}

Another way to do it is to call CopyFile() instead of SHFileOperation(), its a lot easier to use.

To answer your question, you have to call a conversion function such as one of these to convert char* to wchar_t*

Edited 4 Years Ago by Ancient Dragon

The reason I avoided CopyFile() was that it required the destination directories to exist already, and wouldn't create new ones. Maybe I misunderstood it, but I thought that would not save a new directory if I created a new directory in the source.

I was hoping that SHFileOperation() would go through the directories recursively and create them if necessary in the destination, should the need arise.

Thanks for the link though, I will give that a shot.

It looks like SHFileOperation() does create the directories

Copy and Move operations can specify destination directories that do not exist. In those cases, the system attempts to create them and normally displays a dialog box to ask the user if they want to create the new directory. To suppress this dialog box and have the directories created silently, set the FOF_NOCONFIRMMKDIR flag in fFlags.

This should work.

bool Backup::runBackup(std::string source, std::string dest)
{
    char destPath[MAX_PATH] = {0};
    char sourcePath[MAX_PATH] = {0};

    // Note: source and destination paths must be double null terminated
    errno_t error = strcpy_s(destPath, dest.c_str() );
    if (0 != error)
    {
        // handle error
        return FALSE;
    }

    error = strcpy_s(sourcePath, source.c_str() );
    if (0 != error)
    {
        // handle error
        return FALSE;
    }

    //SHFile Struct
    SHFILEOPSTRUCTA fileStruct = { 0 }; 
    fileStruct.wFunc = FO_COPY;
    fileStruct.pTo = destPath;
    fileStruct.pFrom = sourcePath; 
    fileStruct.fFlags = FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION;
    //...
    int iret = SHFileOperationA(&fileStruct);

    return (iret == 0 && fileStruct.fAnyOperationsAborted == FALSE);
}

You can also replace the strcpy_s(...) with the string copy member function.

    char destPath[MAX_PATH] = {0};
    char sourcePath[MAX_PATH] = {0};

    dest.copy(destPath, dest.length(), 0);
    source.copy(sourcePath, source.length(), 0);
This article has been dead for over six months. Start a new discussion instead.