在托管c++里面使用FileSystemWatcher对指定的文件进行监控
//
//FileMonitorHandler.h
//
#pragma once
class IFileMonitorHandle
{
public:
virtual void OnFileChanged(const CString& strFilePath) const = 0;
virtual void OnFileDeleted(const CString& strFilePath) const = 0;
virtual void OnFileRenamed(const CString& strOldFileName, const CString& strNewFileName) const = 0;
};
//
//FileMonitorInterop.h
//
#pragma once
#include <memory>
class IFileMonitorHandle;
class CFileMonitorInterop
{
public:
CFileMonitorInterop(IFileMonitorHandle &);
bool AddMonitorFile(const CString& strFilePath);
void RemoveMonitorFile(const CString& strFilePath);
void UnInitializeMonitormanager();
private:
struct Impl;
std::tr1::shared_ptr<Impl> m_pImpl; // with std::auto_ptr<>: warning C4150: deletion of pointer to incomplete type '...'; no destructor called
};
//
//FileMonitorInterop.cpp
//
#include "stdafx.h"
#include "FileMonitorInterop.h"
#include "FileMonitorHandler.h"
#using <mscorlib.dll>
#using <System.dll>
#include <msclr\auto_gcroot.h>
using namespace System;
using namespace System::IO;
ref class FileMonitorProxy sealed
{
public:
FileMonitorProxy(IFileMonitorHandle& manager) : m_monitorManager(manager) {
m_FilePathToSystemWatchers = gcnew System::Collections::Generic::Dictionary<String^, FileSystemWatcher^>();
}
bool AddFileToMonitor(System::String^ strFilePath) {
if (!IO::File::Exists(strFilePath))
return false;
if (m_FilePathToSystemWatchers->ContainsKey(strFilePath)) // TODO: case-insensitive comparison
return false;
FileInfo^ spFile = gcnew FileInfo(strFilePath);
FileSystemWatcher^ fileWatch = gcnew FileSystemWatcher();
fileWatch->Path = spFile->DirectoryName;
fileWatch->NotifyFilter = NotifyFilters::LastWrite | NotifyFilters::LastAccess | NotifyFilters::FileName;
fileWatch->Filter = spFile->Name;
//fileWatch->SynchronizingObject = this;
AddEvents(fileWatch);
m_FilePathToSystemWatchers->Add(strFilePath, fileWatch);
return true;
}
void RemoveMonitoredFile(System::String^ strFilePath) {
FileSystemWatcher^ fileWatch;
bool bContainsKey = m_FilePathToSystemWatchers->TryGetValue(strFilePath, fileWatch);
if (bContainsKey)
{
RemoveEvents(fileWatch);
m_FilePathToSystemWatchers->Remove(strFilePath);
}
}
void UnInitializeMonitorManagerProxy() {
for each(System::Collections::Generic::KeyValuePair<String^ , FileSystemWatcher^>^ fileWatchItem in m_FilePathToSystemWatchers)
{
FileSystemWatcher^ fileWatch = fileWatchItem->Value;
RemoveEvents(fileWatch);
}
m_FilePathToSystemWatchers->Clear();
}
void OnChanged(System::Object^ /*source*/, FileSystemEventArgs^ e) {
const CString strFullPath(e->FullPath);
switch (e->ChangeType)
{
case WatcherChangeTypes::Changed:
m_monitorManager.OnFileChanged(strFullPath);
break;
case WatcherChangeTypes::Deleted:
m_monitorManager.OnFileDeleted(strFullPath);
break;
default:
break;
}
}
void OnRenamed(System::Object^ /*source*/, System::IO::RenamedEventArgs^ e) {
const CString strOldFullPath(e->OldFullPath);
const CString strNewFullPath(e->FullPath);
m_monitorManager.OnFileRenamed(strOldFullPath, strNewFullPath);
}
private:
FileSystemEventHandler^ m_onChangedHandler;
RenamedEventHandler^ m_onRenamedHandler;
void AddEvents(FileSystemWatcher^ fileWatch) {
if (m_onChangedHandler == nullptr)
m_onChangedHandler = gcnew FileSystemEventHandler(this, &FileMonitorProxy::OnChanged);
if (m_onRenamedHandler == nullptr)
m_onRenamedHandler = gcnew RenamedEventHandler(this, &FileMonitorProxy::OnRenamed);
fileWatch->Changed += m_onChangedHandler;
fileWatch->Created += m_onChangedHandler;
fileWatch->Deleted += m_onChangedHandler;
fileWatch->Renamed += m_onRenamedHandler;
fileWatch->EnableRaisingEvents = true;
}
void RemoveEvents(FileSystemWatcher^ fileWatch) {
fileWatch->EnableRaisingEvents = false;
fileWatch->Changed -= m_onChangedHandler;
fileWatch->Created -= m_onChangedHandler;
fileWatch->Deleted -= m_onChangedHandler;
fileWatch->Renamed -= m_onRenamedHandler;
}
System::Collections::Generic::Dictionary<System::String^, System::IO::FileSystemWatcher^>^ m_FilePathToSystemWatchers;
IFileMonitorHandle& m_monitorManager;
};
// ---------------------------------------------------------------------------
// Wrapper...
// ---------------------------------------------------------------------------
struct CFileMonitorInterop::Impl
{
Impl(IFileMonitorHandle& manager) {
Proxy = gcnew FileMonitorProxy(manager);
}
msclr::auto_gcroot<FileMonitorProxy^> Proxy;
};
// ---------------------------------------------------------------------------
// Interop Routines...
// ---------------------------------------------------------------------------
CFileMonitorInterop::CFileMonitorInterop(IFileMonitorHandle& manager)
{
m_pImpl.reset(new Impl(manager));
}
bool CFileMonitorInterop::AddMonitorFile(const CString& strFilePath)
{
String ^ pStr = gcnew String(strFilePath);
return m_pImpl->Proxy->AddFileToMonitor(pStr);
}
void CFileMonitorInterop::RemoveMonitorFile(const CString& strFilePath)
{
String ^ pStr = gcnew String(strFilePath);
m_pImpl->Proxy->RemoveMonitoredFile(pStr);
}
void CFileMonitorInterop::UnInitializeMonitormanager()
{
m_pImpl->Proxy->UnInitializeMonitorManagerProxy();
}
posted on 2010-04-23 10:08 Levon Chen 阅读(489) 评论(0) 收藏 举报
浙公网安备 33010602011771号