public void CopyFile(IFile file, bool synchronous) { var copy_options = 4 | 16 | 512 | 1024; var andoid = file as PortableFile; var win = file as WinFile; // it can either be android or windows Debug.Assert(andoid != null || win != null); FolderItem dest_item = null; var souce_name = file.Name; if (andoid != null) { dest_item = andoid.RawFolderItem(); } else if (win != null) { var WinFile_name = new FileInfo(win.FullPath); var shell_folder = WinUtil.GetShell32Folder(WinFile_name.DirectoryName); var shell_file = shell_folder.ParseName(WinFile_name.Name); Debug.Assert(shell_file != null); dest_item = shell_file; } // Windows stupidity - if file exists, it will display a stupid "Do you want to replace" dialog, // even if we speicifically told it not to (via the copy options) // // so, if file exists, delete it first var existing_name = (fi_.GetFolder as Folder).ParseName(souce_name); if (existing_name != null) { WinUtil.DeleteSyncPortableFile(existing_name); } (fi_.GetFolder as Folder).CopyHere(dest_item, copy_options); if (synchronous) { WinUtil.WaitForPortableCopyComplete(FullPath + "\\" + souce_name, file.Size); } }
private static void BulkCopy(IEnumerable <IFile> src_files, string dest_folder_name, bool synchronous, Action <string, int, int> copy_complete_callback) { dest_folder_name = dest_folder_name.Replace("/", "\\"); Debug.Assert(!dest_folder_name.EndsWith("\\")); // in case destination does not exist, create it PDManager.Instance.NewFolder(dest_folder_name); Dictionary <string, List <IFile> > files_by_folder = new Dictionary <string, List <IFile> >(); foreach (var f in src_files) { var path = f.Folder.FullPath; if (!files_by_folder.ContainsKey(path)) { files_by_folder.Add(path, new List <IFile>()); } files_by_folder[path].Add(f); } var dest_folder = PDManager.Instance.ParseFolder(dest_folder_name); var all_src_win = src_files.All(f => f is WinFile); if (all_src_win && dest_folder is WinFolder) { BulkCopyWin(src_files.Select(f => (f as WinFile).FullPath).ToList(), dest_folder_name, synchronous, copy_complete_callback); return; } // // here, we know the source or dest or both are android Folder dest_parent_shell_folder = null; if (dest_folder is PortableFolder) { dest_parent_shell_folder = (dest_folder as PortableFolder).RawFolderItem().GetFolder as Folder; } else if (dest_folder is WinFolder) { dest_parent_shell_folder = WinUtil.GetShell32Folder((dest_folder as WinFolder).FullPath); } else { Debug.Assert(false); } int count = files_by_folder.Sum(f => f.Value.Count); int idx = 0; foreach (var f in files_by_folder) { var src_parent = f.Value[0].Folder; var src_parent_file_count = src_parent.Files.Count(); // filter can be specified by "file1;file2;file3.." string filter_spec = f.Value.Count == src_parent_file_count ? "*.*" : string.Join(";", f.Value.Select(n => n.Name)); Folder src_parent_shell_folder = null; if (src_parent is PortableFolder) { src_parent_shell_folder = (src_parent as PortableFolder).RawFolderItem().GetFolder as Folder; } else if (src_parent is WinFolder) { src_parent_shell_folder = WinUtil.GetShell32Folder((src_parent as WinFolder).FullPath); } else { Debug.Assert(false); } var src_items = src_parent_shell_folder.Items() as FolderItems3; // here, we filter only those files that you want from the source folder src_items.Filter(int.MaxValue & ~0x8000, filter_spec); // ... they're ignored, but still :) var copy_options = 4 | 16 | 512 | 1024; // note: we want to compute these beforehand (before the copy takes place) - if a file is being copied, access to it can be locked, // so even asking "f.name" will wait until the copy is 100% complete - which is NOT what we want List <CopyFileInfo> wait_complete = f.Value.Select(src => new CopyFileInfo { name = src.Name, size = src.Size }).ToList(); if (src_items.Count == f.Value.Count) { if (synchronous && copy_complete_callback != null) { Task.Run(() => dest_parent_shell_folder.CopyHere(src_items, copy_options)); } else { dest_parent_shell_folder.CopyHere(src_items, copy_options); } } else { // "amazing" - for Android, the filter spec doesn't work - we need to copy each of them separately Debug.Assert(f.Value[0] is PortableFile); foreach (var file in f.Value) { dest_parent_shell_folder.CopyHere((file as PortableFile).RawFolderItem(), copy_options); } } if (synchronous) { WaitForCopyComplete(wait_complete, count, ref idx, dest_folder_name, copy_complete_callback); } else if (copy_complete_callback != null) { // here, we're async, but with callback Task.Run(() => WaitForCopyComplete(wait_complete, count, ref idx, dest_folder_name, copy_complete_callback)); } } }
public static Folder get_my_computer() { return(WinUtil.GetShell32Folder(0x11)); }