Statistics
| Branch: | Revision:

root / trunk / Pithos.Core / NativeMethods.cs @ 73cdd135

History | View | Annotate | Download (13.3 kB)

1
using System;
2
using System.Collections.Generic;
3
using System.IO;
4
using System.Linq;
5
using System.Runtime.InteropServices;
6
using System.Text;
7

    
8
namespace Pithos.Core
9
{
10
    #region Enums & Structs
11

    
12
    #region enum HChangeNotifyEventID
13
    /// <summary>
14
    /// Describes the event that has occurred. 
15
    /// Typically, only one event is specified at a time. 
16
    /// If more than one event is specified, the values contained 
17
    /// in the <i>dwItem1</i> and <i>dwItem2</i> 
18
    /// parameters must be the same, respectively, for all specified events. 
19
    /// This parameter can be one or more of the following values. 
20
    /// </summary>
21
    /// <remarks>
22
    /// <para><b>Windows NT/2000/XP:</b> <i>dwItem2</i> contains the index 
23
    /// in the system image list that has changed. 
24
    /// <i>dwItem1</i> is not used and should be <see langword="null"/>.</para>
25
    /// <para><b>Windows 95/98:</b> <i>dwItem1</i> contains the index 
26
    /// in the system image list that has changed. 
27
    /// <i>dwItem2</i> is not used and should be <see langword="null"/>.</para>
28
    /// </remarks>
29
    [Flags]
30
    public enum HChangeNotifyEventID
31
    {
32
        /// <summary>
33
        /// All events have occurred. 
34
        /// </summary>
35
        SHCNE_ALLEVENTS = 0x7FFFFFFF,
36

    
37
        /// <summary>
38
        /// A file type association has changed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
39
        /// must be specified in the <i>uFlags</i> parameter. 
40
        /// <i>dwItem1</i> and <i>dwItem2</i> are not used and must be <see langword="null"/>. 
41
        /// </summary>
42
        SHCNE_ASSOCCHANGED = 0x08000000,
43

    
44
        /// <summary>
45
        /// The attributes of an item or folder have changed. 
46
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
47
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
48
        /// <i>dwItem1</i> contains the item or folder that has changed. 
49
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
50
        /// </summary>
51
        SHCNE_ATTRIBUTES = 0x00000800,
52

    
53
        /// <summary>
54
        /// A nonfolder item has been created. 
55
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
56
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
57
        /// <i>dwItem1</i> contains the item that was created. 
58
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>.
59
        /// </summary>
60
        SHCNE_CREATE = 0x00000002,
61

    
62
        /// <summary>
63
        /// A nonfolder item has been deleted. 
64
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
65
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
66
        /// <i>dwItem1</i> contains the item that was deleted. 
67
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
68
        /// </summary>
69
        SHCNE_DELETE = 0x00000004,
70

    
71
        /// <summary>
72
        /// A drive has been added. 
73
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
74
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
75
        /// <i>dwItem1</i> contains the root of the drive that was added. 
76
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
77
        /// </summary>
78
        SHCNE_DRIVEADD = 0x00000100,
79

    
80
        /// <summary>
81
        /// A drive has been added and the Shell should create a new window for the drive. 
82
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
83
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
84
        /// <i>dwItem1</i> contains the root of the drive that was added. 
85
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
86
        /// </summary>
87
        SHCNE_DRIVEADDGUI = 0x00010000,
88

    
89
        /// <summary>
90
        /// A drive has been removed. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
91
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
92
        /// <i>dwItem1</i> contains the root of the drive that was removed.
93
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
94
        /// </summary>
95
        SHCNE_DRIVEREMOVED = 0x00000080,
96

    
97
        /// <summary>
98
        /// Not currently used. 
99
        /// </summary>
100
        SHCNE_EXTENDED_EVENT = 0x04000000,
101

    
102
        /// <summary>
103
        /// The amount of free space on a drive has changed. 
104
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
105
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
106
        /// <i>dwItem1</i> contains the root of the drive on which the free space changed.
107
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
108
        /// </summary>
109
        SHCNE_FREESPACE = 0x00040000,
110

    
111
        /// <summary>
112
        /// Storage media has been inserted into a drive. 
113
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
114
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
115
        /// <i>dwItem1</i> contains the root of the drive that contains the new media. 
116
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
117
        /// </summary>
118
        SHCNE_MEDIAINSERTED = 0x00000020,
119

    
120
        /// <summary>
121
        /// Storage media has been removed from a drive. 
122
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
123
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
124
        /// <i>dwItem1</i> contains the root of the drive from which the media was removed. 
125
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
126
        /// </summary>
127
        SHCNE_MEDIAREMOVED = 0x00000040,
128

    
129
        /// <summary>
130
        /// A folder has been created. <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> 
131
        /// or <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
132
        /// <i>dwItem1</i> contains the folder that was created. 
133
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
134
        /// </summary>
135
        SHCNE_MKDIR = 0x00000008,
136

    
137
        /// <summary>
138
        /// A folder on the local computer is being shared via the network. 
139
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
140
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
141
        /// <i>dwItem1</i> contains the folder that is being shared. 
142
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
143
        /// </summary>
144
        SHCNE_NETSHARE = 0x00000200,
145

    
146
        /// <summary>
147
        /// A folder on the local computer is no longer being shared via the network. 
148
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
149
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
150
        /// <i>dwItem1</i> contains the folder that is no longer being shared. 
151
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
152
        /// </summary>
153
        SHCNE_NETUNSHARE = 0x00000400,
154

    
155
        /// <summary>
156
        /// The name of a folder has changed. 
157
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
158
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
159
        /// <i>dwItem1</i> contains the previous pointer to an item identifier list (PIDL) or name of the folder. 
160
        /// <i>dwItem2</i> contains the new PIDL or name of the folder. 
161
        /// </summary>
162
        SHCNE_RENAMEFOLDER = 0x00020000,
163

    
164
        /// <summary>
165
        /// The name of a nonfolder item has changed. 
166
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
167
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
168
        /// <i>dwItem1</i> contains the previous PIDL or name of the item. 
169
        /// <i>dwItem2</i> contains the new PIDL or name of the item. 
170
        /// </summary>
171
        SHCNE_RENAMEITEM = 0x00000001,
172

    
173
        /// <summary>
174
        /// A folder has been removed. 
175
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
176
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
177
        /// <i>dwItem1</i> contains the folder that was removed. 
178
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
179
        /// </summary>
180
        SHCNE_RMDIR = 0x00000010,
181

    
182
        /// <summary>
183
        /// The computer has disconnected from a server. 
184
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
185
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
186
        /// <i>dwItem1</i> contains the server from which the computer was disconnected. 
187
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
188
        /// </summary>
189
        SHCNE_SERVERDISCONNECT = 0x00004000,
190

    
191
        /// <summary>
192
        /// The contents of an existing folder have changed, 
193
        /// but the folder still exists and has not been renamed. 
194
        /// <see cref="HChangeNotifyFlags.SHCNF_IDLIST"/> or 
195
        /// <see cref="HChangeNotifyFlags.SHCNF_PATH"/> must be specified in <i>uFlags</i>. 
196
        /// <i>dwItem1</i> contains the folder that has changed. 
197
        /// <i>dwItem2</i> is not used and should be <see langword="null"/>. 
198
        /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or 
199
        /// SHCNE_RENAMEFOLDER, respectively, instead. 
200
        /// </summary>
201
        SHCNE_UPDATEDIR = 0x00001000,
202

    
203
        SHCNE_UPDATEITEM = 0x00002000,
204

    
205
        /// <summary>
206
        /// An image in the system image list has changed. 
207
        /// <see cref="HChangeNotifyFlags.SHCNF_DWORD"/> must be specified in <i>uFlags</i>. 
208
        /// </summary>
209
        SHCNE_UPDATEIMAGE = 0x00008000,
210

    
211
    }
212
    #endregion // enum HChangeNotifyEventID
213

    
214
    #region public enum HChangeNotifyFlags
215
    /// <summary>
216
    /// Flags that indicate the meaning of the <i>dwItem1</i> and <i>dwItem2</i> parameters. 
217
    /// The uFlags parameter must be one of the following values.
218
    /// </summary>
219
    [Flags]
220
    public enum HChangeNotifyFlags
221
    {
222
        /// <summary>
223
        /// The <i>dwItem1</i> and <i>dwItem2</i> parameters are DWORD values. 
224
        /// </summary>
225
        SHCNF_DWORD = 0x0003,
226
        /// <summary>
227
        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of ITEMIDLIST structures that 
228
        /// represent the item(s) affected by the change. 
229
        /// Each ITEMIDLIST must be relative to the desktop folder. 
230
        /// </summary>
231
        SHCNF_IDLIST = 0x0000,
232
        /// <summary>
233
        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
234
        /// maximum length MAX_PATH that contain the full path names 
235
        /// of the items affected by the change. 
236
        /// </summary>
237
        SHCNF_PATHA = 0x0001,
238
        /// <summary>
239
        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings of 
240
        /// maximum length MAX_PATH that contain the full path names 
241
        /// of the items affected by the change. 
242
        /// </summary>
243
        SHCNF_PATHW = 0x0005,
244
        /// <summary>
245
        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
246
        /// represent the friendly names of the printer(s) affected by the change. 
247
        /// </summary>
248
        SHCNF_PRINTERA = 0x0002,
249
        /// <summary>
250
        /// <i>dwItem1</i> and <i>dwItem2</i> are the addresses of null-terminated strings that 
251
        /// represent the friendly names of the printer(s) affected by the change. 
252
        /// </summary>
253
        SHCNF_PRINTERW = 0x0006,
254
        /// <summary>
255
        /// The function should not return until the notification 
256
        /// has been delivered to all affected components. 
257
        /// As this flag modifies other data-type flags, it cannot by used by itself.
258
        /// </summary>
259
        SHCNF_FLUSH = 0x1000,
260
        /// <summary>
261
        /// The function should begin delivering notifications to all affected components 
262
        /// but should return as soon as the notification process has begun. 
263
        /// As this flag modifies other data-type flags, it cannot by used by itself.
264
        /// </summary>
265
        SHCNF_FLUSHNOWAIT = 0x2000
266
    }
267
    #endregion // enum HChangeNotifyFlags
268

    
269

    
270
    #endregion
271

    
272
    public static class NativeMethods
273
    {
274
        [DllImport("shell32.dll")]
275
        public static extern void SHChangeNotify(HChangeNotifyEventID wEventId,
276
                                           HChangeNotifyFlags uFlags,
277
                                           IntPtr dwItem1,
278
                                           IntPtr dwItem2);
279

    
280
        public static void RaiseChangeNotification(string path)
281
        {
282
            if (String.IsNullOrWhiteSpace(path))
283
                throw new ArgumentNullException("path", "The path parameter must not be emtpy");
284

    
285
            if (!Directory.Exists(path) && !File.Exists(path))
286
                return;
287

    
288

    
289
            IntPtr pathPointer = Marshal.StringToCoTaskMemAuto(path);
290

    
291
            try
292
            {
293
                NativeMethods.SHChangeNotify(HChangeNotifyEventID.SHCNE_UPDATEITEM,
294
                                             HChangeNotifyFlags.SHCNF_PATHW | HChangeNotifyFlags.SHCNF_FLUSHNOWAIT,
295
                                             pathPointer, IntPtr.Zero);
296
            }
297
            finally
298
            {
299
                Marshal.FreeHGlobal(pathPointer);
300
            }
301

    
302
        }
303
    }
304

    
305

    
306
}