SHFile操作不会移动文件夹的所有内容

SHFileOperation doesn't move all of a folder's contents

本文关键字:文件夹 操作 移动 SHFile      更新时间:2023-10-16

这将在桌面上创建一个新文件夹,但不会将文件夹.pfrom的内容移动到文件夹. pto。

int main()
{
    SHFILEOPSTRUCT sf = {0};
    TCHAR myt[MAX_PATH];
    GetModuleFileName(NULL, myt, MAX_PATH); // puts the currente exe path in the buffer myt
    string currentexepath;
    int i;
    for(i = 0; myt[i] != NULL; i++) {  // this loop is for converting myt to string
        currentexepath += myt[i];      // because string capabilities are needed
    }
    i = currentexepath.find_last_of("\/");
    currentexepath = currentexepath.substr(0, i);
    currentexepath += "\subfolder\*.*"; //i tried with and without *.* and 
    wstring ws = s2ws(currentexepath);
    sf.wFunc = FO_COPY;
    sf.hwnd = 0;
    sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
    sf.pFrom = ws.c_str();
    sf.pTo = L"C:\Users\Me\Desktop\folder";
    SHFileOperation(&sf);
}
// the following is from msdn
// http://social.msdn.microsoft.com/Forums/en/Vsexpressvc/thread/0f749fd8-8a43-4580-b54b-fbf964d68375
wstring s2ws(const string& s)
{
    int len;
    int slength = (int)s.length() + 1;
    len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); 
    wchar_t* buf = new wchar_t[len];
    MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
    std::wstring r(buf);
    delete[] buf;
    return r;
}

SHFileOperation需要一个双空结束字符串。但是你不能使用std::string或std::wstring。参见双空终止字符串。

当你这样做的时候:

currentexepath += "\subfolder\*.*";

字符串的+操作符看不到第二个null终止,因为它在第一个null处停止。

这里有一个方法可以解决这个问题:

int main()
{
    SHFILEOPSTRUCT sf = {0};
    TCHAR myt[MAX_PATH];
    GetModuleFileName(NULL, myt, MAX_PATH); // puts the currente exe path in the buffer myt
    string currentexepath;
    if(TCHAR* LastSlash = _tcsrchr(myt, _T(''))) {
        *LastSlash = _T('');
    }
    // the pipe sign will be replaced with a  to get double null termination
    // because _tcscat_s and all other strcat functions stop at the first 
    // we have to use this workaround
    _tcscat_s(myt, _T("\subfolder\*.*|")); 
    while (TCHAR* ptr = _tcsrchr(myt, _T('|'))) {
        *ptr = _T(''); 
    }
    sf.wFunc = FO_COPY;
    sf.hwnd = 0;
    sf.fFlags = FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR | FOF_NOERRORUI;
    sf.pFrom = myt;
    sf.pTo = L"C:\Users\wh\Desktop\folder";
    if(SHFileOperation(&sf)!=0) {
        // error occured
        MessageBox(NULL, L"SHFileOperation failed", L"Error", MB_OK);
    }
}

if()和while()语句如何转换为布尔值?

例如if语句:

    if(TCHAR* LastSlash = _tcsrchr(myt, _T(''))) {
        *LastSlash = _T('');
    }

也可以写成:

    TCHAR* LastSlash = _tcsrchr(myt, _T(''));
    if(LastSlash) {
        *LastSlash = _T('');
    }

或:

    TCHAR* LastSlash = _tcsrchr(myt, _T(''));
    if(LastSlash != NULL) {
        *LastSlash = _T('');
    }

我在一条语句中合并了TCHAR*的赋值和检查。当指针转换为布尔值时,NULL变为false,其他所有值变为true。