系统自带的文件拷贝、移动、删除和重命名操作

前言

        经常随手花上个半到一个小时,自己手写一个拷贝系统文件的代码,里面用上个几重递归,然后判断下文件属性,看是文件夹还是文件。然后自己根据文件的大小来控制进度条的显示进度。是否真的需要付出这么多了?

        最近,研究了一下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,'',MAX_PATH);
	memset(dstPath,'',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,'',MAX_PATH);
	memset(dstPath,'',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,'',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,'',MAX_PATH);
	memset(reName,'',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;
}


原文地址:https://www.cnblogs.com/james1207/p/3343536.html