SHFileOperationW为什么会创建文件夹而不是移动文件?

huangapple go评论72阅读模式
英文:

Why does SHFileOperationW create folder instead of move file?

问题

我已经根据您提供的代码进行了翻译。以下是翻译好的部分:

我已经创建了一个基于`SHFileOperationW`的自定义“Move”函数,如下所示:

int MoveItem(string strSourcePath, string strDestinationDirectory, string strNewName, bool bAllowOverwrite, bool bCreateDestinationDirectoryIfNotExist)
{
    int intPositionOfLastSlash;
    int intResult = 0;

    SHFILEOPSTRUCTW sfosMove;

    string strNewPath;
    string strOldName;

    wchar_t a_wcNewPath[MAX_PATH] = {0};
    wchar_t a_wcSourcePath[MAX_PATH] = {0};

    wstring wsNewPath;
    wstring wsSourcePath;

    if((IsFileExist(strSourcePath) == false) && (IsFolderExist(strSourcePath) == false))
    {
        intResult = 0x7C;
    }

    else
    {
        if(IsFolderExist(strDestinationDirectory) == false)
        {
            if(bCreateDestinationDirectoryIfNotExist == false)
            {
                intResult = 0x7C;
            }
        }
    }

    if(intResult == 0)
    {
        intPositionOfLastSlash = strSourcePath.find_last_of("\\");
        strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);

        if(strNewName == "")
        {
            strNewPath = strDestinationDirectory + "\\" + strOldName;
        }

        else
        {
            strNewPath = strDestinationDirectory + "\\" + strNewName;
        }

        if(bAllowOverwrite == false)
        {
            if(IsFileExist(strNewPath) == true)
            {
                intResult = 0x7E;
            }

            else if(IsFolderExist(strNewPath) == true)
            {
                intResult = 0x80;
            }
        }
    }

    if(intResult == 0)
    {
        /*- Source Path -*/
        wsSourcePath = Utf8StringToWstring(strSourcePath);

        StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

        CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"
我已经创建了一个基于`SHFileOperationW`的自定义“Move”函数,如下所示:

int MoveItem(string strSourcePath, string strDestinationDirectory, string strNewName, bool bAllowOverwrite, bool bCreateDestinationDirectoryIfNotExist)
{
    int intPositionOfLastSlash;
    int intResult = 0;

    SHFILEOPSTRUCTW sfosMove;

    string strNewPath;
    string strOldName;

    wchar_t a_wcNewPath[MAX_PATH] = {0};
    wchar_t a_wcSourcePath[MAX_PATH] = {0};

    wstring wsNewPath;
    wstring wsSourcePath;

    if((IsFileExist(strSourcePath) == false) && (IsFolderExist(strSourcePath) == false))
    {
        intResult = 0x7C;
    }

    else
    {
        if(IsFolderExist(strDestinationDirectory) == false)
        {
            if(bCreateDestinationDirectoryIfNotExist == false)
            {
                intResult = 0x7C;
            }
        }
    }

    if(intResult == 0)
    {
        intPositionOfLastSlash = strSourcePath.find_last_of("\\");
        strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);

        if(strNewName == "")
        {
            strNewPath = strDestinationDirectory + "\\" + strOldName;
        }

        else
        {
            strNewPath = strDestinationDirectory + "\\" + strNewName;
        }

        if(bAllowOverwrite == false)
        {
            if(IsFileExist(strNewPath) == true)
            {
                intResult = 0x7E;
            }

            else if(IsFolderExist(strNewPath) == true)
            {
                intResult = 0x80;
            }
        }
    }

    if(intResult == 0)
    {
        /*- Source Path -*/
        wsSourcePath = Utf8StringToWstring(strSourcePath);

        StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

        CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);
        /*---------------*/

        /*- New Path -*/
        wsNewPath = Utf8StringToWstring(strNewPath);

        StrCpyW(a_wcNewPath, wsNewPath.c_str());

        CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L"\0\0", 2);
        /*-------------------------*/

        /*- Move Item -*/
        sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
        sfosMove.pFrom = a_wcSourcePath;
        sfosMove.pTo = a_wcNewPath;
        sfosMove.wFunc = FO_MOVE;

        intResult = SHFileOperationW(&sfosMove);
        /*-------------*/
    }

    return intResult;
}
我已经创建了一个基于`SHFileOperationW`的自定义“Move”函数,如下所示:

