예제 #1
0
        ///<summary>This is the function that the worker thread uses to perform the backup.</summary>
        private void InstanceMethodBackup()
        {
            curVal = 0;
            Invoke(new PassProgressDelegate(PassProgressToDialog), new object [] { curVal,
                                                                                   Lan.g(this, "Preparing to copy database"), //this happens very fast and probably won't be noticed.
                                                                                   100, "" });                                //max of 100 keeps dlg from closing
            string dbName         = MiscData.GetCurrentDatabase();
            ulong  driveFreeSpace = 0;
            double dbSize         = GetFileSizes(textBackupFromPath.Text + dbName) / 1024;

            //Attempt to get the free disk space on the drive or share of the destination folder.
            //If the free space cannot be determined the backup will be attempted anyway (old behavior).
            if (ODFileUtils.GetDiskFreeSpace(textBackupToPath.Text, out driveFreeSpace))
            {
                if ((ulong)dbSize * 1024 * 1024 >= driveFreeSpace)           //dbSize is in megabytes, cast to ulong to compare. It will never be negative so this is safe.
                {
                    Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Not enough free disk space available on the destination drive to backup the database.") });
                    //We now want to automatically close FormProgress.  This is done by clearing out the variables.
                    Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" });
                    return;
                }
            }
            try{
                string dbtopath = ODFileUtils.CombinePaths(textBackupToPath.Text, dbName);
                if (Directory.Exists(dbtopath))                // D:\opendental
                {
                    int loopCount = 1;
                    while (Directory.Exists(dbtopath + "backup_" + loopCount))
                    {
                        loopCount++;
                    }
                    Directory.Move(dbtopath, dbtopath + "backup_" + loopCount);
                }
                string        fromPath = ODFileUtils.CombinePaths(textBackupFromPath.Text, dbName);
                string        toPath   = textBackupToPath.Text;
                DirectoryInfo dirInfo  = new DirectoryInfo(fromPath);             //does not check to see if dir exists
                Directory.CreateDirectory(ODFileUtils.CombinePaths(toPath, dirInfo.Name));
                FileInfo[] files = dirInfo.GetFiles();
                curVal = 0;              //curVal gets increased
                for (int i = 0; i < files.Length; i++)
                {
                    string fromFile = files[i].FullName;
                    string toFile   = ODFileUtils.CombinePaths(new string[] { toPath, dirInfo.Name, files[i].Name });
                    if (File.Exists(toFile))
                    {
                        if (files[i].LastWriteTime != File.GetLastWriteTime(toFile))                       //if modification dates don't match
                        {
                            FileAttributes fa         = File.GetAttributes(toFile);
                            bool           isReadOnly = ((fa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);
                            if (isReadOnly)
                            {
                                //If the destination file exists and is marked as read only, then we must mark it as a
                                //normal read/write file before it may be overwritten.
                                File.SetAttributes(toFile, FileAttributes.Normal);                               //Remove read only from the destination file.
                            }
                            File.Copy(fromFile, toFile, true);
                        }
                    }
                    else                        //file doesn't exist, so just copy
                    {
                        File.Copy(fromFile, toFile);
                    }
                    curVal += (double)files[i].Length / (double)1024 / (double)1024;
                    if (curVal < dbSize)                  //this avoids setting progress bar to max, which would close the dialog.
                    {
                        Invoke(new PassProgressDelegate(PassProgressToDialog), new object [] { curVal,
                                                                                               Lan.g(this, "Database: ?currentVal MB of ?maxVal MB copied"),
                                                                                               dbSize, "" });
                    }
                }
            }
            catch {           //for instance, if abort.
                //If the user aborted, FormP will return DialogResult.Cancel which will not cause this error text to be displayed to the user.  See butBackup_Click for more info.
                Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Backup failed.") });
                //We now want to automatically close FormProgress.  This is done by clearing out the variables.
                Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" });
                return;
            }
            //A to Z folder------------------------------------------------------------------------------------
            try {
                if (ShouldUseAtoZFolder())
                {
                    string atozFull = ODFileUtils.RemoveTrailingSeparators(ImageStore.GetPreferredAtoZpath());
                    string atozDir  = atozFull.Substring(atozFull.LastIndexOf(Path.DirectorySeparatorChar) + 1);               //OpenDentalData
                    Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0,
                                                                                          Lan.g(this, "Calculating size of files in A to Z folder."),
                                                                                          100, "" });//max of 100 keeps dlg from closing
                    long atozSize = GetFileSizes(ODFileUtils.CombinePaths(atozFull, ""),
                                                 ODFileUtils.CombinePaths(new string[] { textBackupToPath.Text, atozDir, "" })) / 1024;
                    driveFreeSpace = 0;
                    //Attempt to get the free disk space on the drive or share of the destination folder.
                    //If the free space cannot be determined the backup will be attempted anyway (old behavior).
                    if (ODFileUtils.GetDiskFreeSpace(textBackupToPath.Text, out driveFreeSpace))
                    {
                        if ((ulong)(atozSize * 1024 * 1024) >= driveFreeSpace)                   //atozSize is in megabytes, cast to ulong in order to compare.  It will never be negative so it's safe.
                        //Not enough free space to perform the backup.
                        {
                            throw new ApplicationException(Lan.g(this, "Backing up A to Z images folder failed.  Not enough free disk space available on the destination drive.")
                                                           + "\r\n" + Lan.g(this, "AtoZ folder size:") + " " + atozSize * 1024 * 1024 + "B\r\n"
                                                           + Lan.g(this, "Destination available space:") + " " + driveFreeSpace + "B");
                        }
                    }
                    if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupToPath.Text, atozDir)))                    // D:\OpenDentalData
                    {
                        Directory.CreateDirectory(ODFileUtils.CombinePaths(textBackupToPath.Text, atozDir));            // D:\OpenDentalData
                    }
                    curVal = 0;
                    CopyDirectoryIncremental(ODFileUtils.CombinePaths(atozFull, ""),                                        // C:\OpenDentalData\
                                             ODFileUtils.CombinePaths(new string[] { textBackupToPath.Text, atozDir, "" }), // D:\OpenDentalData\
                                             atozSize);
                }
            }
            catch (ApplicationException ex) {
                Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { ex.Message });
            }
            catch {
                Invoke(new ErrorMessageDelegate(SetErrorMessage), new object[] { Lan.g(this, "Backing up A to Z images folder failed.  User might not have enough permissions or a file might be in use.") });
            }
            //force dialog to close even if no files copied or calculation was slightly off.
            Invoke(new PassProgressDelegate(PassProgressToDialog), new object[] { 0, "", 0, "" });
        }