private void _backupPerformer_StartedCopyingItem(FolderFileItem item)
 {
     if (_copyDataToProgressMap.ContainsKey(item))
     {
         var progressInfo = _copyDataToProgressMap[item];
         progressInfo.IsCopyInProgress = true;
     }
 }
 private void _backupPerformer_CalculatedBytesOfItem(FolderFileItem item, ulong bytes)
 {
     if (_copyDataToProgressMap.ContainsKey(item))
     {
         item.ByteSize = bytes;
         var progressInfo = _copyDataToProgressMap[item];
         progressInfo.TotalBytesToCopy = bytes;
         _totalBackupSize += bytes;
     }
 }
 private void _backupPerformer_CopiedBytesOfItem(FolderFileItem item, ulong bytes)
 {
     if (_copyDataToProgressMap.ContainsKey(item))
     {
         var progressInfo = _copyDataToProgressMap[item];
         progressInfo.BytesCopied += bytes;
         _bytesCopiedSoFar        += bytes;
         _currentProgress          = Math.Min((double)_bytesCopiedSoFar / (double)_totalBackupSize * 100, 100);
         NotifyPropertyChanged(nameof(CurrentProgressString));
     }
 }
Пример #4
0
 public ExcludeFilesFoldersViewModel(IChangeViewModel viewModelChanger, FolderFileItem itemBeingEdited) : base(viewModelChanger)
 {
     _itemBeingEdited = itemBeingEdited;
     _items           = new ObservableCollection <FolderFileItem>();
     foreach (var path in itemBeingEdited.ExcludedPaths)
     {
         Items.Add(new FolderFileItem()
         {
             Path        = path,
             IsDirectory = Directory.Exists(path)
         });
     }
 }
Пример #5
0
 // Modified from https://stackoverflow.com/a/33726939/3938401
 private void CopySingleFile(FolderFileItem itemBeingCopied, string source, string destination)
 {
     if (File.Exists(source))
     {
         if (HasBeenCanceled)
         {
             return;
         }
         if (UsesCompressedFile)
         {
         }
         else
         {
             using (var outStream = new FileStream(destination, FileMode.CreateNew, FileAccess.Write, FileShare.Read))
             {
                 using (var inStream = new FileStream(source, FileMode.Open, FileAccess.Read, FileShare.Read))
                 {
                     int    buffer_size = 10240;
                     byte[] buffer      = new byte[buffer_size];
                     long   total_read  = 0;
                     while (total_read < inStream.Length)
                     {
                         if (HasBeenCanceled)
                         {
                             break;
                         }
                         int read = inStream.Read(buffer, 0, buffer_size);
                         outStream.Write(buffer, 0, read);
                         CopiedBytesOfItem(itemBeingCopied, (ulong)read);
                         total_read += read;
                     }
                 }
             }
         }
     }
 }
Пример #6
0
        // Modified from https://docs.microsoft.com/en-us/dotnet/standard/io/how-to-copy-directories
        private void CopyDirectory(FolderFileItem itemBeingCopied, string sourceDirName, string destDirName, bool copySubDirs, List <string> excludedPaths = null)
        {
            if (HasBeenCanceled)
            {
                return;
            }
            // Get the subdirectories for the specified directory.
            DirectoryInfo dir = new DirectoryInfo(sourceDirName);

            if (!dir.Exists)
            {
                throw new DirectoryNotFoundException(
                          "Source directory does not exist or could not be found: "
                          + sourceDirName);
            }
            _directoryPathsSeen.Add(sourceDirName);

            // If the destination directory doesn't exist, create it.
            if (!Directory.Exists(destDirName) && !_isCalculatingFileSize)
            {
                Directory.CreateDirectory(destDirName);
            }

            // Get the files in the directory and copy them to the new location.
            FileInfo[] files = dir.GetFiles();
            foreach (FileInfo file in files)
            {
                if (HasBeenCanceled)
                {
                    return;
                }
                string tempPath    = Path.Combine(destDirName, file.Name);
                bool   shouldAllow = ShouldAllowPath(excludedPaths, file.FullName);
                if (_isCalculatingFileSize && shouldAllow)
                {
                    _currentDirectorySize += (ulong)file.Length;
                }
                else if (shouldAllow)
                {
                    CopySingleFile(itemBeingCopied, file.FullName, tempPath);
                }
            }

            // If copying subdirectories, copy them and their contents to new location.
            if (copySubDirs)
            {
                DirectoryInfo[] dirs = dir.GetDirectories();
                foreach (DirectoryInfo subDir in dirs)
                {
                    if (HasBeenCanceled)
                    {
                        return;
                    }
                    if (!_directoryPathsSeen.Contains(subDir.FullName))
                    {
                        string temppath = Path.Combine(destDirName, subDir.Name);
                        if (ShouldAllowPath(excludedPaths, subDir.FullName))
                        {
                            CopyDirectory(itemBeingCopied, subDir.FullName, temppath, copySubDirs, excludedPaths);
                        }
                        _directoryPathsSeen.Add(subDir.FullName);
                    }
                }
            }
        }