int MoveItem(string strSourcePath, string strDestinationDirectory, string strNewName, bool bAllowOverwrite, bool bCreateDestinationDirectoryIfNotExist)
{
    int intPositionOfLastSlash;
    int intResult = 0;

    SHFILEOPSTRUCTW sfosMove;

    string strNewPath;
    string strOldName;

    wchar_t a_wcNewPath[MAX_PATH] = {0};
    wchar_t a_wcSourcePath[MAX_PATH] = {0};

    wstring wsNewPath;
    wstring wsSourcePath;

    if((IsFileExist(strSourcePath) == false) && (IsFolderExist(strSourcePath) == false))
    {
        intResult = 0x7C;
    }

    else
    {
        if(IsFolderExist(strDestinationDirectory) == false)
        {
            if(bCreateDestinationDirectoryIfNotExist == false)
            {
                intResult = 0x7C;
            }
        }
    }

    if(intResult == 0)
    {
        intPositionOfLastSlash = strSourcePath.find_last_of("\\");
        strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);

        if(strNewName == "")
        {
            strNewPath = strDestinationDirectory + "\\" + strOldName;
        }

        else
        {
            strNewPath = strDestinationDirectory + "\\" + strNewName;
        }

        if(bAllowOverwrite == false)
        {
            if(IsFileExist(strNewPath) == true)
            {
                intResult = 0x7E;
            }

            else if(IsFolderExist(strNewPath) == true)
            {
                intResult = 0x80;
            }
        }
    }

    if(intResult == 0)
    {
        /*- Source Path -*/
        wsSourcePath = Utf8StringToWstring(strSourcePath);

        StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

        CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);
        /*---------------*/

        /*- New Path -*/
        wsNewPath = Utf8StringToWstring(strNewPath);

        StrCpyW(a_wcNewPath, wsNewPath.c_str());

        CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L"\0\0", 2);
        /*-------------------------*/

        /*- Move Item -*/
        sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
        sfosMove.pFrom = a_wcSourcePath;
        sfosMove.pTo = a_wcNewPath;
        sfosMove.wFunc = FO_MOVE;

        intResult = SHFileOperationW(&sfosMove);
        /*-------------*/
    }

    return intResult;
}
", 2);
/*---------------*/ /*- New Path -*/ wsNewPath = Utf8StringToWstring(strNewPath); StrCpyW(a_wcNewPath, wsNewPath.c_str()); CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L"
我已经创建了一个基于`SHFileOperationW`的自定义“Move”函数,如下所示:

int MoveItem(string strSourcePath, string strDestinationDirectory, string strNewName, bool bAllowOverwrite, bool bCreateDestinationDirectoryIfNotExist)
{
    int intPositionOfLastSlash;
    int intResult = 0;

    SHFILEOPSTRUCTW sfosMove;

    string strNewPath;
    string strOldName;

    wchar_t a_wcNewPath[MAX_PATH] = {0};
    wchar_t a_wcSourcePath[MAX_PATH] = {0};

    wstring wsNewPath;
    wstring wsSourcePath;

    if((IsFileExist(strSourcePath) == false) && (IsFolderExist(strSourcePath) == false))
    {
        intResult = 0x7C;
    }

    else
    {
        if(IsFolderExist(strDestinationDirectory) == false)
        {
            if(bCreateDestinationDirectoryIfNotExist == false)
            {
                intResult = 0x7C;
            }
        }
    }

    if(intResult == 0)
    {
        intPositionOfLastSlash = strSourcePath.find_last_of("\\");
        strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);

        if(strNewName == "")
        {
            strNewPath = strDestinationDirectory + "\\" + strOldName;
        }

        else
        {
            strNewPath = strDestinationDirectory + "\\" + strNewName;
        }

        if(bAllowOverwrite == false)
        {
            if(IsFileExist(strNewPath) == true)
            {
                intResult = 0x7E;
            }

            else if(IsFolderExist(strNewPath) == true)
            {
                intResult = 0x80;
            }
        }
    }

    if(intResult == 0)
    {
        /*- Source Path -*/
        wsSourcePath = Utf8StringToWstring(strSourcePath);

        StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

        CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);
        /*---------------*/

        /*- New Path -*/
        wsNewPath = Utf8StringToWstring(strNewPath);

        StrCpyW(a_wcNewPath, wsNewPath.c_str());

        CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L"\0\0", 2);
        /*-------------------------*/

        /*- Move Item -*/
        sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
        sfosMove.pFrom = a_wcSourcePath;
        sfosMove.pTo = a_wcNewPath;
        sfosMove.wFunc = FO_MOVE;

        intResult = SHFileOperationW(&sfosMove);
        /*-------------*/
    }

    return intResult;
}
我已经创建了一个基于`SHFileOperationW`的自定义“Move”函数,如下所示:

int MoveItem(string strSourcePath, string strDestinationDirectory, string strNewName, bool bAllowOverwrite, bool bCreateDestinationDirectoryIfNotExist)
{
    int intPositionOfLastSlash;
    int intResult = 0;

    SHFILEOPSTRUCTW sfosMove;

    string strNewPath;
    string strOldName;

    wchar_t a_wcNewPath[MAX_PATH] = {0};
    wchar_t a_wcSourcePath[MAX_PATH] = {0};

    wstring wsNewPath;
    wstring wsSourcePath;

    if((IsFileExist(strSourcePath) == false) && (IsFolderExist(strSourcePath) == false))
    {
        intResult = 0x7C;
    }

    else
    {
        if(IsFolderExist(strDestinationDirectory) == false)
        {
            if(bCreateDestinationDirectoryIfNotExist == false)
            {
                intResult = 0x7C;
            }
        }
    }

    if(intResult == 0)
    {
        intPositionOfLastSlash = strSourcePath.find_last_of("\\");
        strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);

        if(strNewName == "")
        {
            strNewPath = strDestinationDirectory + "\\" + strOldName;
        }

        else
        {
            strNewPath = strDestinationDirectory + "\\" + strNewName;
        }

        if(bAllowOverwrite == false)
        {
            if(IsFileExist(strNewPath) == true)
            {
                intResult = 0x7E;
            }

            else if(IsFolderExist(strNewPath) == true)
            {
                intResult = 0x80;
            }
        }
    }

    if(intResult == 0)
    {
        /*- Source Path -*/
        wsSourcePath = Utf8StringToWstring(strSourcePath);

        StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

        CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);
        /*---------------*/

        /*- New Path -*/
        wsNewPath = Utf8StringToWstring(strNewPath);

        StrCpyW(a_wcNewPath, wsNewPath.c_str());

        CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L"\0\0", 2);
        /*-------------------------*/

        /*- Move Item -*/
        sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
        sfosMove.pFrom = a_wcSourcePath;
        sfosMove.pTo = a_wcNewPath;
        sfosMove.wFunc = FO_MOVE;

        intResult = SHFileOperationW(&sfosMove);
        /*-------------*/
    }

    return intResult;
}
", 2);
/*-------------------------*/ /*- Move Item -*/ sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; sfosMove.pFrom = a_wcSourcePath; sfosMove.pTo = a_wcNewPath; sfosMove.wFunc = FO_MOVE; intResult = SHFileOperationW(&sfosMove); /*-------------*/ } return intResult; }

但问题是,当我重复使用此函数时,只有第一个文件被移动。该函数会创建带有文件名的文件夹。

例如:

第一个文件:abc.txt(该文件已移动。)第二个文件:def.txt(此文件未移动。函数创建了一个名为“def.txt”的文件夹)

示例用法引发了问题:

// "D:"驱动器中已存在"example_folder"文件夹。
int intResult;

intResult = MoveItem("C:\\ProgramData\\abc.txt", "D:\\example_folder", "", true, false);

if(intResult == 0)
{
     intResult = MoveItem("C:\\ProgramData\\def.txt", "D:\\example_folder", "", true, false);     
}   

希望这可以帮助您理解您的代码。如果您有任何其他问题,请随时提出。

<details>
<summary>英文:</summary>

I have created own &quot;Move&quot; function based on `SHFileOperationW` like this:

