1
2
3
4
5
6 using System;
7 using System.Collections;
8 using System.Windows.API;
9
10 namespace System.Windows.IO
11 {
12 public delegate void DirectoryChangedFunction(const string& directoryPath);
13
14 public class delegate void DirectoryChangedMethod(const string& directoryPath);
15
16 public class DirectoryChangeNotifier
17 {
18 public nothrow DirectoryChangeNotifier() :
19 notificationHandle(null), waitCanceledEventHandle(null), directoryPath(), firstTime(true), waiting(false)
20 {
21 }
22 public nothrow DirectoryChangeNotifier(void* notificationHandle_, const string& directoryPath_) :
23 notificationHandle(notificationHandle_), waitCanceledEventHandle(CreateEvent()), directoryPath(directoryPath_), firstTime(true), waiting(false)
24 {
25 }
26 public ~DirectoryChangeNotifier()
27 {
28 try
29 {
30 if (waiting)
31 {
32 CancelWait();
33 }
34 if (notificationHandle != null)
35 {
36 FindCloseChangeNotification(notificationHandle);
37 }
38 if (waitCanceledEventHandle != null)
39 {
40 CloseEvent(waitCanceledEventHandle);
41 }
42 }
43 catch (const Exception&)
44 {
45 }
46 }
47 public suppress DirectoryChangeNotifier(const DirectoryChangeNotifier&);
48 public suppress void operator=(const DirectoryChangeNotifier&);
49 public DirectoryChangeNotifier(DirectoryChangeNotifier&& that) :
50 notificationHandle(that.notificationHandle), waitCanceledEventHandle(that.waitCanceledEventHandle), directoryPath(that.directoryPath), firstTime(that.firstTime), waiting(that.waiting)
51 {
52 that.notificationHandle = null;
53 that.waitCanceledEventHandle = null;
54 that.directoryPath.Clear();
55 that.firstTime = false;
56 that.waiting = false;
57 }
58 public default nothrow void operator=(DirectoryChangeNotifier&& that);
59 public void WaitAndCallWhenDirectoryChanged(DirectoryChangedFunction callback)
60 {
61 if (WaitUntilDirectoryChangedOrWaitCanceled())
62 {
63 callback(directoryPath);
64 }
65 }
66 public void WaitAndCallWhenDirectoryChanged(DirectoryChangedMethod callback)
67 {
68 if (WaitUntilDirectoryChangedOrWaitCanceled())
69 {
70 callback(directoryPath);
71 }
72 }
73 public bool WaitUntilDirectoryChangedOrWaitCanceled()
74 {
75 if (firstTime)
76 {
77 firstTime = false;
78 }
79 else
80 {
81 FindNextChangeNotification(notificationHandle);
82 }
83 List<void*> handles;
84 handles.Add(notificationHandle);
85 handles.Add(waitCanceledEventHandle);
86 waiting = true;
87 int index = WaitForMultipleObjects(handles);
88 waiting = false;
89 return index == 0;
90 }
91 public void CancelWait()
92 {
93 if (waiting)
94 {
95 waiting = false;
96 SetEvent(waitCanceledEventHandle);
97 }
98 }
99 void* notificationHandle;
100 void* waitCanceledEventHandle;
101 string directoryPath;
102 bool firstTime;
103 bool waiting;
104 }
105
106 public static class Directory
107 {
108 public static DirectoryChangeNotifier NotifyChanged(const string& directoryPath)
109 {
110 if (System.IO.Directory.Exists(directoryPath))
111 {
112 void* handle = FindFirstChangeNotification(directoryPath);
113 return DirectoryChangeNotifier(handle, directoryPath);
114 }
115 else
116 {
117 throw System.IO.FileSystemException("directory '" + directoryPath + "' does not exist");
118 }
119 }
120 }
121 }