系统自带的文件拷贝、移动、删除和重命名操作
前言
经常随手花上个半到一个小时,自己手写一个拷贝系统文件的代码,里面用上个几重递归,然后判断下文件属性,看是文件夹还是文件。然后自己根据文件的大小来控制进度条的显示进度。是否真的需要付出这么多了?
最近,研究了一下windows shell编程,发现其实很多系统有的功能,系统早就做好,并且完完全全的提供给我们了,只是我们比较喜欢一步步的自己来维护每一个流程。最终导致的结果是,耽误了开发进度,同时造成了某些不可知的软件bug。
简介
在vista之前的版本中,经常可以使用SHFileOperation这个系统函数处理类似于文件的拷贝、移动、删除和重命名操作。但vista之后的版本,系统又提供了com库接口IFileOperation的方式来处理相同的文件操作。当然以前的方法依然适用。只不过最新的文件操作方法使用起来会更加的“人性化”(后面会提到)。
内容
旧版文件操作
拷贝操作
int CEarlyFileOperator::FOCopyFile(const wstring &strFrom, const wstring &strTo) { wchar_t srcPath[MAX_PATH]; wchar_t dstPath[MAX_PATH]; memset(srcPath,'\0',MAX_PATH); memset(dstPath,'\0',MAX_PATH); memcpy(srcPath,strFrom.c_str(),strFrom.length() * sizeof(wchar_t)); memcpy(dstPath,strTo.c_str(),strTo.length() * sizeof(wchar_t)); SHFILEOPSTRUCT FileOp = {0}; FileOp.hwnd = NULL; // 调用过程会改变父窗口属性 FileOp.wFunc = FO_COPY; // 执行文件拷贝 FileOp.pFrom = srcPath; FileOp.pTo = dstPath; FileOp.hNameMappings = NULL; FileOp.fFlags = FOF_ALLOWUNDO; FileOp.lpszProgressTitle = _T("文件正在拷贝中..."); int nRet = SHFileOperation(&FileOp); return nRet; }
移动操作
int CEarlyFileOperator::FORemoveFile(const wstring &strFrom, const wstring &strTo) { wchar_t srcPath[MAX_PATH]; wchar_t dstPath[MAX_PATH]; memset(srcPath,'\0',MAX_PATH); memset(dstPath,'\0',MAX_PATH); memcpy(srcPath,strFrom.c_str(),strFrom.length() * sizeof(wchar_t)); memcpy(dstPath,strTo.c_str(),strTo.length() * sizeof(wchar_t)); SHFILEOPSTRUCT FileOp = {0}; FileOp.hwnd = NULL; // 调用过程会改变父窗口属性 FileOp.wFunc = FO_MOVE; // 执行文件拷贝 FileOp.pFrom = srcPath; FileOp.pTo = dstPath; FileOp.hNameMappings = NULL; FileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR; //FileOp.lpszProgressTitle = _T("文件正在拷贝中..."); int nRet = SHFileOperation(&FileOp); return nRet; }
删除操作
int CEarlyFileOperator::FODelFile(const wstring &strFrom) { wchar_t srcPath[MAX_PATH]; memset(srcPath,'\0',MAX_PATH); memcpy(srcPath,strFrom.c_str(),strFrom.length() * sizeof(wchar_t)); SHFILEOPSTRUCT FileOp = {0}; FileOp.hwnd = NULL; FileOp.wFunc = FO_DELETE; FileOp.pFrom = srcPath; FileOp.pTo = NULL; FileOp.hNameMappings = NULL; FileOp.fFlags = FOF_ALLOWUNDO; //允许撤销,不出现确认对话框 int nRet = SHFileOperation(&FileOp); return nRet; }
重命名操作
int CEarlyFileOperator::FORenameFile(const wstring &strFrom, const wstring &strRename) { wchar_t srcPath[MAX_PATH]; wchar_t reName[MAX_PATH]; memset(srcPath,'\0',MAX_PATH); memset(reName,'\0',MAX_PATH); // 获取路径地址 wstring strPath = strFrom.substr(0,strFrom.rfind(_T("\\"))); wstring strTo = strPath + _T("\\") + strRename; memcpy(srcPath,strFrom.c_str(),strFrom.length() * sizeof(wchar_t)); memcpy(reName,strTo.c_str(),strTo.length() * sizeof(wchar_t)); SHFILEOPSTRUCT FileOp = {0}; FileOp.hwnd = NULL; // 调用过程会改变父窗口属性 FileOp.wFunc = FO_RENAME; // 执行文件拷贝 FileOp.pFrom = srcPath; FileOp.pTo = reName; FileOp.hNameMappings = NULL; FileOp.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION; int nRet = SHFileOperation(&FileOp); return nRet; }
新版文件操作
拷贝操作
int CLaterFileOperator::FOCopyFile(const wstring &strFrom, const wstring &strTo) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; ///< Create the IFileOperation interface hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { ///< Set the operation flags hr = pfo->SetOperationFlags(FOF_ALLOWUNDO); if (SUCCEEDED(hr)) { ///< Create an IShellItem from the supplied source path IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(strFrom.c_str(), NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { ///< Create an IShellItem from the supplied destination path. IShellItem *psiTo = NULL; hr = SHCreateItemFromParsingName(strTo.c_str(), NULL, IID_PPV_ARGS(&psiTo)); if (SUCCEEDED(hr)) { hr = pfo->CopyItem(psiFrom, psiTo, NULL, NULL); if (NULL != psiTo) { psiTo->Release(); } } psiFrom->Release(); } if (SUCCEEDED(hr)) { hr = pfo->PerformOperations(); } } pfo->Release(); } CoUninitialize(); } return hr; }
移动操作
int CLaterFileOperator::FORemoveFile(const wstring &strFrom, const wstring &strTo) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; ///< Create the IFileOperation interface hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { ///< Set the operation flags hr = pfo->SetOperationFlags(FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOCONFIRMMKDIR); if (SUCCEEDED(hr)) { ///< Create an IShellItem from the supplied source path IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(strFrom.c_str(), NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { ///< Create an IShellItem from the supplied destination path. IShellItem *psiTo = NULL; hr = SHCreateItemFromParsingName(strTo.c_str(), NULL, IID_PPV_ARGS(&psiTo)); if (SUCCEEDED(hr)) { hr = pfo->MoveItem(psiFrom, psiTo, NULL, NULL); if (NULL != psiTo) { psiTo->Release(); } } psiFrom->Release(); } if (SUCCEEDED(hr)) { hr = pfo->PerformOperations(); } } pfo->Release(); } CoUninitialize(); } return hr; }
删除操作
int CLaterFileOperator::FODelFile(const wstring &strFrom) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; ///< Create the IFileOperation interface hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { ///< Set the operation flags hr = pfo->SetOperationFlags(FOF_ALLOWUNDO); if (SUCCEEDED(hr)) { ///< Create an IShellItem from the supplied source path IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(strFrom.c_str(), NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { hr = pfo->DeleteItem(psiFrom, NULL); psiFrom->Release(); } if (SUCCEEDED(hr)) { hr = pfo->PerformOperations(); } } pfo->Release(); } CoUninitialize(); } return hr; }
重命名操作
int CLaterFileOperator::FORenameFile(const wstring &strFrom, const wstring &strRename) { HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); if (SUCCEEDED(hr)) { IFileOperation *pfo; ///< Create the IFileOperation interface hr = CoCreateInstance(CLSID_FileOperation, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pfo)); if (SUCCEEDED(hr)) { ///< Set the operation flags hr = pfo->SetOperationFlags(FOF_ALLOWUNDO | FOF_NOCONFIRMATION); if (SUCCEEDED(hr)) { ///< Create an IShellItem from the supplied source path IShellItem *psiFrom = NULL; hr = SHCreateItemFromParsingName(strFrom.c_str(), NULL, IID_PPV_ARGS(&psiFrom)); if (SUCCEEDED(hr)) { hr = pfo->RenameItem(psiFrom, strRename.c_str(), NULL); psiFrom->Release(); } if (SUCCEEDED(hr)) { hr = pfo->PerformOperations(); } } pfo->Release(); } CoUninitialize(); } return hr; }