using System; using System.Collections.Generic; using System.ComponentModel; using System.Configuration; using System.Data; using System.Data.SqlClient; using System.Diagnostics; using System.Linq; using System.Windows.Forms; using DBConfiguration.Properties; using Installer.Common; using System.IO; using System.Text; using Microsoft.Win32; using DTS.Common.Storage; using System.Security.AccessControl; using System.Security.Principal; using DTS.Common.Enums; namespace DBConfiguration { public partial class DBTypeChoice : Form { private BackgroundWorker _worker; private readonly Label _statusLabel = new Label(); private readonly Label _migrationStatusTextLabel = new Label(); bool done = false; bool localDone = false; bool cancelled = false; protected override void OnLoad(EventArgs e) { if (_cmdLine) { //Hide the form Visible = false; ShowInTaskbar = false; Opacity = 0; } base.OnLoad(e); } public DBTypeChoice(string targetDir, Version productVersion, string noUI, string sourcePath, string destPath) { InitializeComponent(); log.Source = "DataPRODbMigratorInstaller"; _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += worker_DoWork; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; if (noUI.ToUpper().StartsWith("STANDALONE")) { _standAlone = true; if (noUI.ToUpper() == "STANDALONECMD") { _cmdLine = true; } tbSourceDB.Text = sourcePath; tbDestinationDB.Text = destPath; _isoDir = Path.Combine(Environment.CurrentDirectory, Settings.Default.ISOMMEDbLocation); var version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; _productVersion = new Version($"{version.Major}.{version.Minor}.{version.Build}"); _targetDir = targetDir; _scriptsDir = Path.Combine(Environment.CurrentDirectory, Settings.Default.ScriptsFolder); ShowCentralizedControls(false); ShowStandAloneControls(true); if (rbMigrateLocal.Checked) { lblDestinationDB.Text = string.Format(Settings.Default.LocalDestDbPath, DbOperations.CURRENT_DB_VERSION); btnOK.Text = Settings.Default.Migrate; } else { lblDestinationDB.Text = Settings.Default.LocalDestDbToBeInitializedPath; btnOK.Text = Settings.Default.Initialize; } btnCancel.Text = Settings.Default.Quit; } else { _targetDir = targetDir; _targetDbDir = $"{_targetDir}\\{Settings.Default.LocalDbFolder}"; _isoDir = Path.Combine(_targetDir, Settings.Default.InstallerCustomActions, Settings.Default.ISOMMEDbLocation); _productVersion = productVersion; _scriptsDir = Path.Combine(_targetDir, Settings.Default.ScriptsFolder); } _majorMinorVersion = productVersion.Major.ToString() + "." + productVersion.Minor.ToString() + "." + productVersion.Build.ToString(); _statusLabel.AutoSize = true; _statusLabel.Location = new System.Drawing.Point(24, 446); _statusLabel.Name = "statusLabel"; _statusLabel.Size = new System.Drawing.Size(0, 13); _statusLabel.TabIndex = 19; Controls.Add(_statusLabel); _migrationStatusTextLabel.AutoSize = true; _migrationStatusTextLabel.Location = new System.Drawing.Point(24, 420); _migrationStatusTextLabel.Name = "migrationStatusTextLabel"; _migrationStatusTextLabel.Size = new System.Drawing.Size(0, 13); _migrationStatusTextLabel.TabIndex = 20; Controls.Add(_migrationStatusTextLabel); } void worker_DoWork(object sender, DoWorkEventArgs e) { log.WriteEntry("Doing work"); //21228: If Database name was changed on the form, rename the db //30701 Migration fails when db not named "DataPRO". if (!_standAlone) { if (tbDBName.Text != _originalTbDBName) { //First the .mdf var oldFileName = Path.Combine(_targetDbDir, _originalTbDBName + Settings.Default.Mdf); var newFileName = Path.Combine(_targetDbDir, tbDBName.Text + Settings.Default.Mdf); File.Move(oldFileName, newFileName); //Then the .ldf oldFileName = Path.Combine(_targetDbDir, _originalTbDBName + Settings.Default.LogLdf); newFileName = Path.Combine(_targetDbDir, tbDBName.Text + Settings.Default.LogLdf); File.Move(oldFileName, newFileName); } } if (cbCopyConfig.Checked) { //Combine the previous config with the new one var result = string.Empty; var allResults = new StringBuilder(); UpdateConfigurationIfPossible(out result); allResults.Append(result); allResults.Append("\r\n"); if (!string.IsNullOrWhiteSpace(allResults.ToString())) { MessageBox.Show(allResults.ToString(), Settings.Default.ConfigMigrationStatus, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } } if (rbLocal.Checked && !rbMigrateLocal.Checked) { if (rbAero.Checked || rbCrash.Checked || rbTSRAIR.Checked) { done = InitializeLocalDb() || _worker.CancellationPending; } else { done = true; } } else { if (rbLocal.Checked && (rbMigrateLocal.Checked || _standAlone)) { done = CopyAndMigrateLocalDb() || _worker.CancellationPending; } else if (rbCentralized.Checked) { done = MigrateCentralizedDb() || _worker.CancellationPending; } else if (rbBoth.Checked) { if ((rbMigrateLocal.Checked || _standAlone) && !localDone) //Don't re-do Local if it succeeded already { localDone = CopyAndMigrateLocalDb() || _worker.CancellationPending; } if (!_worker.CancellationPending && rbMigrateLocal.Checked) { done = MigrateCentralizedDb() || _worker.CancellationPending; } else { done = true; } } else if ((rbLocal.Checked && !rbMigrateLocal.Checked) || _worker.CancellationPending) { done = true; } } } private void UpdateConfigurationIfPossible(out string result) { var allResults = new StringBuilder(); if (!MigrateUserSettings(_targetDir, out result)) { allResults = CombineErrorResults(allResults, result); } else { allResults.Append(result); if (!MigrateAppSettings(_targetDir, out result)) { allResults = CombineErrorResults(allResults, result); } else { if (allResults.ToString().Contains(Settings.Default.ConfigDidNotNeedToBeUpdated) && (result != Settings.Default.ConfigDidNotNeedToBeUpdated)) { //Remove StringResources.ConfigDidNotNeedToBeUpdated because result says it was (or there was an error) allResults.Clear(); allResults.Append(result); } else if (!allResults.ToString().Contains(result)) { allResults.Append("\r\n"); allResults.Append(result); } } } if (allResults.ToString() != Settings.Default.ConfigDidNotNeedToBeUpdated) { //Both user and application values were successful, and at least some user values were updated so //be sure to return that information if no application values were updated. result = allResults.ToString(); } } private StringBuilder CombineErrorResults(StringBuilder allResults, string result) { if (allResults.Length > 0) { allResults.Append("\r\n"); } allResults.Append(result); return allResults; } private bool MigrateUserSettings(string targetDir, out string result) { return MigrateSettings(Settings.Default.UserSettings, targetDir, out result); } private bool MigrateAppSettings(string targetDir, out string result) { return MigrateSettings(Settings.Default.ApplicationSettings, targetDir, out result); } private bool MigrateSettings(string settingsType, string targetDir, out string result) { Configuration newConfig; var commonUtilities = new CommonUtilities(); if (!commonUtilities.GetNewSettings(settingsType, targetDir, out result, out var newSettings, out newConfig)) { return false; } SaveMigratedSettings(newSettings, newConfig, out result); return true; } private void SaveMigratedSettings(SettingElementCollection newSettings, Configuration newConfig, out string result) { var settingsToBeMigrated = new SettingElementCollection(); foreach (SettingElement newSetting in newSettings) { //If this setting exists in the old config, and it is different than the default that was installed, migrate the value if (_oldSettingsDictionary.ContainsKey(newSetting.Name) && _oldSettingsDictionary[newSetting.Name] != newSetting.Value.ValueXml.InnerXml) { //Only change from the new default DownloadFolder setting to the old DownloadFolder setting if it's not the previous default ("..\Data") if (newSetting.Name != Settings.Default.DownloadFolder || _oldSettingsDictionary[Settings.Default.DownloadFolder] != Settings.Default.DataUpOneLevel) { //Add to the list of settings that need to be migrated settingsToBeMigrated.Add(newSetting); } } } foreach (SettingElement settingToBeMigrated in settingsToBeMigrated) { //Migrate the changed value(s) newSettings.Remove(settingToBeMigrated); settingToBeMigrated.Value.ValueXml.InnerXml = _oldSettingsDictionary[settingToBeMigrated.Name]; newSettings.Add(settingToBeMigrated); } newConfig.Save(); result = settingsToBeMigrated.Count <= 0 ? Settings.Default.ConfigDidNotNeedToBeUpdated : string.Format(Settings.Default.ConfigWasUpdated, _mostRecentlyInstalledLowerVersion); } public void worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { switch ((e.UserState as MigrationStatus).StatusType) { case MigrationStatus.StatusTypes.MigrationStatus: _migrationStatusTextLabel.Text = (e.UserState as MigrationStatus).StatusText; _migrationStatusTextLabel.Refresh(); break; case MigrationStatus.StatusTypes.Status: _statusLabel.Text = (e.UserState as MigrationStatus).StatusText; _statusLabel.Refresh(); break; case MigrationStatus.StatusTypes.SourceDb: lblSourceDB.Refresh(); tbSourceDB.Refresh(); break; } } void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (_cmdLine) { //Simulate a Quit button click done = true; cancelled = true; if (_worker.IsBusy) { _worker.CancelAsync(); } else { Close(); } } else { Cursor.Current = Cursors.Default; if (done) { if (cancelled) { //Set the config to a blank local database (if it wasn't already) so this version can be used rbLocal.Checked = true; } if (!_standAlone && ChangesWereMade()) { SaveChanges(); } if (cancelled) { MessageBox.Show(_standAlone ? (rbMigrateLocal.Checked ? Settings.Default.DatabaseStandAloneMigrationCancelled : Settings.Default.DatabaseStandAloneInitializationCancelled) : Settings.Default.DataPROInstallationCancelled, Settings.Default.InstallationStatus, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } else if (oldDatabaseVersion >= DbOperations.CURRENT_DB_VERSION) { if (rbAero.Checked || rbCrash.Checked || rbTSRAIR.Checked) { MessageBox.Show(Settings.Default.DatabaseInitializationCompletedSuccessfully, Settings.Default.InstallationStatus, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } else { MessageBox.Show(string.Format(Settings.Default.NoMigrationNeeded, Environment.NewLine, oldDatabaseVersion, DbOperations.CURRENT_DB_VERSION), Settings.Default.InstallationStatus, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } } else { MessageBox.Show(_standAlone ? (rbLocal.Checked ? (rbMigrateLocal.Checked ? Settings.Default.DatabaseMigrationCompletedSuccessfully : Settings.Default.DatabaseInitializationCompletedSuccessfully) : Settings.Default.DatabaseMigrationCompletedSuccessfully) : Settings.Default.DataPROInstallationCompletedSuccessfully, Settings.Default.InstallationStatus, MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } cancelled = false; if (_standAlone) { btnOK.Enabled = true; EnableControls(true); } else { Close(); } } else { //Re-enable the controls that were disabled when OK was clicked btnOK.Enabled = true; EnableControls(true); } } } void EnableControls(bool enable) { groupBox1.Enabled = enable; tbSourceDB.Enabled = enable; tbSourceDB.Refresh(); btnBrowseSourceDB.Enabled = enable; tbDestinationDB.Enabled = enable; tbDestinationDB.Refresh(); btnBrowseDestinationDB.Enabled = enable; tbDBName.Enabled = enable; EnableRadioButtons(enable); if (rbLocal.Checked) return; tbDBHostname.Enabled = enable; cbUseNTLMAuthentication.Enabled = enable; if (cbUseNTLMAuthentication.Checked) return; tbDBUser.Enabled = enable; tbDBPassword.Enabled = enable; cbShowPassword.Enabled = enable; } private void EnableDestControls(bool enable) { tbDestinationDB.Enabled = enable; tbDestinationDB.Refresh(); btnBrowseDestinationDB.Enabled = enable; } private readonly string _targetDir; private string _targetDbDir; private readonly string _isoDir; private readonly string _scriptsDir; private string _sourceDbDir; private string _sourceDbName; private string _sourceDbNameWithExtension; public readonly Version _productVersion; public readonly string _majorMinorVersion; public readonly bool _standAlone; public readonly bool _cmdLine; private Dictionary _newSettingsDictionary = new Dictionary(); private SettingElementCollection _newSettings = new SettingElementCollection(); private Configuration _newConfig; private Dictionary _oldSettingsDictionary = new Dictionary(); private SettingElementCollection _oldSettings = new SettingElementCollection(); private Configuration _oldConfig; private Dictionary _currentSettingsDictionary = new Dictionary(); private DbType _originalRbDbType = DbType.Local; private string _originalTbDBHostname = string.Empty; private string _originalTbDBName = string.Empty; private bool _originalCbUseNTLMAuthentication = false; private string _originalTbDBPassword = string.Empty; private string _originalTbDBUser = string.Empty; private bool rbMigrateLocalSaved = true; private bool rbAeroSaved = false; private bool rbCrashSaved = false; private bool rbTSRAIRSaved = false; private bool rbNoneOfTheAboveSaved = false; private bool cbUseCentralizedNTLMAuthenticationSaved = false; private string tbDbHostnameSaved = string.Empty; private bool localDataExists = false; private bool destFolderExists = false; private bool localSQLiteDataExists = false; private bool localSQLLocalDbDataExists = false; private string previousDir = string.Empty; private string _mostRecentlyInstalledLowerVersion = string.Empty; private int oldDatabaseVersion = -1; private enum DbType { Centralized = 0, Local = 1, Both = 2 } private enum ConfigSettings { DBType, LocalDbHost, DBName, UseNTLMAuthentication, LocalDBUser, LocalDBPassword } private void rbLocal_CheckedChanged(object sender, EventArgs e) { _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += worker_DoWork; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; if (tbDBHostname.Text != string.Empty) { tbDbHostnameSaved = tbDBHostname.Text; } if (!rbLocal.Checked) return; localDataExists = LocalDataExists(); //44310 Re-evaluate so that _sourceDbDir is correct rbMigrateLocal.Enabled = localDataExists || _standAlone; cbCopyConfig.Checked = localDataExists; cbCopyConfig.Enabled = localDataExists; rbAero.Enabled = true; rbCrash.Enabled = true; rbTSRAIR.Enabled = true; rbNoneOfTheAbove.Enabled = true; rbNoneOfTheAbove.Checked = !rbMigrateLocal.Enabled; //Restore the radio buttons to what they were before Local or Both was de-selected, but only if there is data that can be copied or we're in standalone CheckRadioButton(rbMigrateLocal, rbMigrateLocalSaved && rbMigrateLocal.Enabled); CheckRadioButton(rbNoneOfTheAbove, rbNoneOfTheAboveSaved && rbNoneOfTheAbove.Enabled); tbDBHostname.Text = string.Empty; tbDBHostname.Enabled = false; cbUseCentralizedNTLMAuthenticationSaved = cbUseNTLMAuthentication.Checked; cbUseNTLMAuthentication.Checked = true; cbUseNTLMAuthentication.Enabled = false; tbDBUser.Text = string.Empty; tbDBUser.Enabled = false; tbDBPassword.Text = string.Empty; tbDBPassword.Enabled = false; cbShowPassword.Enabled = false; btnOK.Enabled = true; if (!_standAlone) return; ShowCentralizedControls(false); //since rbLocal is checked ShowStandAloneControls(true); //since rbLocal is checked SetMigrationStatus(""); SetStatus(localDataExists ? "" : Settings.Default.InvalidSourceDb); } private bool DestFolderExists() { var folderExists = false; if (_standAlone) { folderExists = Directory.Exists(tbDestinationDB.Text); } return folderExists; } private bool LocalDataExists() { if (_standAlone) { //Check for "DataPRO.mdf" (SqlLocalDb in 1.5 or later) in previously-installed folder log.WriteEntry($"Checking to see if {tbSourceDB.Text} exists"); if (!File.Exists(Path.Combine(tbSourceDB.Text))) return false; log.WriteEntry($"tbSourceDB.Text is {tbSourceDB.Text}"); if (tbSourceDB.Text.ToUpper().EndsWith(Settings.Default.Mdf.ToUpper())) { localSQLLocalDbDataExists = true; localSQLiteDataExists = false; } else if (tbSourceDB.Text.ToUpper().EndsWith(Settings.Default.Db.ToUpper())) { localSQLiteDataExists = true; localSQLLocalDbDataExists = false; } else { return false; } return true; } if (!PreviousVersionInstalled()) { return false; } if (rbMigrateLocal.Checked || rbBoth.Checked || rbLocal.Checked) { _sourceDbDir = Path.Combine(previousDir, Settings.Default.LocalDbFolder); } else { _sourceDbDir = Path.Combine(_targetDir, Settings.Default.LocalDbFolder); } //Check for "DataPRO.mdf" (SqlLocalDb in 1.5 or later) in previously-installed folder var sourceFileName = Path.Combine(previousDir, Settings.Default.LocalDbFolder, tbDBName.Text + Settings.Default.Mdf); if (File.Exists(sourceFileName)) { localSQLLocalDbDataExists = true; return true; } else { localSQLLocalDbDataExists = false; //Check for "datapro.db" (SQLite file in 1.4 or earlier) in previously-installed folder sourceFileName = Path.Combine(previousDir, Settings.Default.LocalDbFolder, tbDBName.Text + Settings.Default.Db); if (File.Exists(sourceFileName)) { localSQLiteDataExists = true; return true; } else { localSQLiteDataExists = false; return false; } } } private string GetPreviousDir() { var mostRecentlyInstalledSubKeyName = PreviousInstall.GetMostRecentlyInstalledSubKeyName(_productVersion, out string mostRecentlyInstalledLowerVersion); _mostRecentlyInstalledLowerVersion = mostRecentlyInstalledLowerVersion; if (mostRecentlyInstalledSubKeyName == string.Empty) return string.Empty; return PreviousInstall.GetMostRecentlyInstalledPath(mostRecentlyInstalledSubKeyName); } private bool PreviousVersionInstalled() { if (string.IsNullOrWhiteSpace(tbDBName.Text)) return false; previousDir = GetPreviousDir(); return !string.IsNullOrWhiteSpace(previousDir); } private void rbCentralized_CheckedChanged(object sender, EventArgs e) { if (tbDBHostname.Text != string.Empty) { tbDbHostnameSaved = tbDBHostname.Text; } if (!rbCentralized.Checked) return; DisableAndUncheckRadioButtons(); try { tbDBHostname.Text = tbDbHostnameSaved == string.Empty ? _currentSettingsDictionary[ConfigSettings.LocalDbHost.ToString()] : tbDbHostnameSaved; } catch { tbDBHostname.Text = string.Empty; } tbDBHostname.Enabled = true; //Restore the checkbox to what it was before Centralized was de-selected. cbUseNTLMAuthentication.Checked = cbUseCentralizedNTLMAuthenticationSaved; cbUseNTLMAuthentication.Enabled = true; EnableBasedOnNTLMAuthenticationCheckbox(); btnOK.Enabled = ValidateForMigration(); if (!_standAlone) return; ShowCentralizedControls(true); ShowStandAloneControls(false); SetMigrationStatus(""); SetStatus(""); } private void rbBoth_CheckedChanged(object sender, EventArgs e) { if (tbDBHostname.Text != string.Empty) { tbDbHostnameSaved = tbDBHostname.Text; } if (!rbBoth.Checked) return; localDataExists = LocalDataExists(); //44310 Re-evaluate so that _sourceDbDir is correct rbMigrateLocal.Enabled = localDataExists; rbNoneOfTheAbove.Enabled = true; //Restore the checkbox to what it was before Both was de-selected, but only if there is data that can be copied CheckRadioButton(rbMigrateLocal, rbMigrateLocalSaved && rbMigrateLocal.Enabled); CheckRadioButton(rbAero, rbAeroSaved && rbAero.Enabled); CheckRadioButton(rbCrash, rbCrashSaved && rbCrash.Enabled); CheckRadioButton(rbTSRAIR, rbTSRAIRSaved && rbTSRAIR.Enabled); CheckRadioButton(rbNoneOfTheAbove, rbNoneOfTheAboveSaved && rbNoneOfTheAbove.Enabled); try { tbDBHostname.Text = tbDbHostnameSaved == string.Empty ? _currentSettingsDictionary[ConfigSettings.LocalDbHost.ToString()] : tbDbHostnameSaved; } catch { tbDBHostname.Text = string.Empty; } tbDBHostname.Enabled = true; //Restore the checkbox to what it was before Both was de-selected. cbUseNTLMAuthentication.Checked = cbUseCentralizedNTLMAuthenticationSaved; cbUseNTLMAuthentication.Enabled = true; EnableBasedOnNTLMAuthenticationCheckbox(); if (!_standAlone) return; ShowCentralizedControls(true); ShowStandAloneControls(_standAlone); SetMigrationStatus(""); if (!localDataExists) { SetStatus(Settings.Default.InvalidSourceDb); } else if (!destFolderExists) { SetStatus(Settings.Default.InvalidDestinationDb); } } private void ShowStandAloneControls(bool show) { lblSourceDB.Visible = show; tbSourceDB.Visible = show; btnBrowseSourceDB.Visible = show; lblDestinationDB.Visible = show; tbDestinationDB.Visible = show; btnBrowseDestinationDB.Visible = show; rbBoth.Visible = false; } private void ShowCentralizedControls(bool show) { lblDBHostname.Visible = show; tbDBHostname.Visible = show; lblDBName.Visible = show; tbDBName.Visible = show; cbUseNTLMAuthentication.Visible = show; lblDBUser.Visible = show; tbDBUser.Visible = show; lblDBPassword.Visible = show; tbDBPassword.Visible = show; cbShowPassword.Visible = show; } private void cbUseNTLMAuthentication_CheckedChanged(object sender, EventArgs e) { EnableBasedOnNTLMAuthenticationCheckbox(); btnOK.Enabled = CentralizedIsValid(); } private void EnableBasedOnNTLMAuthenticationCheckbox() { if (cbUseNTLMAuthentication.Checked) { tbDBUser.Text = string.Empty; tbDBUser.Enabled = false; tbDBPassword.Text = string.Empty; tbDBPassword.Enabled = false; cbShowPassword.Enabled = false; } else { try { tbDBUser.Text = _currentSettingsDictionary[ConfigSettings.LocalDBUser.ToString()]; } catch { tbDBUser.Text = string.Empty; } tbDBUser.Enabled = true; try { tbDBPassword.Text = _currentSettingsDictionary[ConfigSettings.LocalDBPassword.ToString()]; } catch { tbDBPassword.Text = string.Empty; } tbDBPassword.Enabled = true; cbShowPassword.Enabled = true; } } private EventLog log = new EventLog(); private const int LAST_14_DB_VERSION = 57; private const int LAST_110_DB_VERSION = 70; private bool InitializeLocalDb() { if (CopyDbAndGetDbVersion()) { return true; } if (InitializeAndDetach()) { return true; } DeleteBackupDbs(); return true; } private bool CopyDbAndGetDbVersion() { Cursor.Current = Cursors.WaitCursor; Application.DoEvents(); log.WriteEntry("CopyDataFromPrevious checkbox was checked"); //Copy the blank db so that it can be used if migration fails if (!rbAero.Checked && !rbCrash.Checked && !rbTSRAIR.Checked) { if (_standAlone) { //If the destination db exists, make a copy //30701 Migration fails when db not named "DataPRO". var sourceFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.Initial + Settings.Default.Mdf); if (File.Exists(sourceFileName)) { File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); } sourceFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.Initial + Settings.Default.LogLdf); if (File.Exists(sourceFileName)) { File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); } //Start with a blank db from our db folder sourceFileName = Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder, Settings.Default.DataPROBlankMdf); destFileName = Path.Combine(_targetDbDir, _sourceDbName + ".mdf"); File.Copy(sourceFileName, destFileName, true); sourceFileName = Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder, Settings.Default.DataPROBlankLogLdf); destFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); } else { var sourceFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Initial + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); sourceFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Initial + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); } } if (_worker.CancellationPending) return true; if (!_standAlone && rbMigrateLocal.Checked) { //Get the previous local database version SetMigrationStatus(Settings.Default.QueryingPrevLocalDbVersion); oldDatabaseVersion = GetPreviousDatabaseVersion(true); } if (_worker.CancellationPending) return true; return false; } private bool InitializeAndDetach() { var result = false; if (_worker.CancellationPending) return true; DbOperations.Connection.DBName = "DataPRO"; //fix this tbDBName.Text; var commonUtilities = new CommonUtilities(); var resultString = commonUtilities.Attach(_targetDbDir, _scriptsDir); if (_worker.CancellationPending) return true; if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } else { if (rbAero.Checked) { var outputString = string.Format(Settings.Default.InitializingDb, Settings.Default.Aero, Settings.Default.ThirtySeconds); log.WriteEntry(outputString); SetMigrationStatus(outputString); DbOperations.Connection.Initialize(InitializationTypes.Aero, _targetDir); } else if (rbCrash.Checked) { var outputString = string.Format(Settings.Default.InitializingDb, Settings.Default.Crash, string.Empty); log.WriteEntry(outputString); SetMigrationStatus(outputString); DbOperations.Connection.Initialize(InitializationTypes.Crash, _targetDir); } else if (rbTSRAIR.Checked) { var outputString = string.Format(Settings.Default.InitializingDb, Settings.Default.TSRAIR, string.Empty); log.WriteEntry(outputString); SetMigrationStatus(outputString); DbOperations.Connection.Initialize(InitializationTypes.TSRAIR, _targetDir); } if (_worker.CancellationPending) return true; _ = commonUtilities.Detach(_sourceDbName, _targetDbDir, _scriptsDir); } return result; } private bool CopyAndMigrate() { DbOperations.Connection.DbVersion = oldDatabaseVersion; log.WriteEntry(Settings.Default.CopyingPrevLocalDb); SetMigrationStatus(Settings.Default.CopyingPrevLocalDb); //Copy the previous database to the current folder if (CopyLocalDB(_sourceDbName, true)) { if (_worker.CancellationPending) return true; var commonUtilities = new CommonUtilities(); var resultString = commonUtilities.Attach(_targetDbDir, _scriptsDir); if (_worker.CancellationPending) return true; if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } else { //Migrate the database try { if (rbMigrateLocal.Checked) { var outputString = string.Format(Settings.Default.MigratingPrevLocalDb, oldDatabaseVersion, DbOperations.CURRENT_DB_VERSION); log.WriteEntry(outputString); SetMigrationStatus(outputString); //30701 Migration fails when db not named "DataPRO". if (_standAlone) { previousDir = GetPreviousDir(); } MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(DbOperations.CURRENT_DB_VERSION, SetStatus, tbDBName.Text.Trim(), previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); //handle exceptions and display error if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } } if (_worker.CancellationPending) return true; resultString = commonUtilities.Detach(_sourceDbName, _targetDbDir, _scriptsDir); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } } catch (Exception ex) { log.WriteEntry("Local database migration error occurred: " + ex.Message); throw; } } } else { MessageBox.Show(string.Format(Settings.Default.DatabaseNotCopied, Environment.NewLine + Environment.NewLine), Settings.Default.Success, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } return false; } private void DeleteBackupDbs() { if (!rbBoth.Checked && !_standAlone) { //All went well, so remove the blank database that was created in case of a migration failure log.WriteEntry("Deleting copied database..."); SetMigrationStatus("Deleting copied database..."); var deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.Mdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.LogLdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); } SetMigrationStatus(""); } private bool CopyAndMigrateLocalDb() { try { if (CopyDbAndGetDbVersion()) { return true; } var commonUtilities = new CommonUtilities(); if (oldDatabaseVersion < DbOperations.CURRENT_DB_VERSION) { log.WriteEntry("Old local database version, " + oldDatabaseVersion + ", is less than current, " + DbOperations.CURRENT_DB_VERSION); if (oldDatabaseVersion > 0 && oldDatabaseVersion <= LAST_14_DB_VERSION) { //Export old local (SQLite) database to xml var dialogResult = MessageBox.Show(string.Format(Settings.Default.DatabaseMigrationRequired, Environment.NewLine + Environment.NewLine), Settings.Default.Warning, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); if (dialogResult == DialogResult.OK) { log.WriteEntry("User wants to migrate local database"); //Make a backup copy of the SQLite database log.WriteEntry("Making a backup copy"); if (_worker.CancellationPending) return true; if (oldDatabaseVersion < LAST_14_DB_VERSION) { log.WriteEntry(string.Format(Settings.Default.MigratingPrevLocalDb, oldDatabaseVersion, LAST_14_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingPrevLocalDb, oldDatabaseVersion, LAST_14_DB_VERSION)); MigrateDatabaseUpToLast14DbVersion(oldDatabaseVersion); } if (_worker.CancellationPending) return true; var resultString = commonUtilities.InstallDatabase(_targetDbDir, tbDBName.Text.Trim(), _scriptsDir); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } try { var dbExporter = new DatabaseExport.DbExporter(_isoDir); var dbBackupTimestamp = $"{DateTime.Now.Year:0000}_{DateTime.Now.Month:00}_{DateTime.Now.Day:00}_{DateTime.Now.Hour:00}_{DateTime.Now.Minute:00}"; string exportFileName; if (_standAlone) { exportFileName = tbSourceDB.Text + "_" + dbBackupTimestamp + ".dbxml"; } else { exportFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + "_" + dbBackupTimestamp + ".dbxml"); } log.WriteEntry(string.Format(Settings.Default.ExportingPrevDb, exportFileName)); SetMigrationStatus(string.Format(Settings.Default.ExportingPrevDb, exportFileName)); DatabaseExport.DbOperations.Connection.Server = Settings.Default.LocalDbDataPROInstance; DatabaseExport.DbOperations._usingMSSQL = false; DatabaseExport.DbOperations._usingNTLMAuthentication = cbUseNTLMAuthentication.Checked; if (_standAlone) { DatabaseExport.DbOperations._previousDir = previousDir; } else { DatabaseExport.DbOperations._previousDir = previousDir + "\\db"; } dbExporter.WriteExportXML(previousDir, exportFileName, SetStatus); if (_worker.CancellationPending) return true; var importChoiceResult = MessageBox.Show(string.Format(Settings.Default.ImportChoice, exportFileName, Environment.NewLine + Environment.NewLine), Settings.Default.ActionRequired, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); if (importChoiceResult == DialogResult.OK) { log.WriteEntry(string.Format(Settings.Default.AttachingBlankLocalTempDb, exportFileName)); SetMigrationStatus(string.Format(Settings.Default.AttachingBlankLocalTempDb, exportFileName)); if (_standAlone) { //Copy the DataPROPre20.mdf/.ldf pair as the database name var sourceFileName = Path.Combine(Settings.Default.LocalDbFolder, Settings.Default.DataPRO + Settings.Default.Pre20 + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Pre20 + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry("Stand-alone " + sourceFileName + " was copied as " + destFileName); sourceFileName = Path.Combine(Settings.Default.LocalDbFolder, Settings.Default.DataPRO + Settings.Default.Pre20 + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Pre20 + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry("Stand-alone " + sourceFileName + " was copied as " + destFileName); //Copy the ISO.mdf/.ldf pair sourceFileName = Path.Combine(Settings.Default.LocalDbFolder, Settings.Default.ISO + Settings.Default.Mdf); destFileName = Path.Combine(_targetDbDir, Settings.Default.ISO + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry("Stand-alone " + sourceFileName + " was copied as " + destFileName); sourceFileName = Path.Combine(Settings.Default.LocalDbFolder, Settings.Default.ISO + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, Settings.Default.ISO + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry("Stand-alone " + sourceFileName + " was copied as " + destFileName); } if (_worker.CancellationPending) return true; resultString = commonUtilities.InstallDatabase(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Pre20, _scriptsDir); if (_worker.CancellationPending) return true; if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); if (_worker.CancellationPending) return true; } log.WriteEntry(string.Format(Settings.Default.ImportingToTempLocalDb, exportFileName)); SetMigrationStatus(string.Format(Settings.Default.ImportingToTempLocalDb, exportFileName)); //Import from xml into new database var dbImporter = new DatabaseImport.DbImporter(); DatabaseImport.DbOperations.Connection.DBName = tbDBName.Text + Settings.Default.Pre20; DatabaseImport.DbOperations._usingCentralizedDB = false; DatabaseImport.DbOperations._usingMSSQL = true; DatabaseImport.DbOperations.Connection.Server = Settings.Default.LocalDbDataPROInstance; DatabaseImport.DbOperations._usingNTLMAuthentication = true; DatabaseImport.DbOperations._previousDir = previousDir; dbImporter.ImportXML(exportFileName, SetStatus); if (_worker.CancellationPending) return true; if (!_standAlone) { log.WriteEntry("Updating User Properties from config..."); SetMigrationStatus("Updating User Properties from config..."); var configToDbMigrator = new ConfigToDb.ConfigToDbMigrator(); var result = string.Empty; var subKey = PreviousInstall.GetMostRecentlyInstalledSubKeyName(_productVersion, out string nextLowerVersion); if (_worker.CancellationPending) return true; if (string.IsNullOrWhiteSpace(subKey)) return true; var nextLowerPath = PreviousInstall.GetMostRecentlyInstalledPath(subKey); configToDbMigrator.migrateConfigToDb(nextLowerPath, out result); if (_worker.CancellationPending) return true; if (string.IsNullOrWhiteSpace(result)) { log.WriteEntry("Done with User Property update"); SetMigrationStatus("Done with User Property update"); } else { log.WriteEntry("User Property update not done"); SetMigrationStatus("User Property update not done"); } } DbOperations.Connection.DbVersion = LAST_110_DB_VERSION; //Now migrate the database from LAST_110_DB_VERSION to the current version MigrateFromTemporaryLocalDatabase(); //Detach the database log.WriteEntry(string.Format(Settings.Default.DetachingLocalMigratedDb, _sourceDbName)); SetMigrationStatus(string.Format(Settings.Default.DetachingLocalMigratedDb, _sourceDbName)); var dbFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.Mdf); var logFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.LogLdf); resultString = CommonUtilities.AttachOrDetachDatabase(_scriptsDir, _sourceDbName, dbFileName, logFileName, Settings.Default.DetachDBsbat); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } } else { log.WriteEntry("User cancelled automatic import of data into new local database"); } } catch (Exception ex) { log.WriteEntry($"Local database export failed: {ex.Message}{Environment.NewLine}{ex.StackTrace}"); throw; } } else { log.WriteEntry("User has cancelled local database migration"); MessageBox.Show(string.Format(Settings.Default.DatabaseMigrationCancelled, Environment.NewLine + Environment.NewLine), Settings.Default.ActionRequired, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } } else if (oldDatabaseVersion > LAST_14_DB_VERSION && oldDatabaseVersion <= LAST_110_DB_VERSION) { //Database version is greater than LAST_14_DB_VERSION, but less than the 2.0 version (71), //so doesn't need to be exported, but still needs to be first migrated to LAST_110_DB_VERSION //in a temporary database and then migrated further to the current version. DbOperations.Connection.DbVersion = oldDatabaseVersion; log.WriteEntry(Settings.Default.CopyingPrevLocalDb); SetMigrationStatus(Settings.Default.CopyingPrevLocalDb); //Copy the previous database temporarily to the current folder if (CopyLocalDB(_sourceDbName + Settings.Default.Pre20, false)) { if (_worker.CancellationPending) return true; log.WriteEntry(Settings.Default.TempAttachingCopyPrevLocalDb); SetMigrationStatus(Settings.Default.TempAttachingCopyPrevLocalDb); var resultString = commonUtilities.InstallDatabase(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Pre20, _scriptsDir); if (_worker.CancellationPending) return true; if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } else { if (oldDatabaseVersion < LAST_110_DB_VERSION) { //Migrate the database to version LAST_110_DB_VERSION log.WriteEntry(string.Format(Settings.Default.MigratingPrevLocalDb, oldDatabaseVersion, LAST_110_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingPrevLocalDb, oldDatabaseVersion, LAST_110_DB_VERSION)); try { DbOperations.Connection.ResetLocalConnectionStringDb(tbDBName.Text.Trim() + Settings.Default.Pre20); MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(LAST_110_DB_VERSION, SetStatus, tbDBName.Text.Trim(), previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); //handle exceptions and display error if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } if (_worker.CancellationPending) return true; } catch (Exception ex) { log.WriteEntry("Local database migration to version " + LAST_110_DB_VERSION + " error occurred: " + ex.Message); throw; } } //Now migrate the database from LAST_110_DB_VERSION (70) to the current version log.WriteEntry(string.Format(Settings.Default.MigratingPrevLocalDb, LAST_110_DB_VERSION, DbOperations.CURRENT_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingPrevLocalDb, LAST_110_DB_VERSION, DbOperations.CURRENT_DB_VERSION)); MigrateFromTemporaryLocalDatabase(); if (_worker.CancellationPending) return true; //Detach the database log.WriteEntry(string.Format(Settings.Default.DetachingLocalMigratedDb, _sourceDbName)); SetMigrationStatus(string.Format(Settings.Default.DetachingLocalMigratedDb, _sourceDbName)); var dbFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.Mdf); var logFileName = Path.Combine(_targetDbDir, _sourceDbName + Settings.Default.LogLdf); resultString = CommonUtilities.AttachOrDetachDatabase(_scriptsDir, _sourceDbName, dbFileName, logFileName, Settings.Default.DetachDBsbat); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } } } else { MessageBox.Show(string.Format(Settings.Default.DatabaseNotCopied, Environment.NewLine + Environment.NewLine), Settings.Default.Success, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } } else if (oldDatabaseVersion >= LAST_110_DB_VERSION + 1) { //Database version is 2.0 so doesn't need to be exported, nor migrated through a temporary database, just migrated if (CopyAndMigrate()) { return true; } } else { //Database version must be 0, so an error occurred log.WriteEntry("Local database version is 0, so an error occurred"); throw new Exception(Settings.Default.DatabaseVersionError); } } else { //The database version is greater than or equal to the installing version if (oldDatabaseVersion == DbOperations.CURRENT_DB_VERSION) { log.WriteEntry("Old local database version, " + oldDatabaseVersion + ", is equal to current, " + DbOperations.CURRENT_DB_VERSION); log.WriteEntry(Settings.Default.CopyingPrevLocalDbNoMigration); SetMigrationStatus(Settings.Default.CopyingPrevLocalDbNoMigration); //Copy the previous database to the current folder CopyLocalDB(_sourceDbName, true); } else { //This shouldn't happen, but the most-recently installed database version is greater than this one?! log.WriteEntry("Old local database version, " + oldDatabaseVersion + ", is greater than current, " + DbOperations.CURRENT_DB_VERSION); } } DeleteBackupDbs(); } catch (Exception ex) { log.WriteEntry("In catch: " + ex.Message); if (!_standAlone) { //Detach the destination db so it can be overwritten by the blank db log.WriteEntry("Detaching destination local database..."); SetMigrationStatus("Detaching destination local database..."); var dbFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Mdf); var logFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.LogLdf); var resultString = CommonUtilities.AttachOrDetachDatabase(_scriptsDir, tbDBName.Text.Trim(), dbFileName, logFileName, Settings.Default.DetachDBsbat); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } //Copy the blank db (DataPROInitial.mdf) as DataPRO.mdf since migration failed, so that it can be used var sourceFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); sourceFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); //Since we've copied the blank database so it can be used, remove it to avoid confusion var deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.Mdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.LogLdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); } Cursor.Current = Cursors.Default; MessageBox.Show( string.Format(Settings.Default.LocalDatabaseMigrationFailed, Environment.NewLine, ex.Message, Environment.NewLine), Settings.Default.ActionRequired, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); cancelled = true; } finally { Cursor.Current = Cursors.Default; } return true; } private void ConvertResultAndDisplay(MigrationResult result) { string stringResult = ConvertMigrationResultToSetting(result); MessageBox.Show(stringResult, Settings.Default.ActionRequired, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); } private string ConvertMigrationResultToSetting(MigrationResult result) { var stringResult = string.Empty; switch (result) { case MigrationResult.OK: break; case MigrationResult.ExceptionThrown: break; case MigrationResult.WarningAllowStreamingModesWasNotMigrated: stringResult = string.Format(Settings.Default.WarningAllowStreamingModesWasNotMigrated, Environment.NewLine, Environment.NewLine); break; } return stringResult; } string DestFolder = string.Empty; private void CreateDirectoryPermissions() { DestFolder = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder; if (!Directory.Exists(DestFolder)) { Directory.CreateDirectory(DestFolder); } var ds = new DirectorySecurity(); DirectoryInfo dInfo = new DirectoryInfo(DestFolder); DirectorySecurity dSecurity = dInfo.GetAccessControl(); dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow)); dInfo.SetAccessControl(dSecurity); } private bool MigrateCentralizedDb() { var deleteFileName = string.Empty; try { if (!rbBoth.Checked && !_standAlone) { //Copy the blank db so that it can be used locally if migration fails var sourceFileName = Path.Combine(_targetDbDir, tbDBName.Text + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, tbDBName.Text + Settings.Default.Initial + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); sourceFileName = Path.Combine(_targetDbDir, tbDBName.Text + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, tbDBName.Text + Settings.Default.Initial + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); if (_worker.CancellationPending) return true; } SetMigrationStatus(Settings.Default.QueryingCentralizedDbVersion); oldDatabaseVersion = GetPreviousDatabaseVersion(false); SetMigrationStatus(string.Format(Settings.Default.DisplayDatabaseVersion, oldDatabaseVersion)); if (_worker.CancellationPending) return true; if (oldDatabaseVersion == 0) { CreateDirectoryPermissions(); if (_worker.CancellationPending) return true; //Delete any old DataPROBackup.bak file log.WriteEntry(Settings.Default.DeletingRemoteDataPROBackupBak); SetMigrationStatus(Settings.Default.DeletingRemoteDataPROBackupBak); deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + Settings.Default.BackupBak; File.Delete(deleteFileName); if (_worker.CancellationPending) return true; //Backup (just DataPRO or whatever it is named), Alter and Detach the remote " + tbDBName.Text.Trim() + " and/or ISO databases. log.WriteEntry(string.Format(Settings.Default.BackingUpAlteringDetachingRemoteDb, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.BackingUpAlteringDetachingRemoteDb, tbDBName.Text.Trim())); var backupAlterDetachBatchFile = Path.Combine(_scriptsDir, Settings.Default.BackupAlterDetachbat); const string SqlCmdExe = "sqlcmd.exe"; var oDBCToolsPath = DTS.Common.Utils.Database.GetODBCToolsPath(null); var fullSqlcmdPath = Path.Combine(oDBCToolsPath, SqlCmdExe); //e.g. $"\"C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\110\\Tools\\Binn\\sqlcmd.exe\"" var output = RunRemoteBatchCommand(backupAlterDetachBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); if (_worker.CancellationPending) return true; CopyAndAttachDatabases(); if (_worker.CancellationPending) return true; } else if (oldDatabaseVersion < DbOperations.CURRENT_DB_VERSION) { log.WriteEntry("Old centralized database version, " + oldDatabaseVersion + ", is less than current, " + DbOperations.CURRENT_DB_VERSION); if (oldDatabaseVersion > 0 && oldDatabaseVersion <= LAST_14_DB_VERSION) { //Export old centralized (SQL Server) database to xml log.WriteEntry("User wants to migrate centralized database"); if (oldDatabaseVersion < LAST_14_DB_VERSION) { log.WriteEntry(string.Format(Settings.Default.MigratingPrevCentralizedDb, oldDatabaseVersion)); SetMigrationStatus(string.Format(Settings.Default.MigratingPrevCentralizedDb, oldDatabaseVersion)); MigrateDatabaseUpToLast14DbVersion(oldDatabaseVersion); if (_worker.CancellationPending) return true; } try { var dbExporter = new DatabaseExport.DbExporter(_isoDir); var dbBackupTimestamp = $"{DateTime.Now.Year:0000}_{DateTime.Now.Month:00}_{DateTime.Now.Day:00}_{DateTime.Now.Hour:00}_{DateTime.Now.Minute:00}"; var exportFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + "_" + dbBackupTimestamp + ".dbxml"); log.WriteEntry(string.Format(Settings.Default.ExportingPrevDb, exportFileName)); SetMigrationStatus(string.Format(Settings.Default.ExportingPrevDb, exportFileName)); DatabaseExport.DbOperations.Connection.Server = tbDBHostname.Text; DatabaseExport.DbOperations._usingMSSQL = true; DatabaseExport.DbOperations._usingNTLMAuthentication = cbUseNTLMAuthentication.Checked; if (_standAlone) { DatabaseExport.DbOperations._previousDir = previousDir; } else { DatabaseExport.DbOperations._previousDir = previousDir + "\\db"; } DatabaseExport.DbOperations.Connection.DBName = tbDBName.Text.Trim(); dbExporter.WriteExportXML(previousDir, exportFileName, SetStatus); if (_worker.CancellationPending) return true; log.WriteEntry(string.Format(Settings.Default.ImportingToNewCentralizedDb, exportFileName)); SetMigrationStatus(string.Format(Settings.Default.ImportingToNewCentralizedDb, exportFileName)); CreateDirectoryPermissions(); if (_worker.CancellationPending) return true; //Delete any old DataPROBackup.bak file log.WriteEntry(Settings.Default.DeletingRemoteDataPROBackupBak); SetMigrationStatus(Settings.Default.DeletingRemoteDataPROBackupBak); deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + Settings.Default.BackupBak; File.Delete(deleteFileName); if (_worker.CancellationPending) return true; //Backup, Alter and Detach the remote 1.4 database log.WriteEntry(string.Format(Settings.Default.BackingUpAlteringDetachingRemoteDb, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.BackingUpAlteringDetachingRemoteDb, tbDBName.Text.Trim())); var backupAlterDetachBatchFile = Path.Combine(_scriptsDir, Settings.Default.BackupAlterDetachbat); const string SqlCmdExe = "sqlcmd.exe"; var oDBCToolsPath = DTS.Common.Utils.Database.GetODBCToolsPath(null); var fullSqlcmdPath = Path.Combine(oDBCToolsPath, SqlCmdExe); //e.g. $"\"C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\110\\Tools\\Binn\\sqlcmd.exe\"" var output = RunRemoteBatchCommand(backupAlterDetachBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); //log.WriteEntry(output); //SetMigrationStatus(output); if (_worker.CancellationPending) return true; //Copy DataPRO, ISO, and DataPROPre20 databases to C:\DataPRO_SQL on server and Attach all 3 CopyAndAttachDatabases(); //DataPRO and ISO if (_worker.CancellationPending) return true; CopyAndAttachDataPROPre20Database(); if (_worker.CancellationPending) return true; //Import from xml into new database var dbImporter = new DatabaseImport.DbImporter(); DatabaseImport.DbOperations.Connection.DBName = tbDBName.Text + Settings.Default.Pre20; DatabaseImport.DbOperations._usingCentralizedDB = true; DatabaseImport.DbOperations._usingMSSQL = true; DatabaseImport.DbOperations.Connection.Server = tbDBHostname.Text; DatabaseImport.DbOperations._usingNTLMAuthentication = true; DatabaseImport.DbOperations._previousDir = previousDir; dbImporter.ImportXML(exportFileName, SetStatus); if (_worker.CancellationPending) return true; log.WriteEntry("Updating User Properties from config..."); SetMigrationStatus("Updating User Properties from config..."); var configToDbMigrator = new ConfigToDb.ConfigToDbMigrator(); var result = string.Empty; var subKey = PreviousInstall.GetMostRecentlyInstalledSubKeyName(_productVersion, out string nextLowerVersion); if (_worker.CancellationPending) return true; if (string.IsNullOrWhiteSpace(subKey)) return true; var nextLowerPath = PreviousInstall.GetMostRecentlyInstalledPath(subKey); if (_worker.CancellationPending) return true; configToDbMigrator.migrateConfigToDb(nextLowerPath, out result); if (_worker.CancellationPending) return true; if (string.IsNullOrWhiteSpace(result)) { log.WriteEntry("Done with User Property update"); SetMigrationStatus("Done with User Property update"); } else { log.WriteEntry("User Property update not done"); SetMigrationStatus("User Property update not done"); } DbOperations.Connection.DbVersion = LAST_110_DB_VERSION; //Now migrate the database from LAST_110_DB_VERSION (70) to the current version MigrateFromTemporaryCentralizedDatabase(tbDBName.Text.Trim()); if (_worker.CancellationPending) return true; //Detach the DataPROPre20 db from the central server log.WriteEntry(string.Format(Settings.Default.DetachingRemoteTempPre20Db, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DetachingRemoteTempPre20Db, tbDBName.Text.Trim())); var detachBatchFile = Path.Combine(_scriptsDir, Settings.Default.DetachRemoteDBbat); output = RunRemoteBatchCommand(detachBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); log.WriteEntry(output); } catch (Exception ex) { log.WriteEntry($"Centralized database export failed: {ex.Message}{Environment.NewLine}{ex.StackTrace}"); throw; } } else if (oldDatabaseVersion > LAST_14_DB_VERSION && oldDatabaseVersion <= LAST_110_DB_VERSION) { //Database version is greater than LAST_14_DB_VERSION, but less than the 2.0 version (71), //so doesn't need to be exported, but still needs to be first migrated to LAST_110_DB_VERSION //in a temporary database and then migrated further to the current version. DbOperations.Connection.DbVersion = oldDatabaseVersion; CreateDirectoryPermissions(); if (_worker.CancellationPending) return true; //Delete any old Backup.bak file log.WriteEntry(string.Format(Settings.Default.DeletingRemoteBackupBak, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DeletingRemoteBackupBak, tbDBName.Text.Trim())); deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.BackupBak; File.Delete(deleteFileName); if (_worker.CancellationPending) return true; //Backup, Alter and Detach the remote 1.10 databases log.WriteEntry(string.Format(Settings.Default.BackingUpAlteringDetachingRemoteDbAndISO, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.BackingUpAlteringDetachingRemoteDbAndISO, tbDBName.Text.Trim())); var backupAlterDetachBatchFile = Path.Combine(_scriptsDir, Settings.Default.BackupAlterDetachbat); const string SqlCmdExe = "sqlcmd.exe"; var oDBCToolsPath = DTS.Common.Utils.Database.GetODBCToolsPath(null); var fullSqlcmdPath = Path.Combine(oDBCToolsPath, SqlCmdExe); //e.g. $"\"C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\110\\Tools\\Binn\\sqlcmd.exe\"" var output = RunRemoteBatchCommand(backupAlterDetachBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); if (_worker.CancellationPending) return true; //Delete any old DataPROPre20.mdf and DataPROPre20_Log.ldf files log.WriteEntry(string.Format(Settings.Default.DeletingRemotePre20Mdf, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DeletingRemotePre20Mdf, tbDBName.Text.Trim())); deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.Pre20 + Settings.Default.Mdf; File.Delete(deleteFileName); if (_worker.CancellationPending) return true; log.WriteEntry(string.Format(Settings.Default.DeletingRemotePre20Log, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DeletingRemotePre20Log, tbDBName.Text.Trim())); deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.Pre20 + Settings.Default.LogLdf; File.Delete(deleteFileName); if (_worker.CancellationPending) return true; //Restore the remote 1.10 database as DataPROPre20 log.WriteEntry(Settings.Default.RestoringRemoteDataPROAsPre20); SetMigrationStatus(Settings.Default.RestoringRemoteDataPROAsPre20); var restoreAsDataPROPre20BatchFile = Path.Combine(_scriptsDir, Settings.Default.RestoreAsDataPROPre20bat); output = RunRemoteBatchCommand(restoreAsDataPROPre20BatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); log.WriteEntry(output); if (_worker.CancellationPending) return true; CopyAndAttachDatabases(); if (_worker.CancellationPending) return true; try { //Migrate the database to version LAST_110_DB_VERSION if it's not already there if (oldDatabaseVersion < LAST_110_DB_VERSION) { log.WriteEntry(string.Format(Settings.Default.MigratingPrevCentralizedDbToIntermediate, oldDatabaseVersion, LAST_110_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingPrevCentralizedDbToIntermediate, oldDatabaseVersion, LAST_110_DB_VERSION)); DbOperations.Connection.ResetLocalConnectionStringDb(tbDBName.Text.Trim() + Settings.Default.Pre20); MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(DbOperations.CURRENT_DB_VERSION, SetStatus, tbDBName.Text.Trim(), previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); //handle exceptions and display error if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } if (_worker.CancellationPending) return true; } //Now migrate the database to the current version MigrateFromTemporaryCentralizedDatabase(tbDBName.Text.Trim()); if (_worker.CancellationPending) return true; //Detach Pre20 db from the central server log.WriteEntry(string.Format(Settings.Default.DetachingRemoteTempPre20Db, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DetachingRemoteTempPre20Db, tbDBName.Text.Trim())); var detachBatchFile = Path.Combine(_scriptsDir, Settings.Default.DetachRemoteDBbat); output = RunRemoteBatchCommand(detachBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); log.WriteEntry(output); } catch (Exception ex) { log.WriteEntry("Centralized database migration to version " + LAST_110_DB_VERSION + " error occurred: " + ex.Message); throw; } } else if (oldDatabaseVersion > LAST_110_DB_VERSION) { //Database version is later than 1.10 so doesn't need to be exported, nor migrated to a temporary database, just migrated DbOperations.Connection.DbVersion = oldDatabaseVersion; //Warn user that Centralized database will be migrated to the new version, and that it is recommended that //the old database is backed up more recently (now) than the regularly-scheduled nightly/weekly backup. var rslt = MessageBox.Show(string.Format(Settings.Default.CentralizedDatabaseShouldBeBackedUp, Environment.NewLine), Settings.Default.ActionRequired, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); if (rslt == DialogResult.Cancel) { //Display this message box before attempting to copy the blank database in case it fails (after all the migration failed for some reason). MessageBox.Show(string.Format(Settings.Default.CentralizedDatabaseMigrationCancelled, Environment.NewLine), Settings.Default.ActionRequired, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); NoMigrationCleanup(); return true; } //Migrate the database log.WriteEntry(string.Format(Settings.Default.MigratingPrevCentralizedDb, oldDatabaseVersion, DbOperations.CURRENT_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingPrevCentralizedDb, oldDatabaseVersion, DbOperations.CURRENT_DB_VERSION)); try { MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(DbOperations.CURRENT_DB_VERSION, SetStatus, tbDBName.Text.Trim(), previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); //handle exceptions and display error if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } SetMigrationStatus(""); if (_worker.CancellationPending) return true; } catch (Exception ex) { log.WriteEntry("Centralized database migration error occurred: " + ex.Message); throw; } } else { //Database version must be 0, so an error occurred log.WriteEntry("Centralized database version is 0, so an error occurred"); throw new Exception(Settings.Default.DatabaseVersionError); } } else { //The database version is greater than or equal to the installing version if (oldDatabaseVersion == DbOperations.CURRENT_DB_VERSION) { log.WriteEntry("Old centralized database version, " + oldDatabaseVersion + ", is equal to current, " + DbOperations.CURRENT_DB_VERSION); } else { //The mounted db version is greater than what we are trying to migrate to, so do nothing. log.WriteEntry("Old centralized database version, " + oldDatabaseVersion + ", is greater than current, " + DbOperations.CURRENT_DB_VERSION); } SetMigrationStatus(string.Format(Settings.Default.NoMigrationNeeded, " ", oldDatabaseVersion, DbOperations.CURRENT_DB_VERSION)); } if (!rbBoth.Checked && !_standAlone) { //All went well, so remove the blank local database that was created in case of a migration failure deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.Mdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.LogLdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); } } catch (Exception ex) { if (ex.InnerException != null && ex.InnerException.Message == "The network path was not found") { SetMigrationStatus(""); SetStatus(string.Format(Settings.Default.NetworkError, ex.InnerException.Message)); return false; } else if (ex.Message.Contains("Login failed for user")) { SetMigrationStatus(""); SetStatus(string.Format(Settings.Default.NetworkError, ex.Message)); return false; } else if (ex.Message.Contains("Access to the path '" + DestFolder + "' is denied.")) { SetMigrationStatus(string.Format(Settings.Default.AccessError, ex.Message)); SetStatus(string.Format(Settings.Default.AccessRetry)); return false; } else { //Display this message box before attempting to copy the blank database in case it fails (after all the migration failed for some reason). MessageBox.Show(string.Format(Settings.Default.CentralizedDatabaseMigrationFailed, Environment.NewLine, ex.Message, Environment.NewLine), Settings.Default.ActionRequired, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); NoMigrationCleanup(); //Revert to the blank local database so this version can be used rbLocal.Checked = true; } } return true; } private void NoMigrationCleanup() { //Copy the blank db (DataPROInitial.mdf) as DataPRO.mdf since migration failed, so that it can be used var sourceFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); sourceFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); //Since we've copied the blank database so it can be used, remove it to avoid confusion var deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.Mdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); deleteFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Initial + Settings.Default.LogLdf); File.Delete(deleteFileName); log.WriteEntry(deleteFileName + " was deleted"); } private void CopyAndAttachDataPROPre20Database() { //Copy the 2.0 DataPROPre20.mdf file to remote server log.WriteEntry(Settings.Default.CopyingNewDataPROPre20MdfToRemote); SetMigrationStatus(Settings.Default.CopyingNewDataPROPre20MdfToRemote); var sourceFile = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Pre20) + Settings.Default.Mdf; var destFile = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.Pre20 + Settings.Default.Mdf; File.Copy(sourceFile, destFile, true); log.WriteEntry(string.Format(Settings.Default.DeletingRemotePre20Log, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DeletingRemotePre20Log, tbDBName.Text.Trim())); var deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.Pre20 + Settings.Default.LogLdf; File.Delete(deleteFileName); //Attach 2.0 DataPROPre20 database on remote server log.WriteEntry(string.Format(Settings.Default.AttachingRemotePre20Db, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.AttachingRemotePre20Db, tbDBName.Text.Trim())); var attachDataPROPre20RemoteBatchFile = Path.Combine(_scriptsDir, Settings.Default.AttachDataPROPre20Remotebat); const string SqlCmdExe = "sqlcmd.exe"; var oDBCToolsPath = DTS.Common.Utils.Database.GetODBCToolsPath(null); var fullSqlcmdPath = Path.Combine(oDBCToolsPath, SqlCmdExe); //e.g. $"\"C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\110\\Tools\\Binn\\sqlcmd.exe\"" var output = RunRemoteBatchCommand(attachDataPROPre20RemoteBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); log.WriteEntry(output); } private void CopyAndAttachDatabases() { //Copy the blank DataPRO.mdf file to remote server log.WriteEntry(Settings.Default.CopyingNewDataPROMdfToRemote); SetMigrationStatus(Settings.Default.CopyingNewDataPROMdfToRemote); var sourceFile = Path.Combine(_targetDbDir, Settings.Default.DataPRO) + Settings.Default.Mdf; var destFile = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.Mdf; File.Copy(sourceFile, destFile, true); log.WriteEntry(string.Format(Settings.Default.DeletingRemoteLog, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.DeletingRemoteLog, tbDBName.Text.Trim())); var deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + tbDBName.Text.Trim() + Settings.Default.LogLdf; File.Delete(deleteFileName); //Attach blank DataPRO database on remote server log.WriteEntry(string.Format(Settings.Default.AttachingRemoteDb, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.AttachingRemoteDb, tbDBName.Text.Trim())); var attachDataPRORemoteBatchFile = Path.Combine(_scriptsDir, Settings.Default.AttachDataPRORemotebat); const string SqlCmdExe = "sqlcmd.exe"; var oDBCToolsPath = DTS.Common.Utils.Database.GetODBCToolsPath(null); var fullSqlcmdPath = Path.Combine(oDBCToolsPath, SqlCmdExe); //e.g. $"\"C:\\Program Files\\Microsoft SQL Server\\Client SDK\\ODBC\\110\\Tools\\Binn\\sqlcmd.exe\"" var output = RunRemoteBatchCommand(attachDataPRORemoteBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); log.WriteEntry(output); //Copy the ISO.mdf file to remote server log.WriteEntry(Settings.Default.CopyingISOToRemote); SetMigrationStatus(Settings.Default.CopyingISOToRemote); sourceFile = Path.Combine(_targetDbDir, Settings.Default.ISO) + Settings.Default.Mdf; destFile = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + Settings.Default.ISO + Settings.Default.Mdf; File.Copy(sourceFile, destFile, true); log.WriteEntry(Settings.Default.DeletingRemoteISOLog); SetMigrationStatus(Settings.Default.DeletingRemoteISOLog); deleteFileName = "\\\\" + tbDBHostname.Text + "\\C$\\" + Settings.Default.DataPROSQLFolder + "\\" + Settings.Default.ISO + Settings.Default.LogLdf; File.Delete(deleteFileName); //Attach ISO database on remote server log.WriteEntry(Settings.Default.AttachingRemoteISODb); SetMigrationStatus(Settings.Default.AttachingRemoteISODb); var attachISORemoteBatchFile = Path.Combine(_scriptsDir, Settings.Default.AttachISORemotebat); output = RunRemoteBatchCommand(attachISORemoteBatchFile, tbDBHostname.Text, _majorMinorVersion, tbDBName.Text.Trim(), fullSqlcmdPath); log.WriteEntry(output); } private void MigrateFromTemporaryLocalDatabase() { try { if (!_standAlone && tbDBName.Text.Trim().ToUpper() != Settings.Default.DataPRO.ToUpper()) { //Copy DataPRO database as the actual name log.WriteEntry(string.Format(Settings.Default.CopyingDataPRODb, tbDBName.Text.Trim())); SetMigrationStatus(string.Format(Settings.Default.CopyingDataPRODb, tbDBName.Text.Trim())); //Copy the DataPRO.mdf/.ldf pair as the database name var sourceFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Mdf); var destFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Mdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(string.Format(Settings.Default.WasCopied, sourceFileName, destFileName)); sourceFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.LogLdf); destFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.LogLdf); File.Copy(sourceFileName, destFileName, true); log.WriteEntry(string.Format(Settings.Default.WasCopied, sourceFileName, destFileName)); } //Attach blank database log.WriteEntry(Settings.Default.AttachingBlankDb); SetMigrationStatus(Settings.Default.AttachingBlankDb); //Attach the DataPRO database var dbFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim()) + Settings.Default.Mdf; var logFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim()) + Settings.Default.LogLdf; var resultString = CommonUtilities.AttachOrDetachDatabase(_scriptsDir, tbDBName.Text, dbFileName, logFileName, Settings.Default.AttachDBsbat); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } else { log.WriteEntry(string.Format(Settings.Default.MigratingTempLocalDb, LAST_110_DB_VERSION, DbOperations.CURRENT_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingTempLocalDb, LAST_110_DB_VERSION, DbOperations.CURRENT_DB_VERSION)); DbOperations.Connection.ResetLocalConnectionStringDb(tbDBName.Text.Trim()); MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(DbOperations.CURRENT_DB_VERSION, SetStatus, tbDBName.Text.Trim(), previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); //handle exceptions and display error if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } //Detach the DataPROPre20 database log.WriteEntry(Settings.Default.DetachingTempLocalDb); SetMigrationStatus(Settings.Default.DetachingTempLocalDb); dbFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Pre20) + Settings.Default.Mdf; logFileName = Path.Combine(_targetDbDir, tbDBName.Text.Trim() + Settings.Default.Pre20) + Settings.Default.LogLdf; resultString = CommonUtilities.AttachOrDetachDatabase(_scriptsDir, tbDBName.Text.Trim() + Settings.Default.Pre20, dbFileName, logFileName, Settings.Default.DetachDBsbat); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly); } } } catch (Exception ex) { log.WriteEntry("Local database migration error occurred: " + ex.Message); throw; } } private void MigrateFromTemporaryCentralizedDatabase(string dbName) { log.WriteEntry(string.Format(Settings.Default.MigratingTempCentralizedDb, LAST_110_DB_VERSION, DbOperations.CURRENT_DB_VERSION)); SetMigrationStatus(string.Format(Settings.Default.MigratingTempCentralizedDb, LAST_110_DB_VERSION, DbOperations.CURRENT_DB_VERSION)); try { DbOperations.Connection.ResetLocalConnectionStringDb(tbDBName.Text.Trim()); MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(DbOperations.CURRENT_DB_VERSION, SetStatus, dbName, previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); //handle exceptions and display error if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } } catch (Exception ex) { log.WriteEntry("Centralized database migration error occurred: " + ex.Message); throw; } } private void btnOK_Click(object sender, EventArgs e) { log.WriteEntry("OK clicked"); btnOK.Enabled = false; EnableControls(false); DoDbTypeWork(); } private void DoDbTypeWork() { _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += worker_DoWork; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; log.WriteEntry("Running worker async"); _worker.RunWorkerAsync(); } private void MigrateDatabaseUpToLast14DbVersion(int previousDbVersion) { try { DbOperations.Connection.DbVersion = previousDbVersion; DbOperations.Connection.Server = rbLocal.Checked ? Settings.Default.LocalDbDataPROInstance : tbDBHostname.Text; DbOperations._usingNTLMAuthentication = cbUseNTLMAuthentication.Checked; DbOperations.Connection.DBName = tbDBName.Text; DbOperations.Connection.Username = tbDBUser.Text; DbOperations.Connection.Password = tbDBPassword.Text; DbOperations._usingMSSQL = !rbLocal.Checked; DbOperations._previousDir = previousDir; MigrationResult result = DbOperations.Connection.UpgradeVersionsIfNeeded(LAST_14_DB_VERSION, SetStatus, tbDBName.Text.Trim(), previousDir, _targetDir, Settings.Default.RegistryDataPROExe, Settings.Default.ApplicationSettings); if (result != MigrationResult.OK) { ConvertResultAndDisplay(result); } } catch (DbOperations.NoDBAccessException) { } catch (Exception) { } } public class MigrationStatusClass { public enum StatusTypes { Status, MigrationStatus, SourceDb }; public StatusTypes StatusType { get; set; } public string StatusText { get; set; } } private void SetMigrationStatus(string migrationStatus, bool output = false) { var commonUtilities = new CommonUtilities(); var migrationStatusClass = commonUtilities.SetMigrationStatus(migrationStatus, output); //Remove the previous status SetStatus(string.Empty); _worker.ReportProgress(0, migrationStatusClass); } private void SetStatus(string status, bool output = false) { var commonUtilities = new CommonUtilities(); var migrationStatusClass = commonUtilities.SetMigrationStatus(status, output); _worker.ReportProgress(0, migrationStatusClass); } private int GetPreviousDatabaseVersion(bool usingLocalDatabase) { int oldVersion = 0; string dbName; //30701 Migration fails when db not named "DataPRO". var dbNameWithExtension = string.Empty; if (_standAlone && rbLocal.Checked) { var sourceDbSplit = tbSourceDB.Text.Split('\\'); dbNameWithExtension = sourceDbSplit[sourceDbSplit.Length - 1]; var dbNameSplit = dbNameWithExtension.Split('.'); dbName = dbNameSplit[0].Trim(); previousDir = tbSourceDB.Text.Remove(tbSourceDB.Text.LastIndexOf(dbNameWithExtension)); } else { dbName = tbDBName.Text.Trim(); } try { log.WriteEntry("Trying in GetPreviousDatabaseVersion"); //Reset in case there was already a different (Local or Centralized) query run, for example in the Both case DbOperations.Connection.ResetLocalConnectionStringDb(dbName); if (usingLocalDatabase) { log.WriteEntry("Using local database"); if (localSQLLocalDbDataExists) { log.WriteEntry("Local SQLLocalDb database exists"); DbOperations.Connection.ResetLocalConnectionStringDb(dbName); var commonUtilities = new CommonUtilities(); if (_standAlone) { commonUtilities.InstallDatabase(previousDir, dbName, _scriptsDir); } else { commonUtilities.InstallDatabase(Path.Combine(previousDir, "db"), dbName, _scriptsDir); } } else if (localSQLiteDataExists) { log.WriteEntry("Local SQLite database exists in previous install"); if (_standAlone) { var sourceDbSplit = tbSourceDB.Text.Split('\\'); dbNameWithExtension = sourceDbSplit[sourceDbSplit.Length - 1]; previousDir = tbSourceDB.Text.Remove(tbSourceDB.Text.LastIndexOf(dbNameWithExtension)); } DbOperations._usingMSSQL = false; oldVersion = UsePreviousDatabaseStructure(true, dbNameWithExtension); return oldVersion; } else { log.WriteEntry("No local database exists in previous install"); } } else { log.WriteEntry("Using centralized database"); DbOperations._usingMSSQL = true; DbOperations.Connection.Server = tbDBHostname.Text; DbOperations._usingNTLMAuthentication = cbUseNTLMAuthentication.Checked; DbOperations.Connection.Username = tbDBUser.Text; DbOperations.Connection.Password = tbDBPassword.Text; } //First try the most recent database structure using (var cmd = DbOperations.GetSQLCommand(true)) { try { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandText = DbOperationsEnum.StoredProcedure.sp_DbVersionGet.ToString(); cmd.Parameters.Add(new SqlParameter("@Version", SqlDbType.Int) { Value = null }); var reader = cmd.ExecuteReader(); var dbVersionsList = new List(); while (reader.Read()) { var version = Convert.ToInt32(reader[DbOperations.DbVersions.DbVersionFields.Version.ToString()]); dbVersionsList.Add(version); } reader.Close(); oldVersion = dbVersionsList.Max(); log.WriteEntry("Result of using stored procedure sp_DbVersionGet is " + oldVersion); if (oldVersion > 0) { return oldVersion; } } finally { cmd.Connection.Dispose(); } } } catch (Exception ex) { log.WriteEntry("Exception while getting previous database version: " + ex.Message + "; Stacktrace: " + ex.StackTrace); if (ex.Message != "Could not find stored procedure 'sp_DbVersionGet'.") { //We don't want to re-throw the exception that we get if we're migrating a 1.4 database. throw; } } return UsePreviousDatabaseStructure(usingLocalDatabase, dbNameWithExtension); } private int UsePreviousDatabaseStructure(bool usingLocalDatabase, string dbName) { var oldVersion = 0; try { if (usingLocalDatabase) { //If needed, use the previous database structure using (var sql = DbOperations.GetSQLiteCommand()) { try { sql.CommandText = "SELECT MAX(Version) from [tblDataPRODbVersion]"; using (var ds = DbOperations.Connection.QueryDataSet(sql, previousDir, _standAlone, dbName)) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { oldVersion = Convert.ToInt32(ds.Tables[0].Rows[0].ItemArray[0]); log.WriteEntry(string.Format(Settings.Default.ResultOnLocal, oldVersion)); } } } finally { sql.Connection.Dispose(); } } } else { using (var cmd = DbOperations.GetSQLCommand(true)) //We don't want the CommandType of StoredProcedure to be carried over { try { cmd.CommandText = string.Format("select * from {0} order by {1} desc", DbOperations.VersionTable.TableName, DbOperations.VersionTable.Fields.Version.ToString()); using (var ds = DbOperations.Connection.QueryDataSet(cmd)) { if (ds.Tables[0].Rows.Count > 0) { oldVersion = Convert.ToInt32(ds.Tables[0].Rows[0][DbOperations.VersionTable.Fields.Version.ToString()]); log.WriteEntry(string.Format(Settings.Default.ResultOnCentralServer, oldVersion)); } } } finally { cmd.Connection.Dispose(); } } } } catch (Exception ex) { log.WriteEntry(string.Format(Settings.Default.ExceptionWhileUsingPrevDbStructure, ex.Message)); if (ex.InnerException != null && ex.InnerException.Message == Settings.Default.NetworkPathNotFound) { throw; } } return oldVersion; } private static string RunRemoteBatchCommand(string batchFileName, string serverName, string majorMinorVersion, string dbName, string fullSqlcmdPath) { return RemoteBatchCommandProcessor(batchFileName, serverName, majorMinorVersion, dbName, fullSqlcmdPath); } public static string RemoteBatchCommandProcessor(string batchFileName, string serverName, string majorMinorVersion, string dbName, string fullSqlcmdPath) { CommonUtilities.sb.Clear(); var process = new Process { StartInfo = { FileName = batchFileName, Arguments = serverName + " " + majorMinorVersion + " " + dbName + " " + "\"" + fullSqlcmdPath + "\"", LoadUserProfile = true, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true } }; //* Set ONLY ONE handler here. process.OutputDataReceived += new DataReceivedEventHandler(CommonUtilities.OutputHandler); //* Start process process.Start(); //* Read one element asynchronously process.BeginErrorReadLine(); //* Read the other one synchronously var output = process.StandardOutput.ReadToEnd(); Console.WriteLine(output); process.WaitForExit(); return output; } /// /// Builds the path to the database and database log files and calls CopyDatabaseFile for each. /// private bool CopyLocalDB(string dbName, bool createBackup) { var dbFileName = Path.Combine(_targetDbDir, dbName + Settings.Default.Mdf); var dbFileLogName = Path.Combine(_targetDbDir, dbName + Settings.Default.LogLdf); //Copy DataPRO database file //Copy .mdf file if (!CopyDatabaseFile(_sourceDbDir, _sourceDbName, Settings.Default.Mdf, dbFileName, createBackup)) return false; //Copy .ldf file if (!CopyDatabaseFile(_sourceDbDir, _sourceDbName, Settings.Default.LogLdf, dbFileLogName, createBackup)) return false; if (!_standAlone) { return true; } //Copy ISO file dbFileName = Path.Combine(_targetDbDir, Settings.Default.ISO + Settings.Default.Mdf); dbFileLogName = Path.Combine(_targetDbDir, Settings.Default.ISO + Settings.Default.LogLdf); //Copy .mdf file if (!CopyDatabaseFile(Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder), Settings.Default.ISO, Settings.Default.Mdf, dbFileName, createBackup)) return false; //Copy .ldf file if (CopyDatabaseFile(Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder), Settings.Default.ISO, Settings.Default.LogLdf, dbFileLogName, createBackup)) return true; return false; } private bool CopyDatabaseFile(string sourceDbDir, string dbName, string extension, string destFileName, bool createBackup) { //The database file that is to be copied may have been attached to (localdb)\DataPROInstance, so detach it so it can be copied var commonUtilities = new CommonUtilities(); var resultString = commonUtilities.ProcessSqlLocalDbCommand(Settings.Default.StopDataProInstance); if (resultString.Length != 0) { MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK); } var sourceFileName = Path.Combine(sourceDbDir, dbName + extension); if (File.Exists(destFileName) && createBackup) { //Back it up var _testIDTimestamp = string.Format("{0:0000}_{1:00}_{2:00} {3:00}_{4:00}", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, DateTime.Now.Minute); var temp = destFileName.Replace(extension, "_" + _testIDTimestamp + extension); File.Copy(destFileName, temp, true); //Don't worry about overwriting a db with this timestamp } try { if (sourceFileName != destFileName) { File.Copy(sourceFileName, destFileName, true); log.WriteEntry(sourceFileName + " was copied as " + destFileName); } } catch (Exception ex) { MessageBox.Show(Settings.Default.PreviousDatabaseNotCopied + ex.Message); return false; } return true; } private bool ChangesWereMade() { if (rbLocal.Checked) { //Only consider enabled controls return (_originalRbDbType != DbType.Local) || (_originalTbDBName != tbDBName.Text); } else if (rbCentralized.Checked) { if (cbUseNTLMAuthentication.Checked) { //Only consider enabled controls return (_originalCbUseNTLMAuthentication != cbUseNTLMAuthentication.Checked) || (_originalTbDBHostname != tbDBHostname.Text) || (_originalTbDBName != tbDBName.Text); } else { //Only consider enabled controls return (_originalRbDbType != DbType.Centralized) || (_originalTbDBHostname != tbDBHostname.Text) || (_originalTbDBName != tbDBName.Text) || (_originalCbUseNTLMAuthentication != cbUseNTLMAuthentication.Checked) || (_originalTbDBUser != tbDBUser.Text) || (_originalTbDBPassword != tbDBPassword.Text); } } else //Must be rbBoth.Checked { if (cbUseNTLMAuthentication.Checked) { //Only consider enabled controls return (_originalCbUseNTLMAuthentication != cbUseNTLMAuthentication.Checked) || (_originalTbDBHostname != tbDBHostname.Text) || (_originalTbDBName != tbDBName.Text); } else { //Only consider enabled controls return (_originalRbDbType != DbType.Both) || (_originalTbDBHostname != tbDBHostname.Text) || (_originalTbDBName != tbDBName.Text) || (_originalCbUseNTLMAuthentication != cbUseNTLMAuthentication.Checked) || (_originalTbDBUser != tbDBUser.Text) || (_originalTbDBPassword != tbDBPassword.Text); } } } private void SaveChanges() { GetNewConfig(); var settingsToBeChanged = new SettingElementCollection(); foreach (SettingElement newSetting in _newSettings) { switch (newSetting.Name) { case "DBType": if (rbLocal.Checked && (_originalRbDbType != DbType.Local)) { //Add to the list of settings that need to be saved _newSettingsDictionary[newSetting.Name] = ((int)DbType.Local).ToString(); settingsToBeChanged.Add(newSetting); } else if (rbCentralized.Checked && (_originalRbDbType != DbType.Centralized)) { //Add to the list of settings that need to be saved _newSettingsDictionary[newSetting.Name] = ((int)DbType.Centralized).ToString(); settingsToBeChanged.Add(newSetting); } else if (rbBoth.Checked && (_originalRbDbType != DbType.Both)) { //Add to the list of settings that need to be saved _newSettingsDictionary[newSetting.Name] = ((int)DbType.Both).ToString(); settingsToBeChanged.Add(newSetting); } break; case "LocalDbHost": if (!rbLocal.Checked && (tbDBHostname.Text != _originalTbDBHostname)) { //Add to the list of settings that need to be saved //Only save enabled settings _newSettingsDictionary[newSetting.Name] = tbDBHostname.Text; settingsToBeChanged.Add(newSetting); } break; case "DBName": if (tbDBName.Text != _originalTbDBName) { //Add to the list of settings that need to be saved //Only save enabled settings _newSettingsDictionary[newSetting.Name] = tbDBName.Text; settingsToBeChanged.Add(newSetting); } break; case "UseNTLMAuthentication": //Manuscript 16521 //This setting is a little more complex because it changes when switching from Local (checked) //to Centralized (unchecked), but doesn't change _originalCbUseNTLMAuthentication when that happens. //Then, when manually checked after changing to Centralized, the following comparison will //return false, the "Checked" value will not be saved, and when DataPRO is run, //UseNTLMAuthentication will be false (incorrectly). //So, always set it to it's current value here, and sacrifice a little bit of performance. //Add to the list of settings that need to be saved //Only save enabled settings _newSettingsDictionary[newSetting.Name] = cbUseNTLMAuthentication.Checked.ToString(); settingsToBeChanged.Add(newSetting); break; case "LocalDBUser": if (!rbLocal.Checked && !cbUseNTLMAuthentication.Checked && (tbDBUser.Text != _originalTbDBUser)) { //Add to the list of settings that need to be saved //Only save enabled settings _newSettingsDictionary[newSetting.Name] = tbDBUser.Text; settingsToBeChanged.Add(newSetting); } break; case "LocalDBPassword": if (!rbLocal.Checked && !cbUseNTLMAuthentication.Checked && (tbDBPassword.Text != _originalTbDBPassword)) { //Add to the list of settings that need to be saved //Only save enabled settings _newSettingsDictionary[newSetting.Name] = tbDBPassword.Text; settingsToBeChanged.Add(newSetting); } break; } } foreach (SettingElement settingToBeChanged in settingsToBeChanged) { //Save the changed value(s) _newSettings.Remove(settingToBeChanged); settingToBeChanged.Value.ValueXml.InnerXml = _newSettingsDictionary[settingToBeChanged.Name]; _newSettings.Add(settingToBeChanged); } if (_newConfig != null) _newConfig.Save(); } private void DBTypeChoice_Load(object sender, EventArgs e) { try { if (!EventLog.SourceExists("DataPRODbMigratorInstaller")) { EventLog.CreateEventSource("DataPRODbMigratorInstaller", "DataPRODbMigratorInstallerLog"); } } catch { } log.Source = "DataPRODbMigratorInstaller"; log.WriteEntry("Starting Db Migrator"); try { if (!_standAlone) { log.WriteEntry("Getting new config"); GetNewConfig(); //30701 Migration fails when db not named "DataPRO". log.WriteEntry("Getting previous directory"); previousDir = GetPreviousDir(); log.WriteEntry("Getting old config"); GetOldConfig(); tbDBName.Text = _oldSettingsDictionary[ConfigSettings.DBName.ToString()]; var prevDbVersion = 0; try { prevDbVersion = GetPreviousDatabaseVersion(true); } catch (Exception ex) { log.WriteEntry($"Exception when getting PreviousDatabaseVersion: {ex.Message}"); } if (prevDbVersion > 0) { _currentSettingsDictionary = _oldSettingsDictionary; } else { _currentSettingsDictionary = _newSettingsDictionary; } } } catch (Exception ex) { //Just accept the fact that the config may not be in the target directory, for //example, when doing a stand-alone db migration in a random folder. //If so, _newSettingsDictionary will not be usable, so try/catch all access to it. log.WriteEntry($"Exception when getting new config: {ex.Message}"); } //Do this before the radio button stuff below, since that interacts with this if (!_cmdLine) { try { log.WriteEntry("Getting LocalDbHost from config"); _originalTbDBHostname = _currentSettingsDictionary[ConfigSettings.LocalDbHost.ToString()]; } catch (Exception ex) { log.WriteEntry($"Exception when getting LocalDbHost from config: {ex.Message}"); _originalTbDBHostname = string.Empty; } tbDBHostname.Text = _originalTbDBHostname.Trim(); tbDbHostnameSaved = _originalTbDBHostname.Trim(); try { log.WriteEntry("Getting DBType from config"); if (Enum.TryParse(_currentSettingsDictionary[ConfigSettings.DBType.ToString()], out DbType intDbType)) { _originalRbDbType = intDbType; switch (intDbType) { case DbType.Local: rbLocal.Checked = true; break; case DbType.Centralized: rbCentralized.Checked = true; EnableRadioButtons(false); break; case DbType.Both: rbBoth.Checked = true; break; } } else { rbLocal.Checked = true; _originalRbDbType = DbType.Local; } } catch (Exception ex) { log.WriteEntry($"Exception when getting DBType from config: {ex.Message}"); rbLocal.Checked = true; _originalRbDbType = DbType.Local; } } else { rbLocal.Checked = true; } if (!_cmdLine) { try { log.WriteEntry("Getting DBName from config"); _originalTbDBName = _currentSettingsDictionary[ConfigSettings.DBName.ToString()]; if (_originalTbDBName.ToUpper() != Settings.Default.DataPRO.ToUpper()) { //Database name in the previous version is not the default (DataPRO.mdf) //so change it to what is in the config file, even if not migrating data. //First the .mdf var oldFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.Mdf); var newFileName = Path.Combine(_targetDbDir, _originalTbDBName + Settings.Default.Mdf); File.Move(oldFileName, newFileName); //Then the .ldf oldFileName = Path.Combine(_targetDbDir, Settings.Default.DataPRO + Settings.Default.LogLdf); newFileName = Path.Combine(_targetDbDir, _originalTbDBName + Settings.Default.LogLdf); File.Move(oldFileName, newFileName); } } catch (Exception ex) { log.WriteEntry($"Exception when getting DBName from config: {ex.Message}"); _originalTbDBName = Settings.Default.DataPRO; } } else { _originalTbDBName = Settings.Default.DataPRO; } if (!_cmdLine) { tbDBName.Text = _originalTbDBName.Trim(); _sourceDbName = tbDBName.Text.Trim(); } else { var sourceFile = tbSourceDB.Text; var destFile = Path.Combine(tbDestinationDB.Text, $"{_originalTbDBName}{Settings.Default.Mdf}"); if (sourceFile == destFile) { SetMigrationStatus(""); SetStatus(Settings.Default.SourceDbSameAsDestination, true); StopCommandLine(); return; } else { log.WriteEntry("Calling LocalDataExists"); localDataExists = LocalDataExists(); //Update this flag in case rbLocal is checked later log.WriteEntry("Back from calling LocalDataExists"); SetMigrationStatus(""); if (localDataExists) { log.WriteEntry("LocalDataExists is true"); GetOldConfig(); _currentSettingsDictionary = _oldSettingsDictionary; CheckRadioButton(rbMigrateLocal, rbMigrateLocalSaved); CheckRadioButton(rbAero, rbAeroSaved); CheckRadioButton(rbCrash, rbCrashSaved); CheckRadioButton(rbTSRAIR, rbTSRAIRSaved); CheckRadioButton(rbNoneOfTheAbove, rbNoneOfTheAboveSaved); EnableRadioButtons(true); if (!ValidateForMigration(true)) { StopCommandLine(); return; } SetStatus(""); } else { log.WriteEntry("LocalDataExists is false"); SetStatus(Settings.Default.InvalidSourceDb, true); StopCommandLine(); return; } } _sourceDbName = Settings.Default.DataPRO; } if (string.IsNullOrWhiteSpace(tbDBName.Text)) { btnOK.Enabled = false; } localDataExists = LocalDataExists(); destFolderExists = DestFolderExists(); try { if (!_cmdLine) { log.WriteEntry("Outer try before getting UseNTLMAuthentication from config"); try { log.WriteEntry("Getting UseNTLMAuthentication from config"); cbUseCentralizedNTLMAuthenticationSaved = bool.TryParse(_currentSettingsDictionary[ConfigSettings.UseNTLMAuthentication.ToString()], out bool useNTLMAuthentication) && useNTLMAuthentication; } catch (Exception ex) { log.WriteEntry($"Exception when getting UseNTLMAuthentication from config: {ex.Message}"); cbUseCentralizedNTLMAuthenticationSaved = false; } } if (rbLocal.Checked) { cbUseNTLMAuthentication.Checked = true; CheckRadioButton(rbMigrateLocal, localDataExists || _standAlone); rbMigrateLocal.Enabled = localDataExists || _standAlone; rbNoneOfTheAbove.Checked = !rbMigrateLocal.Enabled; if (_standAlone) { rbNoneOfTheAbove.Visible = false; } else { rbNoneOfTheAbove.Enabled = true; } } else if (rbCentralized.Checked) { cbUseNTLMAuthentication.Checked = cbUseCentralizedNTLMAuthenticationSaved; } else if (rbBoth.Checked) { cbUseNTLMAuthentication.Checked = cbUseCentralizedNTLMAuthenticationSaved; CheckRadioButton(rbMigrateLocal, localDataExists || _standAlone); EnableRadioButtons(localDataExists || _standAlone); if (_standAlone) { rbNoneOfTheAbove.Visible = false; } } } catch (Exception ex) { log.WriteEntry($"Exception from outer try before getting UseNTLMAuthentication from config: {ex.Message}"); cbUseNTLMAuthentication.Checked = false; cbUseCentralizedNTLMAuthenticationSaved = false; } _originalCbUseNTLMAuthentication = cbUseNTLMAuthentication.Checked; if (!_cmdLine) { try { log.WriteEntry("Getting LocalDBUser from config"); _originalTbDBUser = _currentSettingsDictionary[ConfigSettings.LocalDBUser.ToString()]; } catch (Exception ex) { log.WriteEntry($"Exception when getting LocalDBUser from config: {ex.Message}"); _originalTbDBUser = string.Empty; } try { log.WriteEntry("Getting LocalDBPassword from config"); _originalTbDBPassword = _currentSettingsDictionary[ConfigSettings.LocalDBPassword.ToString()]; } catch (Exception ex) { log.WriteEntry($"Exception when getting LocalDBPassword from config: {ex.Message}"); _originalTbDBPassword = string.Empty; } } tbDBPassword.UseSystemPasswordChar = true; if (_cmdLine) { //Migrate button click _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += worker_DoWork; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; log.WriteEntry("Running worker async"); _worker.RunWorkerAsync(); } } private void GetNewConfig() { var newPath = string.Empty; //Open the new config file just installed newPath = Path.Combine(_targetDir, Settings.Default.RegistryDataPROExe); _newConfig = ConfigurationManager.OpenExeConfiguration(@newPath); _newSettings = GetConfigApplicationSettings(_newConfig); _newSettingsDictionary = _newSettings.Cast().ToDictionary(newSetting => newSetting.Name, newSetting => newSetting.Value.ValueXml.InnerXml); } private void GetOldConfig() { var oldPath = string.Empty; //Open the config file from whence we came oldPath = Path.Combine(previousDir, Settings.Default.RegistryDataPROExe); _oldConfig = ConfigurationManager.OpenExeConfiguration(@oldPath); _oldSettings = GetConfigApplicationSettings(_oldConfig); _oldSettingsDictionary = _oldSettings.Cast().ToDictionary(oldSetting => oldSetting.Name, oldSetting => oldSetting.Value.ValueXml.InnerXml); } private void StopCommandLine() { //Don't do any work, but go away gracefully _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += (object sender, DoWorkEventArgs e) => { }; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; log.WriteEntry("Running worker async"); _worker.RunWorkerAsync(); } private SettingElementCollection GetConfigApplicationSettings(Configuration config) { var configurationSectionGroup = config.SectionGroups[Settings.Default.ApplicationSettings]; if (configurationSectionGroup == null) return null; return configurationSectionGroup.Sections[0] is ClientSettingsSection clientSettingsSection ? clientSettingsSection.Settings : null; } private void cbShowPassword_CheckedChanged(object sender, EventArgs e) { tbDBPassword.UseSystemPasswordChar = !cbShowPassword.Checked; } private bool ValidateForMigration(bool output = false) { if (rbLocal.Checked) { return LocalIsValid(output); } if (rbCentralized.Checked) { return CentralizedIsValid(); } if (rbBoth.Checked) { return LocalIsValid() && CentralizedIsValid(); } return false; } private bool LocalIsValid(bool output = false) { if (!_standAlone) return true; btnOK.Enabled = false; //Don't allow a click while querying the version of the source db or if returning false EnableControls(false); SetMigrationStatus(Settings.Default.QueryingPrevLocalDbVersion); SetStatus(""); log.WriteEntry("Getting previous database version"); oldDatabaseVersion = GetPreviousDatabaseVersion(true); log.WriteEntry("Back from getting previous database version"); SetMigrationStatus(""); if (rbMigrateLocal.Checked) { if (oldDatabaseVersion > 0) { lblSourceDB.Text = string.Format(Settings.Default.LocalSourceDbToBeMigratedVersion, oldDatabaseVersion); } } else { if (oldDatabaseVersion != DbOperations.CURRENT_DB_VERSION) { SetStatus(Settings.Default.InvalidSourceDbVersion, output); EnableControls(true); EnableDestControls(false); return false; } } SetMigrationStatus(""); EnableControls(true); if (rbAero.Checked || rbCrash.Checked || rbTSRAIR.Checked) { _targetDbDir = _sourceDbDir; } else { if (!Directory.Exists(tbDestinationDB.Text)) { SetStatus(Settings.Default.InvalidDestinationDb, output); return false; } var sourceFile = tbSourceDB.Text; var destFile = Path.Combine(tbDestinationDB.Text, $"{tbDBName.Text}{Settings.Default.Mdf}"); if (sourceFile == destFile) { SetStatus(Settings.Default.SourceDbSameAsDestination, output); return false; } } if (oldDatabaseVersion > 0) { if (rbMigrateLocal.Checked) { if (oldDatabaseVersion < DbOperations.CURRENT_DB_VERSION) return true; SetStatus(oldDatabaseVersion == DbOperations.CURRENT_DB_VERSION ? Settings.Default.DbVersionsAreTheSame : Settings.Default.SourceDbVersionCannotBeGreaterThanDestination); return false; } else { if (oldDatabaseVersion == DbOperations.CURRENT_DB_VERSION) return true; } } SetStatus(Settings.Default.InvalidSourceDbVersion, output); return false; } private bool CentralizedIsValid() { return !string.IsNullOrWhiteSpace(tbDBHostname.Text) && !string.IsNullOrWhiteSpace(tbDBName.Text) && (cbUseNTLMAuthentication.Checked || !string.IsNullOrWhiteSpace(tbDBPassword.Text) && !string.IsNullOrWhiteSpace(tbDBUser.Text)); } private void tbDBName_TextChanged(object sender, EventArgs e) { if (!_standAlone) { btnOK.Enabled = !string.IsNullOrWhiteSpace(tbDBName.Text); localDataExists = LocalDataExists(); //Update this flag in case rbLocal is checked later if (!rbLocal.Checked && !rbBoth.Checked) return; if (localDataExists) { CheckRadioButton(rbMigrateLocal, rbMigrateLocalSaved); CheckRadioButton(rbAero, rbAeroSaved); CheckRadioButton(rbCrash, rbCrashSaved); CheckRadioButton(rbTSRAIR, rbTSRAIRSaved); CheckRadioButton(rbNoneOfTheAbove, rbNoneOfTheAboveSaved); EnableRadioButtons(true); } else { rbMigrateLocalSaved = rbMigrateLocal.Checked; rbAeroSaved = rbAero.Checked; rbCrashSaved = rbCrash.Checked; rbTSRAIRSaved = rbTSRAIR.Checked; rbNoneOfTheAboveSaved = rbNoneOfTheAbove.Checked; DisableAndUncheckNonInitializationRadioButtons(); } } else { var sourceFile = tbSourceDB.Text; var destFile = Path.Combine(tbDestinationDB.Text, $"{tbDBName.Text}{Settings.Default.Mdf}"); if (sourceFile == destFile) { SetMigrationStatus(""); SetStatus(Settings.Default.SourceDbSameAsDestination); btnOK.Enabled = false; } else { localDataExists = LocalDataExists(); //Update this flag in case rbLocal is checked later SetMigrationStatus(""); if (rbLocal.Checked || rbBoth.Checked) { if (localDataExists) { CheckRadioButton(rbMigrateLocal, rbMigrateLocalSaved); CheckRadioButton(rbAero, rbAeroSaved); CheckRadioButton(rbCrash, rbCrashSaved); CheckRadioButton(rbTSRAIR, rbTSRAIRSaved); CheckRadioButton(rbNoneOfTheAbove, rbNoneOfTheAboveSaved); EnableRadioButtons(true); btnOK.Enabled = ValidateForMigration(); SetStatus(""); } else { rbMigrateLocalSaved = ModifyRadioButton(rbMigrateLocal, false); rbAeroSaved = ModifyRadioButton(rbAero, false); rbCrashSaved = ModifyRadioButton(rbCrash, false); rbTSRAIRSaved = ModifyRadioButton(rbTSRAIR, false); rbNoneOfTheAboveSaved = ModifyRadioButton(rbNoneOfTheAbove, false); btnOK.Enabled = false; SetStatus(Settings.Default.InvalidSourceDb); } } else { btnOK.Enabled = ValidateForMigration(); SetStatus(""); } } } } private void btnCancel_Click(object sender, EventArgs e) { if (MessageBox.Show(Settings.Default.ConfirmAbort, Settings.Default.ActionRequired, MessageBoxButtons.OKCancel, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly) != DialogResult.OK) return; done = true; cancelled = true; if (_worker.IsBusy) { _worker.CancelAsync(); } else { //Set the config to a blank local database (if it wasn't already) so this version can be used rbLocal.Checked = true; if (ChangesWereMade()) { SaveChanges(); } Close(); } } private void btnBrowseSourceDB_Click_1(object sender, EventArgs e) { using (var sourceDB = new OpenFileDialog()) { sourceDB.CheckFileExists = true; sourceDB.CheckPathExists = true; sourceDB.Filter = @"DataPRO database file (*.mdf)|*.mdf|DataPRO (old)|*.db|All Files (*.*)|*.*"; if (sourceDB.ShowDialog() != DialogResult.OK) return; tbSourceDB.Text = sourceDB.FileName; } } private void btnBrowseDestinationDB_Click_1(object sender, EventArgs e) { using (var destinationDBFolder = new FolderBrowserDialog()) { var result = destinationDBFolder.ShowDialog(); if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(destinationDBFolder.SelectedPath)) { tbDestinationDB.Text = destinationDBFolder.SelectedPath; } } } private void tbSourceDB_TextChanged_1(object sender, EventArgs e) { try { Cursor.Current = Cursors.WaitCursor; _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += worker_DoWork; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; if (string.IsNullOrWhiteSpace(tbSourceDB.Text)) { lblSourceDB.Text = Settings.Default.LocalSourceDbToBeMigrated; var migrationStatusClass = new MigrationStatus(); migrationStatusClass.StatusType = MigrationStatus.StatusTypes.SourceDb; _worker.ReportProgress(0, migrationStatusClass); SetMigrationStatus(""); SetStatus(Settings.Default.InvalidSourceDb); btnOK.Enabled = false; return; } var sourceDbSplit = tbSourceDB.Text.Split('\\'); _sourceDbNameWithExtension = sourceDbSplit[sourceDbSplit.Length - 1]; var dbNameSplit = _sourceDbNameWithExtension.Split('.'); _sourceDbName = dbNameSplit[0].Trim(); _sourceDbDir = tbSourceDB.Text.Remove(tbSourceDB.Text.LastIndexOf(_sourceDbNameWithExtension)); if (tbDestinationDB.Text.Trim() == Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder) && _sourceDbNameWithExtension == Settings.Default.DataPROBlankMdf) { lblSourceDB.Text = Settings.Default.LocalSourceDbToBeMigrated; var migrationStatusClass = new MigrationStatus(); migrationStatusClass.StatusType = MigrationStatus.StatusTypes.SourceDb; _worker.ReportProgress(0, migrationStatusClass); SetMigrationStatus(""); SetStatus(Settings.Default.BlankDestinationDb); btnOK.Enabled = false; return; } var sourceFile = tbSourceDB.Text; var destFile = Path.Combine(tbDestinationDB.Text, $"{_sourceDbNameWithExtension}"); btnOK.Enabled = sourceFile != destFile; SetMigrationStatus(""); if (sourceFile == destFile) { lblSourceDB.Text = Settings.Default.LocalSourceDbToBeMigrated; var migrationStatusClass = new MigrationStatus(); migrationStatusClass.StatusType = MigrationStatus.StatusTypes.SourceDb; _worker.ReportProgress(0, migrationStatusClass); SetStatus(Settings.Default.SourceDbSameAsDestination); btnOK.Enabled = false; } else { localDataExists = LocalDataExists(); //Update this flag in case rbLocal is checked later if (!rbLocal.Checked && !rbBoth.Checked) return; if (localDataExists) { CheckRadioButton(rbMigrateLocal, rbMigrateLocalSaved); CheckRadioButton(rbAero, rbAeroSaved); CheckRadioButton(rbCrash, rbCrashSaved); CheckRadioButton(rbTSRAIR, rbTSRAIRSaved); CheckRadioButton(rbNoneOfTheAbove, rbNoneOfTheAboveSaved); EnableRadioButtons(true); if (rbMigrateLocal.Checked) { lblSourceDB.Text = string.Format(Settings.Default.LocalSourceDbToBeMigratedVersion, "..."); } else { lblSourceDB.Text = Settings.Default.LocalSourceDbToBeInitialized; } var migrationStatusClass = new MigrationStatus(); migrationStatusClass.StatusType = MigrationStatus.StatusTypes.SourceDb; _worker.ReportProgress(0, migrationStatusClass); btnOK.Enabled = ValidateForMigration(); } else { rbMigrateLocalSaved = ModifyRadioButton(rbMigrateLocal, false); rbAeroSaved = ModifyRadioButton(rbAero, false); rbCrashSaved = ModifyRadioButton(rbCrash, false); rbTSRAIRSaved = ModifyRadioButton(rbTSRAIR, false); btnOK.Enabled = false; lblSourceDB.Text = Settings.Default.LocalSourceDbToBeMigrated; var migrationStatusClass = new MigrationStatus(); migrationStatusClass.StatusType = MigrationStatus.StatusTypes.SourceDb; _worker.ReportProgress(0, migrationStatusClass); SetStatus(Settings.Default.InvalidSourceDb); btnOK.Enabled = false; } } } finally { Cursor.Current = Cursors.Default; } } private void EnableRadioButtons(bool checkAndEnable) { rbMigrateLocal.Enabled = checkAndEnable; rbAero.Enabled = checkAndEnable; rbCrash.Enabled = checkAndEnable; rbTSRAIR.Enabled = checkAndEnable; rbNoneOfTheAbove.Enabled = checkAndEnable; } private void CheckRadioButton(RadioButton rb, bool check) { rb.Checked = check; } private void DisableAndUncheckNonInitializationRadioButtons() { ModifyRadioButton(rbMigrateLocal, false); ModifyRadioButton(rbNoneOfTheAbove, false); } private void DisableAndUncheckRadioButtons() { ModifyRadioButton(rbMigrateLocal, false); ModifyRadioButton(rbAero, false); ModifyRadioButton(rbCrash, false); ModifyRadioButton(rbTSRAIR, false); ModifyRadioButton(rbNoneOfTheAbove, false); } private bool ModifyRadioButton(RadioButton rb, bool checkAndEnable) { var rbSaved = rb.Checked; rb.Checked = checkAndEnable; rb.Enabled = checkAndEnable; return rbSaved; } private void tbDestinationDB_TextChanged_1(object sender, EventArgs e) { _worker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true }; _worker.ProgressChanged += worker_ProgressChanged; _worker.DoWork += worker_DoWork; _worker.RunWorkerCompleted += worker_RunWorkerCompleted; if (!Directory.Exists(tbDestinationDB.Text)) { SetMigrationStatus(Settings.Default.InvalidDestinationDb); btnOK.Enabled = false; return; } if (tbDestinationDB.Text == Environment.CurrentDirectory || tbDestinationDB.Text == Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder)) { SetMigrationStatus(Settings.Default.DestinationPathIsNotAllowed); btnOK.Enabled = false; return; } _targetDbDir = tbDestinationDB.Text; SetMigrationStatus(""); if (!string.IsNullOrWhiteSpace(tbSourceDB.Text.Trim())) { var sourceDbSplit = tbSourceDB.Text.Split('\\'); _sourceDbNameWithExtension = sourceDbSplit[sourceDbSplit.Length - 1]; var dbNameSplit = _sourceDbNameWithExtension.Split('.'); _sourceDbName = dbNameSplit[0].Trim(); _sourceDbDir = tbSourceDB.Text.Remove(tbSourceDB.Text.LastIndexOf(_sourceDbNameWithExtension)); if (tbDestinationDB.Text.Trim() == Path.Combine(Environment.CurrentDirectory, Settings.Default.LocalDbFolder) && _sourceDbNameWithExtension == Settings.Default.DataPROBlankMdf) { SetMigrationStatus(""); SetStatus(Settings.Default.BlankDestinationDb); btnOK.Enabled = false; return; } } var sourceFile = tbSourceDB.Text; var destFile = Path.Combine(tbDestinationDB.Text, $"{tbDBName.Text}{Settings.Default.Mdf}"); btnOK.Enabled = sourceFile != destFile; SetStatus(sourceFile == destFile ? Settings.Default.SourceDbSameAsDestination : ""); } private void rbMigrateLocal_CheckedChanged(object sender, EventArgs e) { if (!rbCentralized.Checked) { rbMigrateLocalSaved = rbMigrateLocal.Checked; } if (_standAlone && rbMigrateLocal.Checked) { lblSourceDB.Text = Settings.Default.LocalSourceDbToBeMigrated; btnOK.Text = Settings.Default.Migrate; } if (rbMigrateLocal.Checked) { //Just checked, so always copy config when migrating cbCopyConfig.Checked = true; cbCopyConfig.Enabled = false; } else { //Just unchecked, so give user the option to copy config cbCopyConfig.Enabled = true; } } private void rbAero_CheckedChanged(object sender, EventArgs e) { if (!rbCentralized.Checked) { rbAeroSaved = rbAero.Checked; } UpdateSourceDBControls(); } private void rbCrash_CheckedChanged(object sender, EventArgs e) { if (!rbCentralized.Checked) { rbCrashSaved = rbCrash.Checked; } UpdateSourceDBControls(); } private void rbTSRAIR_CheckedChanged(object sender, EventArgs e) { if (!rbCentralized.Checked) { rbTSRAIRSaved = rbTSRAIR.Checked; } UpdateSourceDBControls(); } private void rbNoneOfTheAbove_CheckedChanged(object sender, EventArgs e) { if (!rbCentralized.Checked) { rbNoneOfTheAboveSaved = rbNoneOfTheAbove.Checked; } UpdateSourceDBControls(); } private void UpdateSourceDBControls() { if (!rbMigrateLocal.Checked) { if (_standAlone) { lblSourceDB.Text = Settings.Default.LocalSourceDbToBeInitialized; btnOK.Text = Settings.Default.Initialize; } else { _sourceDbDir = Path.Combine(_targetDir, Settings.Default.LocalDbFolder); } } } private void tbDBHostname_TextChanged(object sender, EventArgs e) { btnOK.Enabled = CentralizedIsValid(); } private void tbDBUser_TextChanged(object sender, EventArgs e) { btnOK.Enabled = CentralizedIsValid(); } private void tbDBPassword_TextChanged(object sender, EventArgs e) { btnOK.Enabled = CentralizedIsValid(); } } }