int MoveItem(string strSourcePath, string strDestinationDirectory, string strNewName, bool bAllowOverwrite, bool bCreateDestinationDirectoryIfNotExist)
{
int intPositionOfLastSlash;
int intResult = 0;

SHFILEOPSTRUCTW sfosMove;

string strNewPath;
string strOldName;

wchar_t a_wcNewPath[MAX_PATH] = {0};
wchar_t a_wcSourcePath[MAX_PATH] = {0};

wstring wsNewPath;
wstring wsSourcePath;

if((IsFileExist(strSourcePath) == false) &amp;&amp; (IsFolderExist(strSourcePath) == false))
{
    intResult = 0x7C;
}

else
{
    if(IsFolderExist(strDestinationDirectory) == false)
    {
        if(bCreateDestinationDirectoryIfNotExist == false)
        {
            intResult = 0x7C;
        }
    }
}

if(intResult == 0)
{
    intPositionOfLastSlash = strSourcePath.find_last_of(&quot;\\&quot;);
    strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);

    if(strNewName == &quot;&quot;)
    {
        strNewPath = strDestinationDirectory + &quot;\\&quot; + strOldName;
    }

    else
    {
        strNewPath = strDestinationDirectory + &quot;\\&quot; + strNewName;
    }

    if(bAllowOverwrite == false)
    {
        if(IsFileExist(strNewPath) == true)
        {
            intResult = 0x7E;
        }

        else if(IsFolderExist(strNewPath) == true)
        {
            intResult = 0x80;
        }
    }
}

