Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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));
 }