Пример #7
0
        private void BackupToCompressedFile(string destination, List <string> filePaths,
                                            Dictionary <string, FolderFileItem> pathsToFolderFileItem, Dictionary <string, ulong> pathsToFileSize)
        {
            var quotedFilePaths = new List <string>();

            foreach (string filePath in filePaths)
            {
                quotedFilePaths.Add("\"" + filePath + "\"");
            }
            var     is64BitOS  = Utilities.Is64BitOS();
            Process process    = new Process();
            var     currentDir = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName;
            var     exePath    = is64BitOS ? currentDir + "/tools/x64/7za.exe" : currentDir + "/tools/x86/7za.exe";

            process.StartInfo.FileName         = exePath;
            process.StartInfo.WorkingDirectory = Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName;

            // https://stackoverflow.com/a/6522928/3938401
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.CreateNoWindow         = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.StandardOutputEncoding = Encoding.UTF8;

            //process.StartInfo.RedirectStandardError = true;
            process.EnableRaisingEvents = true;
            var            didError                = false;
            var            sizeInBytes             = 0UL;
            var            remainingBytes          = 0UL;
            var            didStartCompressingFile = false;
            var            lastPercent             = 0.0;
            string         currentFilePath         = "";
            FolderFileItem currentItem             = null;
            var            bytesCopiedForItem      = new Dictionary <FolderFileItem, ulong>();
            var            didFinishCancel         = false;
            var            nextMessageIsError      = false;
            string         errorMessage            = "";

            process.OutputDataReceived += new DataReceivedEventHandler(delegate(object sender, DataReceivedEventArgs e) {
                if (string.IsNullOrWhiteSpace(e.Data) || didFinishCancel) // in case more events come through
                {
                    return;
                }
                if (HasBeenCanceled || didError)
                {
                    // ONLY WORKS IF YOU AREN'T ALREADY SHOWING A CONSOLE!
                    // https://stackoverflow.com/a/29274238/3938401
                    if (AttachConsole((uint)process.Id))
                    {
                        SetConsoleCtrlHandler(null, true);
                        try
                        {
                            GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, process.SessionId); // ends the process
                            process.Kill();                                                       // process is canned, so OK to kill
                        }
                        catch { }
                        finally
                        {
                            FreeConsole();
                            SetConsoleCtrlHandler(null, false);
                            didFinishCancel = true;
                        }
                        return;
                    }
                }
                if (e.Data.StartsWith("+ ") && e.Data.Trim() != "+")
                {
                    didStartCompressingFile = true;
                    currentFilePath         = e.Data.Substring(2);
                    if (currentItem != null && remainingBytes > 0)
                    {
                        CopiedBytesOfItem(currentItem, remainingBytes);
                        bytesCopiedForItem[currentItem] += remainingBytes;
                        if (!currentItem.IsDirectory)
                        {
                            FinishedCopyingItem?.Invoke(currentItem);
                        }
                        else
                        {
                            if (bytesCopiedForItem[currentItem] == currentItem.ByteSize)
                            {
                                FinishedCopyingItem?.Invoke(currentItem);
                            }
                        }
                    }
                    if (pathsToFolderFileItem.ContainsKey(currentFilePath))
                    {
                        currentItem = pathsToFolderFileItem[currentFilePath];
                    }
                    else
                    {
                        currentItem = null;
                    }
                    if (currentItem != null && !bytesCopiedForItem.ContainsKey(currentItem))
                    {
                        bytesCopiedForItem[currentItem] = 0;
                    }
                    if (pathsToFileSize.ContainsKey(currentFilePath))
                    {
                        sizeInBytes = remainingBytes = pathsToFileSize[currentFilePath];
                    }
                    else
                    {
                        sizeInBytes = remainingBytes = 0;
                    }
                }
                else if (e.Data.Contains("%") && didStartCompressingFile)
                {
                    var percent       = double.Parse(e.Data.Trim().Split('%')[0]);
                    var actualPercent = percent - lastPercent;
                    lastPercent       = percent;
                    var copiedBytes   = Math.Floor((actualPercent / 100.0) * sizeInBytes); // floor -- would rather underestimate than overestimate
                    if (currentItem != null)
                    {
                        CopiedBytesOfItem(currentItem, (ulong)copiedBytes);
                        bytesCopiedForItem[currentItem] += (ulong)copiedBytes;
                    }
                    remainingBytes -= (ulong)copiedBytes;
                }
                else if (e.Data.Contains("Error:"))
                {
                    nextMessageIsError = true;
                }
                else if (nextMessageIsError)
                {
                    errorMessage       = e.Data;
                    didError           = true;
                    nextMessageIsError = false;
                }
            });

            /**
             * Command line params:
             * -y (yes to prompts)
             * -ssw (Compresses files open for writing by another applications)
             * -bsp1 (output for progress to stdout)
             * -bse1 (output for errors to stdout)
             * -bb1 (log level 1)
             * -spf (Use fully qualified file paths)
             * -mx1 (compression level to fastest)
             * -v2g (split into 2 gb volumes -- https://superuser.com/a/184601)
             * -sccUTF-8 (set console output to UTF-8)
             * -p (set password for file)
             * */
            var args = "-y -ssw -bsp1 -bse1 -bb1 -spf -mx1 -v2g -sccUTF-8";

            if (UsesPasswordForCompressedFile)
            {
                var pass = Utilities.SecureStringToString(CompressedFilePassword);
                if (!string.IsNullOrWhiteSpace(pass))
                {
                    args = "-p" + pass + " " + args; // add password flag
                }
            }
            string inputPaths = string.Join("\n", quotedFilePaths);
            // to circumvent issue where inputPaths is too long for command line, need to write them to a file
            // and then load the file into 7z via command line params (@fileName as last param -- https://superuser.com/a/940894)
            var tmpFileName = Path.GetTempFileName();

            using (StreamWriter sw = new StreamWriter(tmpFileName))
            {
                sw.Write(inputPaths);
            }
            args = "a " + args + " \"" + destination + "\" @\"" + tmpFileName + "\""; // a = add file
            process.StartInfo.Arguments = args;
            process.Start();
            process.BeginOutputReadLine();
            //process.BeginErrorReadLine();
            process.WaitForExit();
            // make sure last item is handled properly
            if (!HasBeenCanceled && currentItem != null && remainingBytes > 0)
            {
                CopiedBytesOfItem(currentItem, remainingBytes);
                FinishedCopyingItem?.Invoke(currentItem);
            }
            if (HasBeenCanceled)
            {
                File.Delete(destination);
            }
            if (didError)
            {
                if (string.IsNullOrWhiteSpace(errorMessage))
                {
                    errorMessage = "Compression operation failed";
                }
                throw new Exception(errorMessage);
            }
        }
Пример #8
0
 private void ShowEditDirectoryExclusionsScreen(FolderFileItem item)
 {
     PushViewModel(new ExcludeFilesFoldersViewModel(this, item));
 }
Пример #9
0
 private void BackupPerformer_CalculatedBytesOfItem(FolderFileItem item, ulong bytes)
 {
     _totalBackupSize += bytes;
 }