2012-12-13 1 views
1

특정 작업을 수행하기 위해 특정 파일의 생성 및 삭제를 감시하는 프로그램이 있습니다. .NET FileSystemWatcher를 사용하여 이러한 특정 파일 주위의 활동을 모니터링합니다. 이 프로그램은 .NET 3.5에서 Windows 서비스로 실행되며 C#으로 코딩됩니다. Windows DEL 명령 또는 ERASE 명령을 사용하여 감시중인 파일을 삭제해도 FileSystemWatcher 이벤트 (변경, 삭제, 생성, 오류, 이름 변경)가 실행되지 않는 문제가 발생했습니다. 이 문제는 내 Windows 2003 및 Windows 2008 상자에서만 발생하지만 내 Windows 7 상자에서는 발생하지 않습니다. 그것은 잘 윈도우 7에서 작동합니다. 나는 이것에 대해 광범위하게 봤 거든 행운과 함께 여러 StackOverflow 게시물을 검토했습니다. 필자는 FileSystemWatcher의 다양한 구성으로 작업을 수행했습니다. 버퍼를 늘리고 NotifyFilter 열거 형의 다양한 조합을 시도하고 IncludeSubdirectories를 설정하고 파일을 수정하고 프로그램을 실행하는 사용자의 권한을 늘리거나 줄였습니다. 모두 성공하지 못했습니다. 내 이벤트 처리기의 맨 위에 중단 점을 넣었고 절대로 DEL 또는 ERASE에 도달하지 않습니다. 생성 및 이름 변경 (REN)에서 작동합니다. 이 문제를 해결하기 위해 파일을 삭제하기 전에 이름을 바꿉니다. 그러나 나는 이것을위한 해결책이 있는지 알고 싶다. 어떤 식 으로든 코드를 작성할 수 있거나 서비스가 DEL 또는 ERASE를 선택하게하는 Windows 상자에서 변경할 수있는 구성이 있습니다.Windows ERASE 명령이 Windows Server의 FileSystemWatcher에 이벤트를 등록하지 않는 이유는 무엇입니까?

using System; 
using System.IO; 
using System.Runtime.Serialization; 

namespace GatewayEDI.ClaimRouter.FileManagement 
{ 
    public delegate void FileChangedEventHandler(object sender, FileChangedEventArgs e); 

    public enum Status 
    { 
     Added, 
     Changed, 
     Deleted, 
     Unknown 
    } 

    public class FolderWatcher : IDisposable 
    { 
     protected FileSystemWatcher Watcher; 

     public Status FileStatus 
     { 
      get; 
      set; 
     } 

     public event FileChangedEventHandler FileChanged; 

     public virtual void OnHasFileChanged(FileChangedEventArgs e) 
     { 
      FileChangedEventHandler fileChanged = FileChanged; 
      if (fileChanged != null) 
      { 
       fileChanged(this, e); 
      } 
     } 

     public FolderWatcher(string path, string file) 
     { 
      FileStatus = Status.Unknown; 
      if (!string.IsNullOrEmpty(path) && !string.IsNullOrEmpty(file)) 
       CreateFileSystemWatcher(path, file); 
     } 

     private void CreateFileSystemWatcher(string path, string file) 
     { 
      Watcher = new FileSystemWatcher(); 

      try 
      { 
       if (path.LastIndexOf("\\", StringComparison.CurrentCulture) < path.Length - 1) 
        path += "\\"; 

       Watcher.Path = path; 
       Watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.DirectoryName | NotifyFilters.LastAccess | NotifyFilters.LastWrite; 
       Watcher.Filter = file; 

       Watcher.Created += WatcherChanged; 
       Watcher.Changed += WatcherChanged; 
       Watcher.Renamed += WatcherChanged; 
       Watcher.Deleted += WatcherChanged; 
       Watcher.Error += WatcherError; 
       Watcher.EnableRaisingEvents = true; 
      } 
      catch (Exception ex) 
      { 
       FileStatus = Status.Unknown; 
       throw new FolderWatcherException("Unexpected exception searching file. Path = " + Watcher.Path + ". Error = " + ex.Message, ex); 
      } 
     } 

     void WatcherError(object sender, ErrorEventArgs e) 
     { 
      FileStatus = Status.Unknown; 
      SendFileChangedEvent(); 
     } 

     void WatcherChanged(object sender, FileSystemEventArgs e) 
     { 
      switch (e.ChangeType) 
      { 
       case WatcherChangeTypes.Created: 
        FileStatus = Status.Added; 
        break; 
       case WatcherChangeTypes.Changed: 
        FileStatus = Status.Changed; 
        break; 
       case WatcherChangeTypes.Renamed: 
        FileStatus = e.Name.Equals(Watcher.Filter) ? Status.Added : Status.Deleted; 
        break; 
       case WatcherChangeTypes.Deleted: 
        FileStatus = Status.Deleted; 
        break; 
       default: 
        FileStatus = Status.Unknown; 
        break; 
      } 

      SendFileChangedEvent(); 
     } 