if(intResult == 0)
{
    /*- Source Path -*/
    wsSourcePath = Utf8StringToWstring(strSourcePath);

    StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

    CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L&quot;
SHFILEOPSTRUCTW sfosMove;
string strNewPath;
string strOldName;
wchar_t a_wcNewPath[MAX_PATH] = {0};
wchar_t a_wcSourcePath[MAX_PATH] = {0};
wstring wsNewPath;
wstring wsSourcePath;
if((IsFileExist(strSourcePath) == false) &amp;&amp; (IsFolderExist(strSourcePath) == false))
{
intResult = 0x7C;
}
else
{
if(IsFolderExist(strDestinationDirectory) == false)
{
if(bCreateDestinationDirectoryIfNotExist == false)
{
intResult = 0x7C;
}
}
}
if(intResult == 0)
{
intPositionOfLastSlash = strSourcePath.find_last_of(&quot;\\&quot;);
strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);
if(strNewName == &quot;&quot;)
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strOldName;
}
else
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strNewName;
}
if(bAllowOverwrite == false)
{
if(IsFileExist(strNewPath) == true)
{
intResult = 0x7E;
}
else if(IsFolderExist(strNewPath) == true)
{
intResult = 0x80;
}
}
}
if(intResult == 0)
{
/*- Source Path -*/
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L&quot;\0\0&quot;, 2);
/*---------------*/
/*- New Path -*/
wsNewPath = Utf8StringToWstring(strNewPath);
StrCpyW(a_wcNewPath, wsNewPath.c_str());
CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L&quot;\0\0&quot;, 2);
/*-------------------------*/
/*- Move Item -*/
sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
sfosMove.pFrom = a_wcSourcePath;
sfosMove.pTo = a_wcNewPath;
sfosMove.wFunc = FO_MOVE;
intResult = SHFileOperationW(&amp;sfosMove);
/*-------------*/
}
return intResult;
SHFILEOPSTRUCTW sfosMove;
string strNewPath;
string strOldName;
wchar_t a_wcNewPath[MAX_PATH] = {0};
wchar_t a_wcSourcePath[MAX_PATH] = {0};
wstring wsNewPath;
wstring wsSourcePath;
if((IsFileExist(strSourcePath) == false) &amp;&amp; (IsFolderExist(strSourcePath) == false))
{
intResult = 0x7C;
}
else
{
if(IsFolderExist(strDestinationDirectory) == false)
{
if(bCreateDestinationDirectoryIfNotExist == false)
{
intResult = 0x7C;
}
}
}
if(intResult == 0)
{
intPositionOfLastSlash = strSourcePath.find_last_of(&quot;\\&quot;);
strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);
if(strNewName == &quot;&quot;)
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strOldName;
}
else
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strNewName;
}
if(bAllowOverwrite == false)
{
if(IsFileExist(strNewPath) == true)
{
intResult = 0x7E;
}
else if(IsFolderExist(strNewPath) == true)
{
intResult = 0x80;
}
}
}
if(intResult == 0)
{
/*- Source Path -*/
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L&quot;\0\0&quot;, 2);
/*---------------*/
/*- New Path -*/
wsNewPath = Utf8StringToWstring(strNewPath);
StrCpyW(a_wcNewPath, wsNewPath.c_str());
CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L&quot;\0\0&quot;, 2);
/*-------------------------*/
/*- Move Item -*/
sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
sfosMove.pFrom = a_wcSourcePath;
sfosMove.pTo = a_wcNewPath;
sfosMove.wFunc = FO_MOVE;
intResult = SHFileOperationW(&amp;sfosMove);
/*-------------*/
}
return intResult;
&quot;, 2); /*---------------*/ /*- New Path -*/ wsNewPath = Utf8StringToWstring(strNewPath); StrCpyW(a_wcNewPath, wsNewPath.c_str()); CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L&quot;
SHFILEOPSTRUCTW sfosMove;
string strNewPath;
string strOldName;
wchar_t a_wcNewPath[MAX_PATH] = {0};
wchar_t a_wcSourcePath[MAX_PATH] = {0};
wstring wsNewPath;
wstring wsSourcePath;
if((IsFileExist(strSourcePath) == false) &amp;&amp; (IsFolderExist(strSourcePath) == false))
{
intResult = 0x7C;
}
else
{
if(IsFolderExist(strDestinationDirectory) == false)
{
if(bCreateDestinationDirectoryIfNotExist == false)
{
intResult = 0x7C;
}
}
}
if(intResult == 0)
{
intPositionOfLastSlash = strSourcePath.find_last_of(&quot;\\&quot;);
strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);
if(strNewName == &quot;&quot;)
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strOldName;
}
else
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strNewName;
}
if(bAllowOverwrite == false)
{
if(IsFileExist(strNewPath) == true)
{
intResult = 0x7E;
}
else if(IsFolderExist(strNewPath) == true)
{
intResult = 0x80;
}
}
}
if(intResult == 0)
{
/*- Source Path -*/
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L&quot;\0\0&quot;, 2);
/*---------------*/
/*- New Path -*/
wsNewPath = Utf8StringToWstring(strNewPath);
StrCpyW(a_wcNewPath, wsNewPath.c_str());
CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L&quot;\0\0&quot;, 2);
/*-------------------------*/
/*- Move Item -*/
sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
sfosMove.pFrom = a_wcSourcePath;
sfosMove.pTo = a_wcNewPath;
sfosMove.wFunc = FO_MOVE;
intResult = SHFileOperationW(&amp;sfosMove);
/*-------------*/
}
return intResult;
SHFILEOPSTRUCTW sfosMove;
string strNewPath;
string strOldName;
wchar_t a_wcNewPath[MAX_PATH] = {0};
wchar_t a_wcSourcePath[MAX_PATH] = {0};
wstring wsNewPath;
wstring wsSourcePath;
if((IsFileExist(strSourcePath) == false) &amp;&amp; (IsFolderExist(strSourcePath) == false))
{
intResult = 0x7C;
}
else
{
if(IsFolderExist(strDestinationDirectory) == false)
{
if(bCreateDestinationDirectoryIfNotExist == false)
{
intResult = 0x7C;
}
}
}
if(intResult == 0)
{
intPositionOfLastSlash = strSourcePath.find_last_of(&quot;\\&quot;);
strOldName = strSourcePath.substr(intPositionOfLastSlash + 1);
if(strNewName == &quot;&quot;)
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strOldName;
}
else
{
strNewPath = strDestinationDirectory + &quot;\\&quot; + strNewName;
}
if(bAllowOverwrite == false)
{
if(IsFileExist(strNewPath) == true)
{
intResult = 0x7E;
}
else if(IsFolderExist(strNewPath) == true)
{
intResult = 0x80;
}
}
}
if(intResult == 0)
{
/*- Source Path -*/
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L&quot;\0\0&quot;, 2);
/*---------------*/
/*- New Path -*/
wsNewPath = Utf8StringToWstring(strNewPath);
StrCpyW(a_wcNewPath, wsNewPath.c_str());
CopyMemory(a_wcNewPath + lstrlenW(a_wcNewPath), L&quot;\0\0&quot;, 2);
/*-------------------------*/
/*- Move Item -*/
sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT;
sfosMove.pFrom = a_wcSourcePath;
sfosMove.pTo = a_wcNewPath;
sfosMove.wFunc = FO_MOVE;
intResult = SHFileOperationW(&amp;sfosMove);
/*-------------*/
}
return intResult;
&quot;, 2); /*-------------------------*/ /*- Move Item -*/ sfosMove.fFlags = FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_SILENT; sfosMove.pFrom = a_wcSourcePath; sfosMove.pTo = a_wcNewPath; sfosMove.wFunc = FO_MOVE; intResult = SHFileOperationW(&amp;sfosMove); /*-------------*/ } return intResult;

}


