@@ -166,6 +166,25 @@ public async Task<IStorageHistory> CopyItemsAsync(IList<IStorageItemWithPath> so
166
166
var lockingProcess = await WhoIsLockingAsync ( failedSources . Select ( x => x . HResult == HResult . COPYENGINE_E_SHARING_VIOLATION_SRC ? x . Source : x . Destination ) ) ;
167
167
await DialogDisplayHelper . ShowDialogAsync ( "FileInUseDeleteDialog/Title" . GetLocalized ( ) , lockingProcess != null ? string . Join ( Environment . NewLine , lockingProcess . Select ( x => $ "Name: { x . Name } , PID: { x . Pid } ") ) : "" ) ;
168
168
}
169
+ else if ( copyResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) )
170
+ {
171
+ // Retry with StorageFile API
172
+ var failedSources = copyResult . Items . Where ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) ;
173
+ var copyZip = sourceNoSkip . Zip ( destinationNoSkip , ( src , dest ) => new { src , dest } ) . Zip ( collisionsNoSkip , ( z1 , coll ) => new { z1 . src , z1 . dest , coll } ) ;
174
+ var sourceMatch = await failedSources . Select ( x => copyZip . SingleOrDefault ( s => s . src . Path . Equals ( x . Source , StringComparison . OrdinalIgnoreCase ) ) ) . Where ( x => x != null ) . ToListAsync ( ) ;
175
+ return await filesystemOperations . CopyItemsAsync (
176
+ await sourceMatch . Select ( x => x . src ) . ToListAsync ( ) ,
177
+ await sourceMatch . Select ( x => x . dest ) . ToListAsync ( ) ,
178
+ await sourceMatch . Select ( x => x . coll ) . ToListAsync ( ) , progress , errorCode , cancellationToken ) ;
179
+ }
180
+ else if ( copyResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NotFound ) )
181
+ {
182
+ await DialogDisplayHelper . ShowDialogAsync ( "FileNotFoundDialog/Title" . GetLocalized ( ) , "FileNotFoundDialog/Text" . GetLocalized ( ) ) ;
183
+ }
184
+ else if ( copyResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . AlreadyExists ) )
185
+ {
186
+ await DialogDisplayHelper . ShowDialogAsync ( "ItemAlreadyExistsDialogTitle" . GetLocalized ( ) , "ItemAlreadyExistsDialogContent" . GetLocalized ( ) ) ;
187
+ }
169
188
errorCode ? . Report ( HResult . Convert ( copyResult . Items . FirstOrDefault ( x => ! x . Succeeded ) ? . HResult ) ) ;
170
189
return null ;
171
190
}
@@ -254,6 +273,19 @@ public async Task<IStorageHistory> CopyItemsAsync(IList<IStorageItemWithPath> so
254
273
return await CreateAsync ( source , errorCode , cancellationToken ) ;
255
274
}
256
275
}
276
+ else if ( createResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) )
277
+ {
278
+ // Retry with StorageFile API
279
+ return await filesystemOperations . CreateAsync ( source , errorCode , cancellationToken ) ;
280
+ }
281
+ else if ( createResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NotFound ) )
282
+ {
283
+ await DialogDisplayHelper . ShowDialogAsync ( "FileNotFoundDialog/Title" . GetLocalized ( ) , "FileNotFoundDialog/Text" . GetLocalized ( ) ) ;
284
+ }
285
+ else if ( createResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . AlreadyExists ) )
286
+ {
287
+ await DialogDisplayHelper . ShowDialogAsync ( "ItemAlreadyExistsDialogTitle" . GetLocalized ( ) , "ItemAlreadyExistsDialogContent" . GetLocalized ( ) ) ;
288
+ }
257
289
errorCode ? . Report ( HResult . Convert ( createResult . Items . FirstOrDefault ( x => ! x . Succeeded ) ? . HResult ) ) ;
258
290
return ( null , null ) ;
259
291
}
@@ -397,6 +429,17 @@ public async Task<IStorageHistory> DeleteItemsAsync(IList<IStorageItemWithPath>
397
429
var lockingProcess = await WhoIsLockingAsync ( failedSources . Select ( x => x . HResult == HResult . COPYENGINE_E_SHARING_VIOLATION_SRC ? x . Source : x . Destination ) ) ;
398
430
await DialogDisplayHelper . ShowDialogAsync ( "FileInUseDeleteDialog/Title" . GetLocalized ( ) , lockingProcess != null ? string . Join ( Environment . NewLine , lockingProcess . Select ( x => $ "Name: { x . Name } , PID: { x . Pid } ") ) : "" ) ;
399
431
}
432
+ else if ( deleteResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) )
433
+ {
434
+ // Abort, path is too long for recycle bin
435
+ //var failedSources = deleteResult.Items.Where(x => HResult.Convert(x.HResult) == FileSystemStatusCode.NameTooLong);
436
+ //var sourceMatch = await failedSources.Select(x => source.DistinctBy(x => x.Path).SingleOrDefault(s => s.Path.Equals(x.Source, StringComparison.OrdinalIgnoreCase))).Where(x => x != null).ToListAsync();
437
+ //return await filesystemOperations.DeleteItemsAsync(sourceMatch, progress, errorCode, permanently, cancellationToken);
438
+ }
439
+ else if ( deleteResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NotFound ) )
440
+ {
441
+ await DialogDisplayHelper . ShowDialogAsync ( "FileNotFoundDialog/Title" . GetLocalized ( ) , "FileNotFoundDialog/Text" . GetLocalized ( ) ) ;
442
+ }
400
443
errorCode ? . Report ( HResult . Convert ( deleteResult . Items . FirstOrDefault ( x => ! x . Succeeded ) ? . HResult ) ) ;
401
444
return null ;
402
445
}
@@ -515,13 +558,38 @@ public async Task<IStorageHistory> MoveItemsAsync(IList<IStorageItemWithPath> so
515
558
return await MoveItemsAsync ( source , destination , collisions , progress , errorCode , cancellationToken ) ;
516
559
}
517
560
}
561
+ else if ( source . Zip ( destination , ( src , dest ) => ( src , dest ) ) . FirstOrDefault ( x => x . src . ItemType == FilesystemItemType . Directory && PathNormalization . GetParentDir ( x . dest ) . IsSubPathOf ( x . src . Path ) ) is ( IStorageItemWithPath , string ) subtree )
562
+ {
563
+ var destName = subtree . dest . Split ( Path . DirectorySeparatorChar , StringSplitOptions . RemoveEmptyEntries ) . Last ( ) ;
564
+ var srcName = subtree . src . Path . Split ( Path . DirectorySeparatorChar , StringSplitOptions . RemoveEmptyEntries ) . Last ( ) ;
565
+ await DialogDisplayHelper . ShowDialogAsync ( "ErrorDialogThisActionCannotBeDone" . GetLocalized ( ) , $ "{ "ErrorDialogTheDestinationFolder" . GetLocalized ( ) } ({ destName } ) { "ErrorDialogIsASubfolder" . GetLocalized ( ) } ({ srcName } )") ;
566
+ }
518
567
else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . InUse ) )
519
568
{
520
569
// TODO: proper dialog, retry
521
570
var failedSources = moveResult . Items . Where ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . InUse ) ;
522
571
var lockingProcess = await WhoIsLockingAsync ( failedSources . Select ( x => x . HResult == HResult . COPYENGINE_E_SHARING_VIOLATION_SRC ? x . Source : x . Destination ) ) ;
523
572
await DialogDisplayHelper . ShowDialogAsync ( "FileInUseDeleteDialog/Title" . GetLocalized ( ) , lockingProcess != null ? string . Join ( Environment . NewLine , lockingProcess . Select ( x => $ "Name: { x . Name } , PID: { x . Pid } ") ) : "" ) ;
524
573
}
574
+ else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) )
575
+ {
576
+ // Retry with StorageFile API
577
+ var failedSources = moveResult . Items . Where ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) ;
578
+ var moveZip = sourceNoSkip . Zip ( destinationNoSkip , ( src , dest ) => new { src , dest } ) . Zip ( collisionsNoSkip , ( z1 , coll ) => new { z1 . src , z1 . dest , coll } ) ;
579
+ var sourceMatch = await failedSources . Select ( x => moveZip . SingleOrDefault ( s => s . src . Path . Equals ( x . Source , StringComparison . OrdinalIgnoreCase ) ) ) . Where ( x => x != null ) . ToListAsync ( ) ;
580
+ return await filesystemOperations . MoveItemsAsync (
581
+ await sourceMatch . Select ( x => x . src ) . ToListAsync ( ) ,
582
+ await sourceMatch . Select ( x => x . dest ) . ToListAsync ( ) ,
583
+ await sourceMatch . Select ( x => x . coll ) . ToListAsync ( ) , progress , errorCode , cancellationToken ) ;
584
+ }
585
+ else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NotFound ) )
586
+ {
587
+ await DialogDisplayHelper . ShowDialogAsync ( "FileNotFoundDialog/Title" . GetLocalized ( ) , "FileNotFoundDialog/Text" . GetLocalized ( ) ) ;
588
+ }
589
+ else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . AlreadyExists ) )
590
+ {
591
+ await DialogDisplayHelper . ShowDialogAsync ( "ItemAlreadyExistsDialogTitle" . GetLocalized ( ) , "ItemAlreadyExistsDialogContent" . GetLocalized ( ) ) ;
592
+ }
525
593
errorCode ? . Report ( HResult . Convert ( moveResult . Items . FirstOrDefault ( x => ! x . Succeeded ) ? . HResult ) ) ;
526
594
return null ;
527
595
}
@@ -586,6 +654,19 @@ public async Task<IStorageHistory> RenameAsync(IStorageItemWithPath source, stri
586
654
var lockingProcess = await WhoIsLockingAsync ( failedSources . Select ( x => x . HResult == HResult . COPYENGINE_E_SHARING_VIOLATION_SRC ? x . Source : x . Destination ) ) ;
587
655
await DialogDisplayHelper . ShowDialogAsync ( "FileInUseDeleteDialog/Title" . GetLocalized ( ) , lockingProcess != null ? string . Join ( Environment . NewLine , lockingProcess . Select ( x => $ "Name: { x . Name } , PID: { x . Pid } ") ) : "" ) ;
588
656
}
657
+ else if ( renameResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) )
658
+ {
659
+ // Retry with StorageFile API
660
+ return await filesystemOperations . RenameAsync ( source , newName , collision , errorCode , cancellationToken ) ;
661
+ }
662
+ else if ( renameResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NotFound ) )
663
+ {
664
+ await DialogDisplayHelper . ShowDialogAsync ( "RenameError/ItemDeleted/Title" . GetLocalized ( ) , "RenameError/ItemDeleted/Text" . GetLocalized ( ) ) ;
665
+ }
666
+ else if ( renameResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . AlreadyExists ) )
667
+ {
668
+ await DialogDisplayHelper . ShowDialogAsync ( "ItemAlreadyExistsDialogTitle" . GetLocalized ( ) , "ItemAlreadyExistsDialogContent" . GetLocalized ( ) ) ;
669
+ }
589
670
errorCode ? . Report ( HResult . Convert ( renameResult . Items . FirstOrDefault ( x => ! x . Succeeded ) ? . HResult ) ) ;
590
671
return null ;
591
672
}
@@ -681,6 +762,24 @@ public async Task<IStorageHistory> RestoreItemsFromTrashAsync(IList<IStorageItem
681
762
var lockingProcess = await WhoIsLockingAsync ( failedSources . Select ( x => x . HResult == HResult . COPYENGINE_E_SHARING_VIOLATION_SRC ? x . Source : x . Destination ) ) ;
682
763
await DialogDisplayHelper . ShowDialogAsync ( "FileInUseDeleteDialog/Title" . GetLocalized ( ) , lockingProcess != null ? string . Join ( Environment . NewLine , lockingProcess . Select ( x => $ "Name: { x . Name } , PID: { x . Pid } ") ) : "" ) ;
683
764
}
765
+ else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) )
766
+ {
767
+ // Retry with StorageFile API
768
+ var failedSources = moveResult . Items . Where ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NameTooLong ) ;
769
+ var moveZip = source . Zip ( destination , ( src , dest ) => new { src , dest } ) ;
770
+ var sourceMatch = await failedSources . Select ( x => moveZip . SingleOrDefault ( s => s . src . Path . Equals ( x . Source , StringComparison . OrdinalIgnoreCase ) ) ) . Where ( x => x != null ) . ToListAsync ( ) ;
771
+ return await filesystemOperations . RestoreItemsFromTrashAsync (
772
+ await sourceMatch . Select ( x => x . src ) . ToListAsync ( ) ,
773
+ await sourceMatch . Select ( x => x . dest ) . ToListAsync ( ) , progress , errorCode , cancellationToken ) ;
774
+ }
775
+ else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . NotFound ) )
776
+ {
777
+ await DialogDisplayHelper . ShowDialogAsync ( "FileNotFoundDialog/Title" . GetLocalized ( ) , "FileNotFoundDialog/Text" . GetLocalized ( ) ) ;
778
+ }
779
+ else if ( moveResult . Items . Any ( x => HResult . Convert ( x . HResult ) == FileSystemStatusCode . AlreadyExists ) )
780
+ {
781
+ await DialogDisplayHelper . ShowDialogAsync ( "ItemAlreadyExistsDialogTitle" . GetLocalized ( ) , "ItemAlreadyExistsDialogContent" . GetLocalized ( ) ) ;
782
+ }
684
783
errorCode ? . Report ( HResult . Convert ( moveResult . Items . FirstOrDefault ( x => ! x . Succeeded ) ? . HResult ) ) ;
685
784
return null ;
686
785
}
@@ -795,7 +894,6 @@ private struct HResult
795
894
//public const int COPYENGINE_E_SAME_FILE = -2144927741;
796
895
//public const int COPYENGINE_E_DEST_SAME_TREE = -2144927734;
797
896
//public const int COPYENGINE_E_DEST_SUBTREE = -2144927735;
798
- //public const int COPYENGINE_E_DIFF_DIR = -2144927740;
799
897
800
898
public static FileSystemStatusCode Convert ( int ? hres )
801
899
{
0 commit comments