已知文件被某进程占用,强行解除占用,并删除文件

BOOL GetVolumeNameByHandle(HANDLE hFile, LPTSTR szVolumeName, UINT cchMax)
{
	BOOL bResult = FALSE;
	TCHAR szBuf[500] = { 0 };
	TCHAR * pIter = szBuf;
	int i =0;
	BY_HANDLE_FILE_INFORMATION stFileInfo = { 0 };
 
	do
	{
		if(FALSE == GetFileInformationByHandle(hFile, &stFileInfo)) {
			break;
		}
 
		if(0== GetLogicalDriveStrings(_countof(szBuf), szBuf)) {
			break;
		}
 
		for(; pIter; pIter+=4)
		{
			DWORD dwVolumeSerialNumber =0;
 
			if(GetVolumeInformation(pIter, NULL, 0, &dwVolumeSerialNumber, 
				NULL, NULL, NULL, 0))
			{
				if(dwVolumeSerialNumber == stFileInfo.dwVolumeSerialNumber)
				{
					lstrcpyn(szVolumeName, pIter, cchMax);
					bResult = TRUE;
					break;
				}
			}
		}
 
	} while (FALSE);
 
	return bResult;
}


BOOL GetFilePathFromHandleW(HANDLE hFile, LPTSTR lpszPath, UINT cchMax)
{
	BOOL bResult = FALSE;
	TCHAR szValue[MAX_PATH] = { 0 };
 
	IO_STATUS_BLOCK isb = { 0 };
	FILE_NAME_INFORMATION fni = { 0 };
	HANDLE hNtDll = NULL;
	PFN_ZwQueryInformationFile pfn_ZwQueryInformationFile = NULL;
 
	do
	{
		if (INVALID_HANDLE_VALUE==hFile || NULL==lpszPath ||0==cchMax) {
			break;
		}
 
		hNtDll = GetModuleHandle(TEXT("ntdll.dll")); 
		if (NULL == hNtDll) {
			break;
		}
 
		pfn_ZwQueryInformationFile = (PFN_ZwQueryInformationFile)
			GetProcAddress(hNtDll, TEXT("ZwQueryInformationFile"));
		if (NULL == pfn_ZwQueryInformationFile) {
			break;
		}
 
		// 9 == FileNameInformation
		if (0!= pfn_ZwQueryInformationFile(hFile, &isb, &fni, sizeof(fni), 9)) {
			break;
		}
 
		if (FALSE == GetVolumeNameByHandle(hFile, szValue, _countof(szValue))) {
			break;
		}
 
		PathAppend(szValue, fni.FileName);
 
		lstrcpyn(lpszPath, szValue, cchMax);
 
		bResult = TRUE;
	} while (FALSE);
	return bResult;
}


BOOL DeleteLockedFile(DWORD dwProcessID, HANDLE hFile)
{
	TCHAR szTargetName[MAX_PATH] = { 0 };
	HANDLE hTargeFile = INVALID_HANDLE_VALUE;
	HANDLE hProcess = NULL;
	BOOL bResult = FALSE;
 
	do 
	{
		hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
		if (NULL == hProcess) {
			break;
		}
 
		if (FALSE == DuplicateHandle(hProcess, hFile, 
			GetCurrentProcess(), &hTargeFile, 
			0, FALSE, DUPLICATE_SAME_ACCESS)) 
		{
			break;
		}
 
		if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
			break;
		}
 
		if (FALSE == GetFilePathFromHandle(hTargeFile, 
			szTargetName, _countof(szTargetName))) 
		{
			break;
		}
 
		CloseHandle(hTargeFile);
		hTargeFile = INVALID_HANDLE_VALUE;
 
		if (0 == lstrlen(szTargetName)) {
			break;
		}
 
		if (FALSE == DuplicateHandle(hProcess, hFile, 
			GetCurrentProcess(), &hTargeFile, 
			0, FALSE, 
			DUPLICATE_SAME_ACCESS|DUPLICATE_CLOSE_SOURCE))
		{
			break;
		}
 
		if (INVALID_HANDLE_VALUE==hTargeFile || NULL==hTargeFile) {
			break;
		}
 
		CloseHandle(hTargeFile);
		hTargeFile = INVALID_HANDLE_VALUE;
 
		bResult = DeleteFile(szTargetName);
	} while (FALSE);
 
	if (INVALID_HANDLE_VALUE != hTargeFile && NULL != hTargeFile) {
		CloseHandle(hTargeFile);
	}
 
	if (hProcess) {
		CloseHandle(hProcess);
	}
	return bResult;
}

至于怎么判断文件被某个进程占用,前面有过介绍,这里只大概介绍一下思路:

1、遍历进程
2、遍历进程里面的句柄
3、根据句柄获取文件全路径
4、判断文件是否所需解除文件?

你可能感兴趣的:(工作随笔篇,c++,文件删除)