But The problem is when I use this function repeatedly, only first file is moved. The function creates folders with name of files.

For example:

&gt; First file: abc.txt (This file is moved.) Second file: def.txt (This
&gt; file is not moved. The function creates a folder named &quot;def.txt&quot;)

Example usage creates the problem:

// "example_folder" is already present in "D:" drive.
int intResult;

intResult = MoveItem("C:\ProgramData\abc.txt", "D:\example_folder", "", true, false);

if(intResult == 0)
{
intResult = MoveItem("C:\ProgramData\def.txt", "D:\example_folder", "", true, false);
}


</details>


# 答案1
**得分**: 0

1. 你应该分配文件名缓冲区的大小为 `[MAX_PATH + 1]`,因为它们必须有足够的空间来容纳 `MAX_PATH` 个字符 *和* 终止的双 null。
2. 你只复制了两个字节到源路径和目标路径的末尾,但你的意图是复制四个字节。`L"

</details>
# 答案1
**得分**: 0
1. 你应该分配文件名缓冲区的大小为 `[MAX_PATH + 1]`,因为它们必须有足够的空间来容纳 `MAX_PATH` 个字符 *和* 终止的双 null。
2. 你只复制了两个字节到源路径和目标路径的末尾,但你的意图是复制四个字节。`L"\0\0"` 是两个宽字符,即四个字节。
`CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);`
这会有影响吗?从实际情况来看,可能不会,因为你已经将缓冲区初始化为全零。但这是潜在灾难的因素。
3. 你正在复制到一个可能没有足够空间来容纳你复制的字符的缓冲区。(通常情况下,这可能会正常工作,因为你的源路径可能不会比 `MAX_PATH` 更长,但你也在进行从 UTF-8 到 UTF-16 的转换;出于安全考虑,你应该使用 `StringCchCopy()` 或类似的函数。)
```lang-cpp
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

</details>
# 答案1
**得分**: 0
1. 你应该分配文件名缓冲区的大小为 `[MAX_PATH + 1]`,因为它们必须有足够的空间来容纳 `MAX_PATH` 个字符 *和* 终止的双 null。
2. 你只复制了两个字节到源路径和目标路径的末尾,但你的意图是复制四个字节。`L"\0\0"` 是两个宽字符,即四个字节。
`CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);`
这会有影响吗?从实际情况来看,可能不会,因为你已经将缓冲区初始化为全零。但这是潜在灾难的因素。
3. 你正在复制到一个可能没有足够空间来容纳你复制的字符的缓冲区。(通常情况下,这可能会正常工作,因为你的源路径可能不会比 `MAX_PATH` 更长,但你也在进行从 UTF-8 到 UTF-16 的转换;出于安全考虑,你应该使用 `StringCchCopy()` 或类似的函数。)
```lang-cpp
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
"` 是两个宽字符,即四个字节。 `CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"

</details>
# 答案1
**得分**: 0
1. 你应该分配文件名缓冲区的大小为 `[MAX_PATH + 1]`,因为它们必须有足够的空间来容纳 `MAX_PATH` 个字符 *和* 终止的双 null。
2. 你只复制了两个字节到源路径和目标路径的末尾,但你的意图是复制四个字节。`L"\0\0"` 是两个宽字符,即四个字节。
`CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);`
这会有影响吗?从实际情况来看,可能不会,因为你已经将缓冲区初始化为全零。但这是潜在灾难的因素。
3. 你正在复制到一个可能没有足够空间来容纳你复制的字符的缓冲区。(通常情况下,这可能会正常工作,因为你的源路径可能不会比 `MAX_PATH` 更长,但你也在进行从 UTF-8 到 UTF-16 的转换;出于安全考虑,你应该使用 `StringCchCopy()` 或类似的函数。)
```lang-cpp
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());

