@@ -179,6 +179,17 @@ private static void RunDialogTest()
179
179
msgbox . ShowDialog ( ) ;
180
180
}
181
181
182
+ private static int RemoveZoneIdentifer_Win32 ( string filepath )
183
+ {
184
+ string zoneIdentifier = filepath + ":Zone.Identifier" ;
185
+ bool success = NativeMethods . DeleteFile ( zoneIdentifier ) ;
186
+ if ( success )
187
+ return 0 ;
188
+
189
+ int error = Marshal . GetLastWin32Error ( ) ;
190
+ return error ;
191
+ }
192
+
182
193
private static void RemoveZoneIdentifer ( string directory )
183
194
{
184
195
// https://stackoverflow.com/a/6375373
@@ -187,29 +198,34 @@ private static void RemoveZoneIdentifer(string directory)
187
198
188
199
// Enumerate all files recursively
189
200
string [ ] files = Directory . GetFiles ( directory , "*" , SearchOption . AllDirectories ) ;
190
- string [ ] directories = Directory . GetDirectories ( directory , "*" , SearchOption . AllDirectories ) ;
191
201
192
- // For each file or directory , remove the Zone.Identifier alternate data stream
193
- foreach ( string file in files . Concat ( directories ) )
202
+ // For each file, remove the Zone.Identifier alternate data stream
203
+ foreach ( string file in files )
194
204
{
195
- FileInfo info = new FileInfo ( file ) ;
196
- bool statusBackUp = info . IsReadOnly ;
197
- info . IsReadOnly = false ;
205
+ int ret = RemoveZoneIdentifer_Win32 ( file ) ;
206
+ if ( ret == 0 )
207
+ continue ;
198
208
199
- string zoneIdentifier = file + ":Zone.Identifier" ;
200
- bool success = NativeMethods . DeleteFile ( zoneIdentifier ) ;
201
- if ( ! success )
202
- {
203
- int error = Marshal . GetLastWin32Error ( ) ;
204
- if ( error == NativeConstants . ERROR_FILE_NOT_FOUND )
205
- continue ;
209
+ // If the file doesn't exist, ignore it
210
+ if ( ret == NativeConstants . ERROR_FILE_NOT_FOUND )
211
+ continue ;
206
212
207
- string errorMessage = new Win32Exception ( error ) . Message ;
208
-
209
- failedMessages . Add ( $ "{ file } : { errorMessage } ") ;
213
+ // Try again, but temporarily remove the read-only attribute
214
+ if ( ret == NativeConstants . ERROR_ACCESS_DENIED )
215
+ {
216
+ FileInfo info = new ( file ) ;
217
+ if ( info . IsReadOnly )
218
+ {
219
+ info . IsReadOnly = false ;
220
+ ret = RemoveZoneIdentifer_Win32 ( file ) ;
221
+ info . IsReadOnly = true ;
222
+ if ( ret == 0 )
223
+ continue ;
224
+ }
210
225
}
211
226
212
- info . IsReadOnly = statusBackUp ;
227
+ string errorMessage = new Win32Exception ( ret ) . Message ;
228
+ failedMessages . Add ( $ "{ file } : { errorMessage } ") ;
213
229
}
214
230
215
231
if ( failedMessages . Count > 0 )
0 commit comments