【问题标题】:SHFileOperation doesn't move all of a folder's contentsSHFileOperation 不会移动文件夹的所有内容
【发布时间】:2011-04-24 03:08:06
【问题描述】:

这会在桌面上创建一个新文件夹,但不会将文件夹 .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\\*.*\0"; //i tried with and without *.* and \0
    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\0";
    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;
}

【问题讨论】:

    标签: c++ file directory move shfileoperation


    【解决方案1】:

    SHFileOperation 需要一个双空终止的字符串。但是您不能为此使用 std::string 或 std::wstring 。另见Double null-terminated string

    当你这样做时:

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

    字符串的 + 运算符没有看到第二个空终止符,因为它在第一个空值处停止。

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

    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('\0');
        }
    
        // the pipe sign will be replaced with a \0 to get double null termination
        // because _tcscat_s and all other strcat functions stop at the first \0
        // we have to use this workaround
        _tcscat_s(myt, _T("\\subfolder\\*.*|")); 
        while (TCHAR* ptr = _tcsrchr(myt, _T('|'))) {
            *ptr = _T('\0'); 
        }
    
        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\0";
        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('\0');
        }
    

    也可以写成:

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

    或:

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

    我将 TCHAR* 的分配和检查结合在一个语句中。当指针转换为布尔值时,NULL 变为 false,所有其他值变为 true。

    【讨论】:

    • if() 和 while() 语句如何转换为布尔值?
    • @Geore,我在上面添加了解释。如果还不清楚,请告诉我。
    猜你喜欢
    • 2018-10-25
    • 1970-01-01
    • 2018-08-18
    • 2013-03-16
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 2021-11-29
    • 1970-01-01
    相关资源
    最近更新 更多