关于枚举进程所占用文件
我想要拷贝Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data下的master, model, msdb, tempdb这几个系统数据库文件,因为他们被另一个进程占用了,所以无法执行拷贝的操作,如果强制结束sqlservr.exe,就可以执行拷贝操作了;但是另一方面 ,如果我列举sqlservr.exe所占用的文件时,却枚举不出以上几个数据库文件了。
我是用以下代码来进行枚举的。其中参数lpFileName是因为错误32所导致无法执行拷贝的文件名;其中当processName为sqlservr.exe时,只能枚举出model.mdf这个数据库文件,其他几个都无法枚举,这是怎么回事呢?
请高人指点。谢谢
void CloseRemoteFileHandles( LPCTSTR lpFileName )
{
CString deviceFileName;
CString fsFilePath;
CString name;
CString processName;
SystemHandleInformation hi;
SystemProcessInformation pi;
SystemProcessInformation::SYSTEM_PROCESS_INFORMATION* pPi;
//Convert it to device file name
if ( !SystemInfoUtils::GetDeviceFileName( lpFileName, deviceFileName ) )
{
_tprintf( _T("GetDeviceFileName() failed.\n") );
return;
}
//Query every file handle (system wide)
if ( !hi.SetFilter( _T("File"), TRUE ) )
{
_tprintf( _T("SystemHandleInformation::SetFilter() failed.\n") );
return;
}
if ( !pi.Refresh() )
{
_tprintf( _T("SystemProcessInformation::Refresh() failed.\n") );
return;
}
//Iterate through the found file handles
for ( POSITION pos = hi.m_HandleInfos.GetHeadPosition(); pos != NULL; )
{
SystemHandleInformation::SYSTEM_HANDLE& h = hi.m_HandleInfos.GetNext(pos);
if ( !pi.m_ProcessInfos.Lookup( h.ProcessID, pPi ) )
continue;
if ( pPi == NULL )
continue;
//Get the process name
SystemInfoUtils::Unicode2CString( &pPi->usName, processName );
if (_tcsicmp( processName, _T("sqlservr.exe") ) == 0)
{
int aa = 0;
}
//NT4 Stupid thing if I query the name of a file in services.exe
//Messengr service brings up a message dialog
if ( INtDll::dwNTMajorVersion == 4 && _tcsicmp(processName,_T("services.exe")) == 0 )
continue;
//get the file name for this given handle
hi.GetName( (HANDLE)h.HandleNumber, name, h.ProcessID );
//This is what we want to copy,so close the handle
if ( _tcscmp( name, deviceFileName ) == 0 )
{
CloseRemoteHandle( processName, h.ProcessID, (HANDLE)h.HandleNumber );
}
}
}