     protected void SendFileChangedEvent() 
     { 
      string fileName = Watcher == null ? string.Empty : Watcher.Filter; 
      FileChangedEventArgs args = new FileChangedEventArgs 
      { 
       FileStatus = FileStatus, 
       FileName = fileName 
      }; 
      OnHasFileChanged(args); 
     } 

     public void DeleteFile() 
     { 
      FileInfo fi = new FileInfo(Watcher.Path + Watcher.Filter); 
      try 
      { 
       fi.Delete(); 
      } 
      catch (Exception ex) 
      { 
       throw new FolderWatcherException("Error deleting file. Path = " + Watcher.Path + ", File = " + Watcher.Filter + ". Error = " + ex.Message, ex); 
      } 
     } 

     private bool _alreadyDisposed; 

     public void Dispose() 
     { 
      Dispose(true); 
      GC.SuppressFinalize(this); 
     } 

     protected virtual void Dispose(bool isDisposing) 
     { 
      if (_alreadyDisposed) 
       return; 
      if (isDisposing) 
      { 
       if (Watcher != null) 
        Watcher.Dispose(); 
      } 
      _alreadyDisposed = true; 
     } 

     ~FolderWatcher() 
     { 
      Dispose(false); 
     } 
    } 

    [Serializable] 
    public class FolderWatcherException : Exception 
    { 
     public FolderWatcherException() 
     { 
     } 

     public FolderWatcherException(string message) : base(message) 
     { 
     } 

     public FolderWatcherException(string message, Exception inner) : base(message, inner) 
     { 
     } 

     protected FolderWatcherException(SerializationInfo info, StreamingContext context) : base(info, context) 
     { 
     } 
    } 
} 

윈도우 내가 파일을 수정하는 데 사용하는 명령입니다 : : 여기 (코멘트 간결 제거) 내 파일 감시자의 코드는,

Create: echo creating main flag > Main.flg 
Delete: DEL Main.flg 
Rename: REN Main.flg Main1.flg 

난은 FileSystemWatcher 어느 정도 신뢰할 수 있다는 것을 인식하지만, 이 경우 지속적으로 문제를 재현 할 수 있습니다. 시간이 허락하는 어느 시점에서, 우리는이 파일 감시 구성 요소를 좀 더 안정된 것으로 대체 할 것입니다.

+0

FWIW - 제대로 구성된 FileSystemWatcher가 신뢰할 수 없다는 것을 결코 발견하지 못했습니다. – pmartin

답변

0

나는이 문제를 자체 Windows Server 2008 R2 상자에서 재현 할 수 있는지 확인하기 위해 작은 프로그램을 작성했습니다. 내가 모니터링 된 디렉토리에서

using System; 
using System.IO; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      FileSystemWatcher fsw = new FileSystemWatcher(); 
      fsw.Path = @"D:\test"; 
      fsw.Deleted += new FileSystemEventHandler(ReportChange); 
      fsw.Created += new FileSystemEventHandler(ReportChange); 
      fsw.EnableRaisingEvents = true; 

      Console.In.ReadLine(); 
     } 

     private static void ReportChange(object source, FileSystemEventArgs e) 
     { 
      // Specify what is done when a file is created or deleted. 
      Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType); 
     } 
    } 
} 

내 코드 위를 성공적으로보고 파일 삭제 : 여기에 내 코드입니다.

코드를 자세히 살펴보면 FSW에게 모니터링 할 파일을 정확히 알려주는 것처럼 보입니다. 나에게 이것은 타이밍 문제와 같이 보인다. 붙여 넣은 코드를 기반으로 FSW를 만드는 과정에서 파일을 삭제하는 과정을 이해할 수 없습니다. FSW가보고 싶은 파일이 삭제되기 전에 FSW가 생성, 초기화 및 활성화되는지 확신합니까? 내 의심은 파일이 먼저 삭제 된 다음 FSW가 실제로 존재하지 않는 특정 파일을 모니터링하도록 만들어지고 있다는 것입니다.

+0

프로그램을 실행하면 문제를 파악하는 데 도움이되었습니다. 그것은 16 비트 이름입니다. 내 파일 이름은 MainQueue.flg이고 삭제시 MAINQU ~ 1.FLG로 기록됩니다. 내 파일 이름이 16 비트 DEL 명령에 비해 너무 깁니다. 내 서비스에서 특정 파일 이름에 대한 활동을 찾고 있으므로 이벤트가 발생하면 일치하지 않습니다. –

관련 문제