</details>
# 答案1
**得分**: 0
1. 你应该分配文件名缓冲区的大小为 `[MAX_PATH + 1]`,因为它们必须有足够的空间来容纳 `MAX_PATH` 个字符 *和* 终止的双 null。
2. 你只复制了两个字节到源路径和目标路径的末尾,但你的意图是复制四个字节。`L"\0\0"` 是两个宽字符,即四个字节。
`CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L"\0\0", 2);`
这会有影响吗?从实际情况来看,可能不会,因为你已经将缓冲区初始化为全零。但这是潜在灾难的因素。
3. 你正在复制到一个可能没有足够空间来容纳你复制的字符的缓冲区。(通常情况下,这可能会正常工作,因为你的源路径可能不会比 `MAX_PATH` 更长,但你也在进行从 UTF-8 到 UTF-16 的转换;出于安全考虑,你应该使用 `StringCchCopy()` 或类似的函数。)
```lang-cpp
wsSourcePath = Utf8StringToWstring(strSourcePath);
StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
", 2);` 这会有影响吗?从实际情况来看,可能不会,因为你已经将缓冲区初始化为全零。但这是潜在灾难的因素。 3. 你正在复制到一个可能没有足够空间来容纳你复制的字符的缓冲区。(通常情况下,这可能会正常工作,因为你的源路径可能不会比 `MAX_PATH` 更长,但你也在进行从 UTF-8 到 UTF-16 的转换;出于安全考虑,你应该使用 `StringCchCopy()` 或类似的函数。) ```lang-cpp wsSourcePath = Utf8StringToWstring(strSourcePath); StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
  1. 你没有初始化 SHFILEOPSTRUCTW 结构,所以你无法知道它的各个部分中有什么样的数据。像这样:

    SHFILEOPSTRUCTW sfosMove{};

  2. 解决了所有这些问题是否会解决你的问题?也许,但我不知道。(首先,你贴出的代码中有几个未定义的函数。)当我运行这段代码,几乎与你贴出的代码相同,修复了我在这里指出的问题后,它似乎运行正常。

这个整个回答可能会被降级,因为它不是一个明确的“答案”,但希望它能帮助你避免一些潜在的麻烦。

英文:

🛑☠️ Potential buffer overruns in several places here.

  1. You should be allocating filename buffers with size [MAX_PATH + 1], because they must have enough room to hold MAX_PATH characters and the terminating double-null.
  2. You are only copying two bytes to the end of both your source and your destination paths, when your intent is to copy four. L&quot;\0\0&quot; is two wide characters, which is four bytes.

CopyMemory(a_wcSourcePath + lstrlenW(a_wcSourcePath), L&quot;\0\0&quot;, 2);

Will this matter? Practically speaking, probably not, as you did initialize the buffer to all-zeroes. But it's a recipe for potential disaster.

  1. You are copying to a buffer that may not have room for the characters you're copying. (It would usually work out, since presumably your source path is not longer than MAX_PATH, but you're dealing with conversions as well, from UTF-8 to UTF-16; for safety's sake, you should use StringCchCopy() or similar.)
    wsSourcePath = Utf8StringToWstring(strSourcePath);

    StrCpyW(a_wcSourcePath, wsSourcePath.c_str());
  1. You are not initializing the SHFILEOPSTRUCTW struct, so you have no way of knowing what sort of data is sitting in its various parts. Like this:

SHFILEOPSTRUCTW sfosMove{};

  1. Will fixing all of those issues fix your problem? Maybe, but I don't know. (You have several functions in your pasted code that are not defined, for one thing.) When I run this code, more or less as you have it there, with the problems I've noted here fixed, it seems to work fine.

This whole answer might get downgraded because it's not definitively an "answer," but hopefully it saves you from some trouble down the line.

答案2

得分: 0

I'd start by using the std::filesystem function to handle path manipulation and such.

I'd probably also use std::filesystem::rename to move the files, but there may be a case to make for using MoveFileEx instead. In particular, I haven't tried to check whether Microsoft's implementation of rename will actually move a file from one drive to another (but I'd guess it probably does).

So, a version using just std::filesystem stuff would be something like this:

bool MoveItem(string sourcePath, string destDirectory, string destName, bool allowOverwrite, bool createDest) {

	namespace fs = std::filesystem;

	fs::path src{sourcePath};
	fs::path dest{destDirectory};

	if (!fs::exists(src))
		return false;

	if (createDest) {
		fs::create_directories(destDirectory); // does nothing if already exists
	} else if (!fs::is_directory(dest)) {
		return false;	// fail if it doesn't exist and we aren't allowed to create it.
	}

    dest = dest / (destName.empty() ? src.filename() : destName);

	if (!allowOverwrite && fs::exists(dest)) {
		return false;
	}

    std::error_code ec;
    fs::rename(src, dest, ec);
    return !ec;
}

If you wanted to use MoveFileEx instead, the last part of the code (after the dest = dest / ... line) would look something like this:

DWORD flags{ MOVEFILE_COPY_ALLOWED };

if (allowOverwrite)
	flags |= MOVEFILE_REPLACE_EXISTING;

return MoveFileEx(src.string().c_str(), dest.string().c_str(), flags) != 0;

I haven't tried to test every possible scenario (different combinations of flags, directory and/or files that already exist, moving between drives, over networks, etc.) but did a quick little test with code like this:

#include &lt;vector&gt;
#include &lt;fstream&gt;

int main() {
	std::vector&lt;string&gt; testNames { &quot;a.test&quot;, &quot;b.test&quot;, &quot;c.test&quot;};

	// Create a few files to test with:
	for (auto t : testNames) {
		std::ofstream o(t);
	}

	// move them to some innocuous destination:
	for (auto t : testNames) {
		MoveItem(t, &quot;c:/junk&quot;, &quot;&quot;, false, true);
	}
}
英文:

I'd start by using the std::filesystem function to handle path manipulation and such.

I'd probably also use std::filesystem::rename to move the files, but there may be a case to make for using MoveFileEx instead. In particular, I haven't tried to check whether Microsoft's implementation of rename will actually move a file from one drive to another (but I'd guess it probably does).

So, a version using just std::filesystem stuff would be something like this:

bool MoveItem(string sourcePath, string destDirectory, string destName, bool allowOverwrite, bool createDest) {

	namespace fs = std::filesystem;

	fs::path src{sourcePath};
	fs::path dest{destDirectory};

	if (!fs::exists(src))
		return false;

	if (createDest) {
		fs::create_directories(destDirectory); // does nothing if already exists
	} else if (!fs::is_directory(dest)) {
		return false;	// fail if it doesn&#39;t exist and we aren&#39;t allowed to create it.
	}

    dest = dest / (destName.empty() ? src.filename() : destName);

	if (!allowOverwrite &amp;&amp; fs::exists(dest)) {
		return false;
	}

    std::error_code ec;
    fs::rename(src, dest, ec);
    return !ec;
}

If you wanted to use MoveFileEx instead, the last part of the code (after the dest = dest / ... line) would look something like this:

DWORD flags{ MOVEFILE_COPY_ALLOWED };

if (allowOverwrite)
	flags |= MOVEFILE_REPLACE_EXISTING;

return MoveFileEx(src.string().c_str(), dest.string().c_str(), flags) != 0;

I haven't tried to test every possible scenario (different combinations of flags, directory and/or files that already exist, moving between drives, over networks, etc.) but did a quick little test with code like this:

#include &lt;vector&gt;
#include &lt;fstream&gt;

int main() {
	std::vector&lt;string&gt; testNames { &quot;a.test&quot;, &quot;b.test&quot;, &quot;c.test&quot;};

	// Create a few files to test with:
	for (auto t : testNames) {
		std::ofstream o(t);
	}

	// move them to some innocuous destination:
	for (auto t : testNames) {
		MoveItem(t, &quot;c:/junk&quot;, &quot;&quot;, false, true);
	}
}

huangapple
  • 本文由 发表于 2023年6月26日 22:25:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76557619.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定