Vas*_*yev 3 c++ winapi temporary-files
我正在为其他开发人员编写临时文件管理器.我想删除文件,即使我们的控制台应用程序崩溃或被"X"按钮关闭.
到目前为止,我找到了std::set_terminate,std::atexit以及SetConsoleCtrlHandler我可以删除我需要的所有临时文件的方法.问题是 - 我无法删除打开的文件.此外 - 我无法控制流到这些文件的流,导致开发人员使用多个库(例如GDAL),这些库使用自己的流机制并且只能接受目标文件路径.
如何强制关闭并删除当前应用程序打开的所有文件?
您需要关闭当前进程拥有的文件句柄.去做这个:
NtQuerySystemInformationAPI与未记录的SystemHandleInformation参数一起使用.GetFinalPathNameByHandle获取已打开文件的路径进一步缩小范围,例如,您可以选择特定文件名或名称中的所有文件tmp.CloseHandle()强制关闭句柄,然后DeleteFile()在路径上调用.一些代码(没有任何错误检查):
SYSTEM_HANDLE_INFORMATION* pInfo=NULL;
DWORD dwSize=0;
NTSTATUS status=0;
do
{
// keep reallocing until buffer is big enough
status = NtQuerySystemInformation(SystemHandleInformation, pInfo, dwSize, &dwSize);
if (status==STATUS_INFO_LENGTH_MISMATCH)
pInfo = (SYSTEM_HANDLE_INFORMATION*)realloc(pInfo, dwSize);
} while(status!=0);
// iterate over every handle
for (DWORD i=0; i<pInfo->dwCount; i++)
{
if (pInfo->handles[i].ProcessID==GetCurrentProcessId() && pInfo->handles[i].HandleType==28)
{
TCHAR szPath[MAX_PATH];
GetFinalPathNameByHandle((HANDLE)pInfo->handles[i].HandleNumber, szPath, MAX_PATH, 0);
if (_tcsstr(szFilePath, L"filename_I_want_to_delete"))
{
CloseHandle((HANDLE)pInfo->handles[i].HandleNumber);
DeleteFile(szPath);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这假设您需要删除的所有文件都由执行删除的进程拥有.如果任何文件属于另一个进程,则需要使用DuplicateHandle()该DUPLICATE_CLOSE_SOURCE选项进行额外步骤.假设您具有合适的权限,则会为您提供句柄,然后您可以像以前一样关闭并删除该文件.
有一些很好的示例代码在这里.
| 归档时间: |
|
| 查看次数: |
3530 次 |
| 最近记录: |