Levon Chen 的脚步

生活在于拥抱改变。

在托管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)    收藏  举报

导航