Files
DP44/DataPRO/Modules/InstallerCustomActions/.svn/pristine/e1/e183030c0e387e6aab7623217203069ffda92fb3.svn-base

378 lines
18 KiB
Plaintext
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
using DTS.Common.Storage;
using DTS.Common.Enums;
using DBConfiguration.Properties;
using Microsoft.Win32;
using System.Diagnostics;
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Configuration;
namespace DBConfiguration
{
public class CommonUtilities
{
public CommonUtilities()
{
log.Source = "DataPRODbMigratorInstaller";
}
private readonly EventLog log = new EventLog();
public void InitializeDbToTSRAIR(string targetDir)
{
var targetDbDir = $"{targetDir}\\{Settings.Default.LocalDbFolder}";
var scriptsDir = Path.Combine(targetDir, Settings.Default.ScriptsFolder);
DbOperations.Connection.DBName = "DataPRO"; //This cannot be changed during TSR AIR Go installation
UpdateTSRAIRAppSettings(targetDir);
var resultString = Attach(targetDbDir, scriptsDir);
DbOperations.Connection.Initialize(InitializationTypes.TSRAIR, targetDir);
_ = Detach(DbOperations.Connection.DBName, targetDbDir, scriptsDir);
MessageBox.Show(Settings.Default.TSRAIRGoInstallationCompletedSuccessfully,
Settings.Default.InstallationStatus,
MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
private void UpdateTSRAIRAppSettings(string targetDir)
{
try
{
if (!GetNewSettings(Settings.Default.ApplicationSettings, targetDir, out var result, out var settings, out var config))
{
log.WriteEntry($"failed to updatetsrairappsetting {result}");
}
var setting = settings.Get("LaunchTSRAIRGo");
settings.Remove(setting);
setting.Value.ValueXml.InnerXml = "True";
settings.Add(setting);
config.Save(ConfigurationSaveMode.Full);
ConfigurationManager.RefreshSection("appSettings");
}
catch (Exception ex)
{
log.WriteEntry($"Failed to update tsr air app settings {ex.Message}");
//nothing to do right now
}
}
public bool GetNewSettings(string settingsType, string targetDir,
out string result, out SettingElementCollection newSettings, out Configuration newConfig)
{
result = string.Empty;
newSettings = null;
newConfig = null;
var newPath = string.Empty;
try
{
//Open the new config file just installed
newPath = Path.Combine(targetDir, Settings.Default.RegistryDataPROExe);
newConfig = ConfigurationManager.OpenExeConfiguration(@newPath);
}
catch (Exception ex)
{
result = string.Format(Settings.Default.NewSettingsCouldNotBeFound, ex.Message, newPath);
return false;
}
newSettings = GetConfigSettings(settingsType, newConfig);
if (newSettings != null) return true;
result = Settings.Default.NewSettingsCouldNotBeProcessed;
return false;
}
private static SettingElementCollection GetConfigSettings(string settingsType, Configuration config)
{
var clientSettingsSection = new ClientSettingsSection();
var configurationSectionGroup = config.SectionGroups[settingsType];
if ((configurationSectionGroup != null) && (configurationSectionGroup.Sections[0] != null))
{
clientSettingsSection = configurationSectionGroup.Sections[0] as ClientSettingsSection;
}
return clientSettingsSection?.Settings;
}
public string Attach(string targetDbDir, string scriptsDir)
{
log.WriteEntry(Settings.Default.AttachingPrevLocalDb);
SetMigrationStatus(Settings.Default.AttachingPrevLocalDb);
var resultString = InstallDatabase(targetDbDir, DbOperations.Connection.DBName, scriptsDir);
return resultString;
}
public string InstallDatabase(string dBdir, string dbName, string scriptsDir)
{
string resultString = "";
try
{
DbOperations._usingCentralizedDB = false;
DbOperations._usingMSSQL = true;
DbOperations.Connection.Server = Settings.Default.LocalDbDataPROInstance;
DbOperations._usingNTLMAuthentication = true;
resultString = ProcessSqlLocalDbCommand(Settings.Default.StopDataProInstance);
if (resultString.Length != 0)
{
MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
}
resultString = ProcessSqlLocalDbCommand(Settings.Default.DeleteDataProInstance);
if (resultString.Length != 0)
{
MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
}
resultString = ProcessSqlLocalDbCommand(Settings.Default.CreateDataProInstance);
if (resultString.Length != 0)
{
MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
}
resultString = ProcessSqlLocalDbCommand(Settings.Default.StartDataProInstance);
if (resultString.Length != 0)
{
MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
}
Console.WriteLine("Attaching DataPRO");
//Attach the DataPRO database
var dbFileName = Path.Combine(dBdir, dbName) + Settings.Default.Mdf;
var logFileName = Path.Combine(dBdir, dbName) + Settings.Default.LogLdf;
Console.WriteLine($"dbFileName is {dbFileName}");
Console.WriteLine($"logFileName is {logFileName}");
Console.WriteLine($"_scriptsDir is {scriptsDir}");
resultString = AttachOrDetachDatabase(scriptsDir, dbName, dbFileName, logFileName, Settings.Default.AttachDBsbat);
if (resultString.Length != 0)
{
MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
}
Console.WriteLine("Attaching ISO");
//Attach the ISO database
dbFileName = Path.Combine(dBdir, Settings.Default.ISO) + Settings.Default.Mdf;
logFileName = Path.Combine(dBdir, Settings.Default.ISO) + Settings.Default.LogLdf;
resultString = AttachOrDetachDatabase(scriptsDir, Settings.Default.ISO, dbFileName, logFileName, Settings.Default.AttachDBsbat);
if (resultString.Length != 0)
{
MessageBox.Show(resultString, Settings.Default.Warning, MessageBoxButtons.OK, MessageBoxIcon.Warning,
MessageBoxDefaultButton.Button2, MessageBoxOptions.DefaultDesktopOnly);
}
}
catch (Exception ex)
{
log.WriteEntry($"Exception while getting previous local database version: {ex.Message}; Stacktrace: {ex.StackTrace}");
throw;
}
return resultString;
}
public string Detach(string sourceDbName, string targetDbDir, string scriptsDir)
{
//Detach the databases
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);
var 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);
}
log.WriteEntry(Settings.Default.DetachingLocalISODb);
SetMigrationStatus(Settings.Default.DetachingLocalISODb);
dbFileName = Path.Combine(targetDbDir, Settings.Default.ISO + Settings.Default.Mdf);
logFileName = Path.Combine(targetDbDir, Settings.Default.ISO + Settings.Default.LogLdf);
resultString = CommonUtilities.AttachOrDetachDatabase(scriptsDir, Settings.Default.ISO, dbFileName, logFileName, Settings.Default.DetachDBsbat);
return resultString;
}
public MigrationStatus SetMigrationStatus(string migrationStatus, bool output = false)
{
//Remove the previous status
SetStatus(string.Empty);
var migrationStatusClass = new MigrationStatus();
migrationStatusClass.StatusType = MigrationStatus.StatusTypes.MigrationStatus;
migrationStatusClass.StatusText = migrationStatus;
if (output)
{
Console.WriteLine(migrationStatus);
}
return migrationStatusClass;
}
private void SetStatus(string status, bool output = false)
{
var migrationStatusClass = new MigrationStatus();
migrationStatusClass.StatusType = MigrationStatus.StatusTypes.Status;
migrationStatusClass.StatusText = status;
if (output)
{
Console.WriteLine(status);
}
}
/// <summary>
/// Get the path to the latest version of SQL Server Express LocalDB
/// installed, and run the command passed in.
/// </summary>
/// <param name="command"></param>
/// <returns></returns>
public string ProcessSqlLocalDbCommand(string command)
{
//SQL Server Express LocalDB 2014 is a Prerequisite of the DataPRO Installer,
//so it should be there unless it has been subsequently uninstalled.
var localDbPath = GetSqlServerLocalDBPath();
if (localDbPath == string.Empty)
{
log.WriteEntry($"localDbPath is empty");
//SQL Server LocalDb is not installed so display error and go away
return Settings.Default.SqlServerLocalDbNotInstalled;
}
var sqlLocalDbExeFileName = localDbPath + Settings.Default.SqlLocalDBExe;
log.WriteEntry($"sqlLocalDbExeFileName = {sqlLocalDbExeFileName}");
return SqlCommandProcessor(sqlLocalDbExeFileName, command);
}
public static string AttachOrDetachDatabase(string scriptsDir, string dbName, string sqlDbFileName, string sqlLogFileName, string attachOrDetach)
{
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 batchFileName = Path.Combine(scriptsDir, attachOrDetach);
return BatchCommandProcessor(batchFileName, dbName, sqlDbFileName, sqlLogFileName, fullSqlcmdPath);
}
private string GetSqlServerLocalDBPath()
{
var highestVersionInstalledPath = string.Empty;
var rk = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var sk1 = rk.OpenSubKey(Settings.Default.RegistrySoftwareMicrosoftMicrosoftSQLServerLocalDBInstalledVersions);
if (sk1 == null)
{
log.WriteEntry($"sk1 is null; returning string.Empty");
return string.Empty;
}
var maxProductVersion = 0.0;
foreach (var productSubKeyName in sk1.GetSubKeyNames())
{
log.WriteEntry($"productSubKeyName is {productSubKeyName}");
var thisVersion = -1D;
if (!double.TryParse(productSubKeyName,
System.Globalization.NumberStyles.Float | System.Globalization.NumberStyles.AllowThousands,
System.Globalization.CultureInfo.InvariantCulture,
out thisVersion)) continue;
log.WriteEntry($"thisVersion is {thisVersion}/maxProductVersion is {maxProductVersion}");
if (thisVersion < maxProductVersion) continue;
maxProductVersion = thisVersion;
var newKey = sk1.OpenSubKey(productSubKeyName);
if (newKey == null)
{
log.WriteEntry($"newKey is null (productSubKeyName is {productSubKeyName}); continuing");
continue;
}
var val = newKey.GetValue(Settings.Default.InstanceAPIPath, -1, RegistryValueOptions.None).ToString();
log.WriteEntry($"val is {val}");
if ((val == "-1") || (!val.EndsWith(Settings.Default.SqlUserInstanceDll))) continue;
log.WriteEntry($"highestVersionInstalledPath = {highestVersionInstalledPath}");
highestVersionInstalledPath = val.Substring(0, val.Length - Settings.Default.SqlUserInstanceDll.Length);
}
log.WriteEntry($"Returning {highestVersionInstalledPath.Replace(Settings.Default.LocalDB, Settings.Default.Tools)}");
return highestVersionInstalledPath.Replace(Settings.Default.LocalDB, Settings.Default.Tools);
}
public static StringBuilder sb = new StringBuilder();
public static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (outLine.Data != null)
{
if (string.IsNullOrWhiteSpace(outLine.Data))
{
sb.Append(Environment.NewLine);
}
sb.Append(outLine.Data);
}
}
public static string SqlCommandProcessor(string sqlLocalDbExeFileName, string command)
{
var resultString = string.Empty;
sb.Clear();
var process = new Process
{
StartInfo =
{
FileName = sqlLocalDbExeFileName,
Arguments = command,
LoadUserProfile = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
//* Set ONLY ONE handler here.
process.OutputDataReceived += new DataReceivedEventHandler(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();
if (sb.Length > 0)
{
resultString = sb.ToString();
}
return resultString;
}
public static string BatchCommandProcessor(string batchFileName, string dbName, string sqlDbFileName, string sqlLogFileName,
string fullSqlcmdPath)
{
var resultString = string.Empty;
sb.Clear();
var process = new Process
{
StartInfo =
{
FileName = batchFileName,
Arguments = dbName + " " + "\"" + sqlDbFileName + "\"" + " " + "\"" + sqlLogFileName + "\"" + " " + "\"" + fullSqlcmdPath + "\"",
LoadUserProfile = true,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true
}
};
//* Set ONLY ONE handler here.
process.OutputDataReceived += new DataReceivedEventHandler(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();
if (sb.Length > 0)
{
resultString = sb.ToString();
}
return resultString;
}
}
}