[SOLVED] (C++) My CopyFile() function doesn't work, but my paths and parameter types seem to be ok

Issue

I’m trying to write a function which copies the current running program’s .exe file to the Windows’s Startup folder. I’m completely new to this, so don’t be mad at me 😀

I have this piece of code:

void startup()
{
    std::string str = GetClipboardText();
    wchar_t buffer[MAX_PATH];
    GetModuleFileName(NULL, buffer, MAX_PATH);
    std::wstring stemp = std::wstring(str.begin(), str.end());
    LPCWSTR sw = stemp.c_str();
    int a;
    if (CopyFile(buffer, sw, true))
        a = 1;
    else a = 0;
}

Here I get the paths and save them in buffer (like D:\source\Project2\Debug\Project2.exe, I checked if that’s the right path, if I paste what buffer contains in File Explorer, it runs the right .exe file) and sw (like C:\Users\user\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup). But it doesn’t copy, and the simple if check shows a=0.

I thought it might not has the permission to copy files into the Startup folder, but it doesn’t work with other "test" folders as well.

Solution

CopyFile() copies from one file to another file. So both lpExistingFileName and lpNewFileName parameters must be given file paths, but you are passing in a folder path for the lpNewFileName parameter. That will not work.

Had you followed what the documentation says:

If the function fails, the return value is zero. To get extended error information, call GetLastError.

GetLastError() would have told you that your inputs where unacceptable.

So, to fix this, you will have to extract and concatenate the source filename onto your destination folder path, eg:

std::wstring GetClipboardUnicodeText()
{
    // get clipboard text using CF_UNICODETEXT, return as std::wstring...
}

void startup()
{
    std::wstring str = GetClipboardUnicodeText();

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

    WCHAR dest[MAX_PATH] = {};
    PathCombineW(dest, str.c_str(), PathFindFileNameW(src));

    int a = CopyFileW(src, dest, TRUE);
}

Otherwise, to copy a file into a folder without specifying a target filename, use SHFileOperation() instead, eg:

void startup()
{
    // note the extra null terminator!
    std::wstring dest = GetClipboardUnicodeText() + L'\0';

    // note +1 for the extra null terminator!
    WCHAR src[MAX_PATH+1] = {};
    GetModuleFileNameW(NULL, src, MAX_PATH);

    SHFILEOPSTRUCTW op = {};
    op.wFunc = FO_COPY;
    op.pFrom = src;
    op.pTo = dest.c_str();
    op.fFlags = FOF_FILESONLY;

    int a = SHFileOperationW(&op);
}

Answered By – Remy Lebeau

Answer Checked By – Katrina (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *