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


    前言

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

            最近,研究了一下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;
    }


  • 相关阅读:
    【Android笔记】Android操作HTTP实现与服务器通信
    【Android笔记】Android与服务器通信 http和socket两种形式
    【网络编程笔记】简单的TCP协议 socket编程(C语言版服务器和客户端)
    【Web后端笔记】基于Socket实现的简单Web服务器搭建
    【Web前端笔记】css让背景图片拉伸填充的属性
    【Android笔记】ServerSocket 与 Socket的区别
    【Android笔记】Android与服务器数据库通信的方法
    【Android笔记】Android的三种网络通信方式
    【Web后端笔记】jsp传递中文数据出现乱码的问题
    【Web后端笔记】jsp 的四个作用域 :page、request、session和application的区别
  • 原文地址:https://www.cnblogs.com/james1207/p/3343536.html
Copyright © 2020-2023  润新知