private void butRun_Click(object sender, EventArgs e) { if (comboDbs.SelectedIndex == -1) { MsgBox.Show(this, "Please select a backup database first."); return; } //make sure it's not this database if (comboDbs.SelectedItem.ToString() == MiscData.GetCurrentDatabase()) { MsgBox.Show(this, "Please choose a database other than the current database."); return; } //make sure it's from before March 17th. //if(!DatabaseMaintenance.DatabaseIsOlderThanMarchSeventeenth(comboDbs.SelectedItem.ToString())){ // MsgBox.Show(this,"The backup database must be older than March 17, 2010."); // return; //} Cursor = Cursors.WaitCursor; textResults.Text = ""; duplicateClaimProcInfo = DatabaseMaintenances.GetDuplicateClaimProcs(); if (duplicateClaimProcInfo == "") { textResults.Text += "Duplicate claim payments: None found. Database OK.\r\n\r\n"; } else { textResults.Text += duplicateClaimProcInfo; } duplicateSuppInfo = DatabaseMaintenances.GetDuplicateSupplementalPayments(); if (duplicateSuppInfo == "") { textResults.Text += "Duplicate supplemental payments: None found. Database OK.\r\n\r\n"; } else { textResults.Text += duplicateSuppInfo; } missingSuppInfo = DatabaseMaintenances.GetMissingClaimProcs(comboDbs.SelectedItem.ToString()); if (missingSuppInfo == "") { textResults.Text += "Missing claim payments: None found. Database OK."; } else { textResults.Text += missingSuppInfo; } Cursor = Cursors.Default; }
private void butSynch_Click(object sender, EventArgs e) { if (textUsername.Text == "") { MsgBox.Show(this, "Please enter a username first."); return; } if (ReplicationServers.Listt.Count == 0) { MsgBox.Show(this, "Please add at servers to the list first"); return; } Cursor = Cursors.WaitCursor; string currentDatabaseName = MiscData.GetCurrentDatabase(); for (int i = 0; i < ReplicationServers.Listt.Count; i++) { string compName = ReplicationServers.Listt[i].Descript; DataConnection dc = new DataConnection(); try { //try { dc.SetDb(compName, currentDatabaseName, textUsername.Text, textPassword.Text, "", "", DataConnection.DBtype); //} //catch(MySql.Data.MySqlClient.MySqlException ex) { // if(ex.Number==1042) {//The error 1042 is issued when the connection could not be made. // throw ex;//Pass the exception along. // } // DataConnection.cmd.Connection.Close(); //} //Connection is considered to be successfull at this point. Now restart the slave process to force replication. string command = "SLAVE STOP; START SLAVE; SHOW SLAVE STATUS;"; DataTable slaveStatus = dc.GetTable(command); //Wait for the slave process to become active again. for (int j = 0; j < 40 && slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes"; j++) { Thread.Sleep(1000); command = "SHOW SLAVE STATUS"; slaveStatus = dc.GetTable(command); } if (slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes") { throw new Exception("Slave IO is not running on computer " + compName); } if (slaveStatus.Rows[0]["Slave_SQL_Running"].ToString().ToLower() != "yes") { throw new Exception("Slave SQL is not running on computer " + compName); } //Wait for replication to complete. while (slaveStatus.Rows[0]["Slave_IO_State"].ToString().ToLower() != "waiting for master to send event" || slaveStatus.Rows[0]["Seconds_Behind_Master"].ToString() != "0") { slaveStatus = dc.GetTable(command); } } catch (Exception ex) { Cursor = Cursors.Default; MessageBox.Show(Lan.g(this, "Error forcing replication on computer") + " " + compName + ": " + ex.Message); return; //Cancel operation. } } Cursor = Cursors.Default; MessageBox.Show(Lan.g(this, "Database synch completed successfully.")); }
private void butSynch_Click(object sender, EventArgs e) { if (textUsername.Text == "") { MsgBox.Show(this, "Please enter a username first."); return; } if (_listReplicationServers.Count == 0) { MsgBox.Show(this, "Please add at servers to the list first."); return; } Cursor = Cursors.WaitCursor; string databaseNameOriginal = MiscData.GetCurrentDatabase(); string compNameOriginal = DataConnection.GetServerName(); DataConnection dc; bool isReplicationSucessfull = true; for (int i = 0; i < _listReplicationServers.Count; i++) { string compName = _listReplicationServers[i].Descript; dc = new DataConnection(); try { dc.SetDb(compName, databaseNameOriginal, textUsername.Text, textPassword.Text, "", "", DataConnection.DBtype); //Connection is considered to be successfull at this point. Now restart the slave process to force replication. string command = "STOP SLAVE; START SLAVE; SHOW SLAVE STATUS;"; DataTable slaveStatus = dc.GetTable(command); //Wait for the slave process to become active again. for (int j = 0; j < 40 && slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes"; j++) { Thread.Sleep(1000); command = "SHOW SLAVE STATUS"; slaveStatus = dc.GetTable(command); } if (slaveStatus.Rows[0]["Slave_IO_Running"].ToString().ToLower() != "yes") { throw new ApplicationException(Lan.g(this, "Slave IO is not running on server") + " " + compName); } if (slaveStatus.Rows[0]["Slave_SQL_Running"].ToString().ToLower() != "yes") { throw new ApplicationException(Lan.g(this, "Slave SQL is not running on server") + " " + compName); } //Wait for replication to complete. while (slaveStatus.Rows[0]["Slave_IO_State"].ToString().ToLower() != "waiting for master to send event" || slaveStatus.Rows[0]["Seconds_Behind_Master"].ToString() != "0") { slaveStatus = dc.GetTable(command); } } catch (Exception ex) { Cursor = Cursors.Default; MessageBox.Show(Lan.g(this, "Error forcing synch on server") + " " + compName + ": " + ex.Message); isReplicationSucessfull = false; break; //Cancel operation. } } if (isReplicationSucessfull) { Cursor = Cursors.Default; MessageBox.Show(Lan.g(this, "Database synch completed successfully.")); } //Do not leave this function without connecting back to original database, or closing program. //At this point we are still connected to the last replication server in the list, try to connect back up to the original database. bool isReconnectSuccessful = false; while (!isReconnectSuccessful) { try { //Reconnect back to original database. dc = new DataConnection(); dc.SetDb(compNameOriginal, databaseNameOriginal, textUsername.Text, textPassword.Text, "", "", DataConnection.DBtype); isReconnectSuccessful = true; //No exception thrown, leave while loop. } catch (Exception ex) { if (MessageBox.Show(Lan.g(this, "Error reconnecting to server") + " " + compNameOriginal + ": " + ex.Message + "\r\n" + Lan.g(this, "Would you like to retry? Cancel will close the program."), "", MessageBoxButtons.OKCancel) != DialogResult.OK) { FormOpenDental.S_ProcessKillCommand(); } } } }
///<summary>Called in two places. Once from FormOpenDental.PrefsStartup, and also from FormBackups after a restore.</summary> public static bool CheckProgramVersion() { if (PrefC.GetBool(PrefName.UpdateWindowShowsClassicView)) { return(CheckProgramVersionClassic()); } Version storedVersion = new Version(PrefC.GetString(PrefName.ProgramVersion)); Version currentVersion = new Version(Application.ProductVersion); string database = ""; //string command=""; if (DataConnection.DBtype == DatabaseType.MySql) { database = MiscData.GetCurrentDatabase(); } if (storedVersion < currentVersion) { //There are two different situations where this might happen. if (PrefC.GetString(PrefName.UpdateInProgressOnComputerName) == "") //1. Just performed an update from this workstation on another database. //This is very common for admins when viewing slighly older databases. //There should be no annoying behavior here. So do nothing. { #if !DEBUG //Excluding this in debug allows us to view slightly older databases without accidentally altering them. Prefs.UpdateString(PrefName.ProgramVersion, currentVersion.ToString()); Cache.Refresh(InvalidType.Prefs); #endif return(true); } //and 2a. Just performed an update from this workstation on this database. //or 2b. Just performed an update from this workstation for multiple databases. //In both 2a and 2b, we already downloaded Setup file to correct location for this db, so skip 1 above. //This computer just performed an update, but none of the other computers has updated yet. //So attempt to stash all files that are in the Application directory. if (!CopyFromHereToUpdateFiles(currentVersion)) { Application.Exit(); return(false); } Prefs.UpdateString(PrefName.ProgramVersion, currentVersion.ToString()); Prefs.UpdateString(PrefName.UpdateInProgressOnComputerName, ""); //now, other workstations will be allowed to update. Cache.Refresh(InvalidType.Prefs); } if (storedVersion > currentVersion) { //This is the update sequence for both a direct workstation, and for a ClientWeb workstation. if (!PrefC.UsingAtoZfolder) //Not using image path. //this does not bypass checking the RegistrationKey because that's the only way to get the UpdateCode. //perform program update automatically. { DownloadAndRunSetup(storedVersion, currentVersion); Application.Exit(); return(false); } string folderUpdate = ODFileUtils.CombinePaths(ImageStore.GetPreferredAtoZpath(), "UpdateFiles"); //look at the manifest to see if it's the version we need string manifestVersion = ""; try { manifestVersion = File.ReadAllText(ODFileUtils.CombinePaths(folderUpdate, "Manifest.txt")); } catch { //fail silently } if (manifestVersion != storedVersion.ToString(3)) //manifest version is wrong //No point trying the Setup.exe because that's probably wrong too. //Just go straight to downloading and running the Setup.exe. { string manpath = ODFileUtils.CombinePaths(folderUpdate, "Manifest.txt"); if (MessageBox.Show(Lan.g("Prefs", "The expected version information was not found in this file: ") + manpath + ". " + Lan.g("Prefs", "There is probably a permission issue on that folder which should be fixed. ") + "\r\n\r\n" + Lan.g("Prefs", "The suggested solution is to return to the computer where the update was just run. Go to Help | Update | Setup, and click the Recopy button.") + "\r\n\r\n" + Lan.g("Prefs", "If, instead, you click OK in this window, then a fresh Setup file will be downloaded and run."), "", MessageBoxButtons.OKCancel) != DialogResult.OK) //they don't want to download again. { Application.Exit(); return(false); } DownloadAndRunSetup(storedVersion, currentVersion); Application.Exit(); return(false); } //manifest version matches if (MessageBox.Show(Lan.g("Prefs", "Files will now be copied.") + "\r\n" + Lan.g("Prefs", "Workstation version will be updated from ") + currentVersion.ToString(3) + Lan.g("Prefs", " to ") + storedVersion.ToString(3), "", MessageBoxButtons.OKCancel) != DialogResult.OK) //they don't want to update for some reason. { Application.Exit(); return(false); } string tempDir = Path.GetTempPath(); //copy UpdateFileCopier.exe to the temp directory File.Copy(ODFileUtils.CombinePaths(folderUpdate, "UpdateFileCopier.exe"), //source ODFileUtils.CombinePaths(tempDir, "UpdateFileCopier.exe"), //dest true); //overwrite //wait a moment to make sure the file was copied Thread.Sleep(500); //launch UpdateFileCopier to copy all files to here. int processId = Process.GetCurrentProcess().Id; string appDir = Application.StartupPath; Process.Start(ODFileUtils.CombinePaths(tempDir, "UpdateFileCopier.exe"), "\"" + folderUpdate + "\"" //pass the source directory to the file copier. + " " + processId.ToString() //and the processId of Open Dental. + " \"" + appDir + "\""); //and the directory where OD is running Application.Exit(); //always exits, whether launch of setup worked or not return(false); } return(true); }
///<summary>Essentially no changes have been made to this since version 6.5.</summary> private static bool CheckProgramVersionClassic() { Version storedVersion = new Version(PrefC.GetString(PrefName.ProgramVersion)); Version currentVersion = new Version(Application.ProductVersion); string database = MiscData.GetCurrentDatabase(); if (storedVersion < currentVersion) { Prefs.UpdateString(PrefName.ProgramVersion, currentVersion.ToString()); Cache.Refresh(InvalidType.Prefs); } if (storedVersion > currentVersion) { if (PrefC.UsingAtoZfolder) { string setupBinPath = ODFileUtils.CombinePaths(ImageStore.GetPreferredAtoZpath(), "Setup.exe"); if (File.Exists(setupBinPath)) { if (MessageBox.Show("You are attempting to run version " + currentVersion.ToString(3) + ",\r\n" + "But the database " + database + "\r\n" + "is already using version " + storedVersion.ToString(3) + ".\r\n" + "A newer version must have already been installed on at least one computer.\r\n" + "The setup program stored in your A to Z folder will now be launched.\r\n" + "Or, if you hit Cancel, then you will have the option to download again." , "", MessageBoxButtons.OKCancel) == DialogResult.Cancel) { if (MessageBox.Show("Download again?", "", MessageBoxButtons.OKCancel) == DialogResult.OK) { FormUpdate FormU = new FormUpdate(); FormU.ShowDialog(); } Application.Exit(); return(false); } try { Process.Start(setupBinPath); } catch { MessageBox.Show("Could not launch Setup.exe"); } } else if (MessageBox.Show("A newer version has been installed on at least one computer," + "but Setup.exe could not be found in any of the following paths: " + ImageStore.GetPreferredAtoZpath() + ". Download again?", "", MessageBoxButtons.OKCancel) == DialogResult.OK) { FormUpdate FormU = new FormUpdate(); FormU.ShowDialog(); } } else //Not using image path. //perform program update automatically. { string patchName = "Setup.exe"; string updateUri = PrefC.GetString(PrefName.UpdateWebsitePath); string updateCode = PrefC.GetString(PrefName.UpdateCode); string updateInfoMajor = ""; string updateInfoMinor = ""; if (FormUpdate.ShouldDownloadUpdate(updateUri, updateCode, out updateInfoMajor, out updateInfoMinor)) { if (MessageBox.Show(updateInfoMajor + Lan.g("Prefs", "Perform program update now?"), "", MessageBoxButtons.YesNo) == DialogResult.Yes) { string tempFile = ODFileUtils.CombinePaths(Path.GetTempPath(), patchName); //Resort to a more common temp file name. FormUpdate.DownloadInstallPatchFromURI(updateUri + updateCode + "/" + patchName, //Source URI tempFile, true, true, null); //Local destination file. File.Delete(tempFile); //Cleanup install file. } } } Application.Exit(); //always exits, whether launch of setup worked or not return(false); } return(true); }
private void butRestore_Click(object sender, System.EventArgs e) { if (textBackupRestoreFromPath.Text != "" && !textBackupRestoreFromPath.Text.EndsWith("" + Path.DirectorySeparatorChar)) { MessageBox.Show(Lan.g(this, "Paths must end with ") + Path.DirectorySeparatorChar + "."); return; } if (textBackupRestoreToPath.Text != "" && !textBackupRestoreToPath.Text.EndsWith("" + Path.DirectorySeparatorChar)) { MessageBox.Show(Lan.g(this, "Paths must end with ") + Path.DirectorySeparatorChar + "."); return; } if (ShouldUseAtoZFolder()) { if (textBackupRestoreAtoZToPath.Text != "" && !textBackupRestoreAtoZToPath.Text.EndsWith("" + Path.DirectorySeparatorChar)) { MessageBox.Show(Lan.g(this, "Paths must end with ") + Path.DirectorySeparatorChar + "."); return; } } if (Environment.OSVersion.Platform != PlatformID.Unix) { //dmg This check will not work on Linux, because mapped drives exist as regular (mounted) paths. Perhaps there //is another way to check for this on Linux. if (textBackupRestoreToPath.Text != "" && textBackupRestoreToPath.Text.StartsWith("" + Path.DirectorySeparatorChar)) { MsgBox.Show(this, "The restore database TO folder must be on this computer."); return; } } //pointless to save defaults string dbName = MiscData.GetCurrentDatabase(); if (InnoDb.HasInnoDbTables(dbName)) { //Database has innodb tables. Restore tool does not work on dbs with InnoDb tables. MsgBox.Show(this, "InnoDb tables detected. Restore tool cannot run with InnoDb tables."); return; } if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreFromPath.Text, dbName))) // D:\opendental { MessageBox.Show(Lan.g(this, "Restore FROM path is invalid. Unable to find folder named ") + dbName); return; } if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, dbName))) // C:\mysql\data\opendental { MessageBox.Show(Lan.g(this, "Restore TO path is invalid. Unable to find folder named ") + dbName); return; } if (ShouldUseAtoZFolder()) { if (!Directory.Exists(textBackupRestoreAtoZToPath.Text)) // C:\OpenDentalData\ { MsgBox.Show(this, "Restore A-Z images TO path is invalid."); return; } string atozFull = textBackupRestoreAtoZToPath.Text; // C:\OpenDentalData\ //remove the trailing \ atozFull = atozFull.Substring(0, atozFull.Length - 1); // C:\OpenDentalData string atozDir = atozFull.Substring(atozFull.LastIndexOf(Path.DirectorySeparatorChar) + 1); // OpenDentalData if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreFromPath.Text, atozDir))) // D:\OpenDentalData { MsgBox.Show(this, "Restore A-Z images FROM path is invalid."); return; } } string fromPath = ODFileUtils.CombinePaths(new string[] { textBackupRestoreFromPath.Text, dbName, "" }); // D:\opendental\ DirectoryInfo dirInfo = new DirectoryInfo(fromPath); //does not check to see if dir exists if (MessageBox.Show(Lan.g(this, "Restore from backup created on") + "\r\n" + dirInfo.LastWriteTime.ToString("dddd") + " " + dirInfo.LastWriteTime.ToString() , "", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel) { return; } Cursor = Cursors.WaitCursor; //stop the service-------------------------------------------------------------------------------------- ServiceController sc = new ServiceController("MySQL"); if (!ServicesHelper.Stop(sc)) { MsgBox.Show(this, "Unable to stop MySQL service."); Cursor = Cursors.Default; return; } //rename the current database--------------------------------------------------------------------------- //Get a name for the new directory string newDb = dbName + "backup_" + DateTime.Today.ToString("MM_dd_yyyy"); if (Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, newDb))) //if the new database name already exists //find a unique one { int uniqueID = 1; string originalNewDb = newDb; do { newDb = originalNewDb + "_" + uniqueID.ToString(); uniqueID++; }while(Directory.Exists(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, newDb))); } //move the current db (rename) Directory.Move(ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, dbName) , ODFileUtils.CombinePaths(textBackupRestoreToPath.Text, newDb)); //Restore---------------------------------------------------------------------------------------------- string toPath = textBackupRestoreToPath.Text; // C:\mysql\data\ Directory.CreateDirectory(ODFileUtils.CombinePaths(toPath, dirInfo.Name)); FileInfo[] files = dirInfo.GetFiles(); curVal = 0; //curVal gets increased for (int i = 0; i < files.Length; i++) { File.Copy(files[i].FullName, ODFileUtils.CombinePaths(new string[] { toPath, dirInfo.Name, files[i].Name })); } //start the service-------------------------------------------------------------------------------------- ServicesHelper.Start(sc); Cursor = Cursors.Default; //restore A-Z folder, and give user a chance to cancel it. if (ShouldUseAtoZFolder()) { FormP = new FormProgress(); FormP.MaxVal = 100; //We will be setting maxVal from worker thread. (double)fileSize/1024; FormP.NumberMultiplication = 100; FormP.DisplayText = ""; //We will set the text from the worker thread. FormP.NumberFormat = "N1"; //start the thread that will perform the database copy Thread workerThread = new Thread(new ThreadStart(InstanceMethodRestore)); workerThread.Start(); //display the progress dialog to the user: FormP.ShowDialog(); if (FormP.DialogResult == DialogResult.Cancel) { workerThread.Abort(); return; } } Version programVersionDb = new Version(PrefC.GetStringNoCache(PrefName.ProgramVersion)); Version programVersionCur = new Version(Application.ProductVersion); if (programVersionDb != programVersionCur) { MsgBox.Show(this, "The restored database version is different than the version installed and requires a restart. The program will now close."); FormOpenDental.S_ProcessKillCommand(); return; } else { DataValid.SetInvalid(Cache.GetAllCachedInvalidTypes().ToArray()); } MsgBox.Show(this, "Done"); Close(); return; }
///<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, "" }); }
private void butBackup_Click(object sender, System.EventArgs e) { if (!IsBackupTabValid()) { return; } //Ensure that the backup from and backup to paths are different. This is to prevent the live database //from becoming corrupt. if (this.textBackupFromPath.Text.Trim().ToLower() == this.textBackupToPath.Text.Trim().ToLower()) { MsgBox.Show(this, "The backup from path and backup to path must be different."); return; } //test saving defaults if (textBackupFromPath.Text != PrefC.GetString(PrefName.BackupFromPath) || textBackupToPath.Text != PrefC.GetString(PrefName.BackupToPath) || textBackupRestoreFromPath.Text != PrefC.GetString(PrefName.BackupRestoreFromPath) || textBackupRestoreToPath.Text != PrefC.GetString(PrefName.BackupRestoreToPath) || textBackupRestoreAtoZToPath.Text != PrefC.GetString(PrefName.BackupRestoreAtoZToPath)) { if (MsgBox.Show(this, MsgBoxButtons.YesNo, "Set as default?") && SaveTabPrefs()) { DataValid.SetInvalid(InvalidType.Prefs); } } string dbName = MiscData.GetCurrentDatabase(); if (InnoDb.HasInnoDbTables(dbName)) { //Database has innodb tables. Backup tool does not work on dbs with InnoDb tables. MsgBox.Show(this, "InnoDb tables detected. Backup tool cannot run with InnoDb tables."); return; } if (!Directory.Exists(ODFileUtils.CombinePaths(textBackupFromPath.Text, dbName))) // C:\mysql\data\opendental { MsgBox.Show(this, "Backup FROM path is invalid."); return; } if (!Directory.Exists(textBackupToPath.Text)) // D:\ { MsgBox.Show(this, "Backup TO path is invalid."); return; } _errorMessage = ""; FormP = new FormProgress(); FormP.MaxVal = 100; //We will be setting maxVal from worker thread. (double)fileSize/1024; FormP.NumberMultiplication = 100; FormP.DisplayText = ""; //We will set the text from the worker thread. FormP.NumberFormat = "N1"; //start the thread that will perform the database copy Thread workerThread = new Thread(new ThreadStart(InstanceMethodBackup)); workerThread.Start(); //display the progress dialog to the user: FormP.ShowDialog(); if (FormP.DialogResult == DialogResult.Cancel) { workerThread.Abort(); return; } if (_errorMessage == "") { SecurityLogs.MakeLogEntry(Permissions.Backup, 0, Lan.g(this, "Database backup created at ") + textBackupToPath.Text); MessageBox.Show(Lan.g(this, "Backup complete.")); } else //Backup failed for some reason. { MessageBox.Show(_errorMessage); } Close(); }