Files
DP44/DataPRO/Modules/InstallerCustomActions/.svn/pristine/62/62b98472c7c48140ad22808e9098d2c08f6d3a58.svn-base

437 lines
22 KiB
Plaintext
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
using System;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MigrateConfiguration.Resources;
using Installer.Common;
using System.IO;
using DTS.Common.Utilities;
namespace MigrateConfiguration
{
internal static class ConfigurationMigration
{
/// <summary>
/// Get the arguments from the MigrateConfiguration Installer Custom Action and migrates
/// the config values from the most-recently installed version of DataPRO (if any).
/// </summary>
/// <param name="args">
/// [TARGETDIR]
/// [ProductVersion]
/// </param>
private static void Main(string[] args)
{
var targetDir = string.Empty;
var productVersion = new Version();
var noUI = string.Empty;
string setupExeDir = string.Empty;
for (var i = 0; i < args.Length; i++)
{
switch (i)
{
case 0:
targetDir = args[i];
break;
case 1:
productVersion = new Version(args[i]);
break;
case 2:
noUI = args[i];
break;
case 3:
setupExeDir = args[i];
break;
}
}
try
{
if (!System.Diagnostics.EventLog.SourceExists("DataPROInstaller"))
{
System.Diagnostics.EventLog.CreateEventSource("DataPROInstaller", "DataPROInstallerLog");
}
}
catch
{
}
var result = string.Empty;
var allResults = new StringBuilder();
//try
//{
// //Set the DownloadFolder setting to the current default which may be different than an old default
// //before calling UpdateConfigurationIfPossible below, so that we don't stomp on a migrated value
// //from the previous version which is not the old default.
// var settingToFind = StringResources.DownloadFolder;
// var valueToSet = StringResources.DataUpTwoLevels;
// if (!ModifyConfigSetting(targetDir, StringResources.ApplicationSettings, StringResources.DataPROWin7PropertiesSettings, settingToFind, valueToSet, out result))
// {
// allResults = CombineErrorResults(allResults, result);
// allResults.Append("\r\n");
// allResults.Append(string.Format(StringResources.ThisSettingNeedsModification, settingToFind, valueToSet));
// allResults.Append("\r\n");
// }
// //Set the ImportArchiveFolder setting so that it defaults to C:\DTS\DTS.Suite\ImportArchive (..\..\ImportArchive)
// settingToFind = StringResources.ImportArchiveFolder;
// valueToSet = StringResources.ImportArchiveUpTwoLevels;
// if (!ModifyConfigSetting(targetDir, StringResources.ApplicationSettings, StringResources.DataPROWin7PropertiesSettings, settingToFind, valueToSet, out result))
// {
// allResults = CombineErrorResults(allResults, result);
// allResults.Append("\r\n");
// allResults.Append(string.Format(StringResources.ThisSettingNeedsModification, settingToFind, valueToSet));
// allResults.Append("\r\n");
// }
//}
//catch (Exception ex)
//{
// allResults = CombineErrorResults(allResults, ex.Message);
// allResults.Append("\r\n");
//}
//Note that if the old DownloadFolder setting is the old default, we will not migrate it,
//but instead we will use the current default setting that we set above.
UpdateConfigurationIfPossible(targetDir, productVersion, setupExeDir, out result);
allResults.Append(result);
allResults.Append("\r\n");
//try
//{
// if (!FixRunTimeModulesPath(targetDir, StringResources.DTSPlugins, out result))
// {
// allResults = CombineErrorResults(allResults, result);
// allResults.Append("\r\n");
// allResults.Append(StringResources.DTSPluginsNeedsModification);
// allResults.Append("\r\n");
// }
//}
//catch (Exception ex)
//{
// allResults = CombineErrorResults(allResults, ex.Message);
// allResults.Append("\r\n");
//}
if (string.IsNullOrWhiteSpace(allResults.ToString())) return;
if (noUI != "TRUE")
{
MessageBox.Show(allResults.ToString(), StringResources.ConfigMigrationStatus, MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
}
}
/// <summary>
/// Get the most-recent previously installed config file and migrate any changed settings to the newly-installed config file
/// </summary>
/// <param name="targetDir">The directory where the new config file resides.</param>
/// <param name="installingVersion">The version of DataPRO that was just installed.</param>
/// <param name="result">Text describing the success/failure of the config migration.</param>
public static void UpdateConfigurationIfPossible(string targetDir, Version installingVersion, string setupExeDir, out string result)
{
var log = new System.Diagnostics.EventLog();
log.Source = "MySource";
result = string.Empty;
var subKey = PreviousInstall.GetMostRecentlyInstalledSubKeyName(installingVersion, out string nextLowerVersion);
//log.WriteEntry("MostRecentlyInstalledSubKeyName = " + subKey);
if (string.IsNullOrWhiteSpace(subKey)) return;
var nextLowerPath = PreviousInstall.GetMostRecentlyInstalledPath(subKey);
var allResults = new StringBuilder();
_ = MigrateLicenseFile(nextLowerVersion, nextLowerPath, targetDir, setupExeDir, out var migrateLicenseResult);
allResults.AppendLine(migrateLicenseResult);
if (allResults.ToString() != StringResources.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 static StringBuilder CombineErrorResults(StringBuilder allResults, string result)
{
if (allResults.Length > 0)
{
allResults.Append("\r\n");
}
allResults.Append(result);
return allResults;
}
/// <summary>
/// Migrates the UserSettings section of the config file
/// </summary>
/// <param name="nextLowerVersion">The DataPRO version of the old config file.</param>
/// <param name="nextLowerPath">The path to the old config file.</param>
/// <param name="targetDir">The path to the new config file.</param>
/// <param name="result">Text describing the success/failure of the config migration.</param>
/// <returns>True if migration succeeded or was not needed due to all defaults in the old config file, false if it failed.</returns>
private static bool MigrateUserSettings(string nextLowerVersion, string nextLowerPath, string targetDir, out string result)
{
return MigrateSettings(StringResources.UserSettings, nextLowerVersion, nextLowerPath, targetDir, out result);
}
/// <summary>
/// identifies if a file is a datapro license
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static bool IsDataPROLicense(string path)
{
if (!File.Exists(path)) { return false; }
var contents = File.ReadAllText(path);
if (contents.Contains("<License>") && contents.Contains("<LicenseAttributes>"))
{
return true;
}
return false;
}
/// <summary>
/// finds any licenses in the directory or subdirectories
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static string FindLicenseInPath(string path, int subDirectoriesToCheck)
{
if (string.IsNullOrWhiteSpace(path)) { return null; }
if (!Directory.Exists(path)) { return null; }
var files = new DirectoryInfo(path).GetFiles("*.lic");
foreach (var file in files)
{
if (IsDataPROLicense(file.FullName)) { return file.FullName; }
}
if (0 >= subDirectoriesToCheck) { return null; }
subDirectoriesToCheck--;
var directories = new DirectoryInfo(path).GetDirectories();
foreach (var dir in directories)
{
var file = FindLicenseInPath(dir.FullName, subDirectoriesToCheck);
if (!string.IsNullOrWhiteSpace(file)) { return file; }
}
return null;
}
/// <summary>
/// copies license file from old installation to a new installation
/// </summary>
/// <param name="nextLowerVersion">next lowest version installed</param>
/// <param name="nextLowerPath">path to next lower version</param>
/// <param name="targetDir">the directory of the new install</param>
/// <param name="result">displayable string indicating results</param>
/// <returns>true if license file was copied, false otherwise</returns>
private static bool MigrateLicenseFile(string nextLowerVersion, string nextLowerPath, string targetDir, string setupExeDir, out string result)
{
try
{
var installVersionPath = FindLicenseInPath(new DirectoryInfo(setupExeDir).Parent.FullName, 2);
if (null != installVersionPath && File.Exists(installVersionPath))
{
var newPath = Path.Combine(targetDir, new FileInfo(installVersionPath).Name);
File.Copy(installVersionPath, newPath);
result = StringResources.InstallerLicenseFileFoundCopied;
return true;
}
var oldVersionPath = FindLicenseInPath(nextLowerPath, 2);
if (null != oldVersionPath && File.Exists(oldVersionPath))
{
var newPath = Path.Combine(targetDir, new FileInfo(oldVersionPath).Name);
File.Copy(oldVersionPath, newPath);
result = StringResources.OldLicenseFoundCopied;
return true;
}
result = StringResources.NoLicenseFound;
return false;
}
catch (Exception ex)
{
result = $"{StringResources.FailedToCopyLicense} {ex.Message}";
return false;
}
}
/// <summary>
/// Migrates the ApplicationSettings section of the config file
/// </summary>
/// <param name="nextLowerVersion">The DataPRO version of the old config file.</param>
/// <param name="nextLowerPath">The path to the old config file.</param>
/// <param name="targetDir">The path to the new config file.</param>
/// <param name="result">Text describing the success/failure of the config migration.</param>
/// <returns>True if migration succeeded or was not needed due to all defaults in the old config file, false if it failed.</returns>
private static bool MigrateAppSettings(string nextLowerVersion, string nextLowerPath, string targetDir, out string result)
{
return MigrateSettings(StringResources.ApplicationSettings, nextLowerVersion, nextLowerPath, targetDir, out result);
}
/// <summary>
/// If the old config file contains an element in the new config file, and it is different, copy it to the new config file.
/// </summary>
/// <param name="settingsType">Either UserSettings or ApplicationSettings.</param>
/// <param name="nextLowerVersion">The DataPRO version of the old config file.</param>
/// <param name="nextLowerPath">The path to the old config file.</param>
/// <param name="targetDir">The path to the new config file.</param>
/// <param name="result">Text describing the success/failure of the config migration.</param>
/// <returns>True if migration succeeded or was not needed due to all defaults in the old config file, false if it failed.</returns>
private static bool MigrateSettings(string settingsType, string nextLowerVersion, string nextLowerPath, string targetDir, out string result)
{
var oldSettings = new SettingElementCollection();
if (!GetOldSettings(settingsType, nextLowerPath, out result, out oldSettings))
{
return false;
}
else
{
var newSettings = new SettingElementCollection();
Configuration newConfig;
if (!ConfigInitializationHelper.GetNewSettings(settingsType, targetDir, out result, out newSettings, out newConfig))
{
return false;
}
else
{
SaveMigratedSettings(nextLowerVersion, oldSettings, newSettings, newConfig, out result);
return true;
}
}
}
/// <summary>
/// Gets the settings from the old config file
/// </summary>
/// <param name="settingsType">Either UserSettings or ApplicationSettings.</param>
/// <param name="nextLowerPath">The path to the old config file.</param>
/// <param name="result">Text describing the success/failure of the config migration.</param>
/// <param name="oldSettings">The settings from the old config file</param>
/// <returns>True if the settings were successfully found and processed, false if not.</returns>
private static bool GetOldSettings(string settingsType, string nextLowerPath,
out string result, out SettingElementCollection oldSettings)
{
result = string.Empty;
oldSettings = null;
Configuration oldConfig;
var oldPath = string.Empty;
try
{
//Open the config file from the most-recently installed version of DataPRO - this assumes that it was installed in the default folder!!!
oldPath = nextLowerPath + StringResources.RegistryDataPROExe;
oldConfig = ConfigurationManager.OpenExeConfiguration(@oldPath);
}
catch (System.Exception ex)
{
result = string.Format(StringResources.OldSettingsCouldNotBeFound, ex.Message, oldPath);
return false;
}
oldSettings = GetConfigSettings(settingsType, oldConfig);
if (oldSettings != null) return true;
result = StringResources.OldSettingsCouldNotBeProcessed;
return false;
}
/// <summary>
/// Update the new config file if needed
/// </summary>
/// <param name="nextLowerVersion">The highest version installed that is lower than this version</param>
/// <param name="oldSettings">The settings from the old config file</param>
/// <param name="newSettings">The settings from the new config file</param>
/// <param name="newConfig">The config being modified</param>
/// <param name="result">Text describing the success/failure of the config migration.</param>
/// <returns>True if the settings were successfully found and processed, false if not.</returns>
private static void SaveMigratedSettings(string nextLowerVersion, SettingElementCollection oldSettings, SettingElementCollection newSettings,
Configuration newConfig, out string result)
{
var oldSettingsDictionary = oldSettings.Cast<SettingElement>().ToDictionary(oldSetting => oldSetting.Name, oldSetting => oldSetting.Value.ValueXml.InnerXml);
var settingsToBeMigrated = new SettingElementCollection();
foreach (System.Configuration.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 != StringResources.DownloadFolder || oldSettingsDictionary[StringResources.DownloadFolder] != StringResources.DataUpOneLevel)
{
//Add to the list of settings that need to be migrated
settingsToBeMigrated.Add(newSetting);
}
}
}
foreach (System.Configuration.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 ? StringResources.ConfigDidNotNeedToBeUpdated : string.Format(StringResources.ConfigWasUpdated, nextLowerVersion);
}
/// <summary>
/// This allows you to change a config setting.
/// </summary>
/// <param name="targetDir">The path to the config file</param>
/// <param name="sectionGroupToFind">For example, "applicationSettings"</param>
/// <param name="sectionToFind">For example, "DataPROWin7.Properties.Settings"</param>
/// <param name="settingToFind">For example, "DownloadFolder"</param>
/// <param name="valueToSet">For example, "..\..\Data"</param>
/// <param name="result"></param>
/// <returns></returns>
private static bool ModifyConfigSetting(string targetDir, string sectionGroupToFind, string sectionToFind, string settingToFind, string valueToSet, out string result)
{
result = string.Empty;
try
{
//Open the new config file just installed
var newPath = Path.Combine(targetDir, StringResources.RegistryDataPROExe);
var newConfig = ConfigurationManager.OpenExeConfiguration(@newPath);
var settingFound = false;
var newConfigSectionGroup = newConfig.SectionGroups[sectionGroupToFind];
if (newConfigSectionGroup != null)
{
var applicationSettingsSection = (ClientSettingsSection)newConfigSectionGroup.Sections[sectionToFind];
var element = applicationSettingsSection.Settings.Get(settingToFind);
if (null != element)
{
settingFound = true;
applicationSettingsSection.Settings.Remove(element);
element.Value.ValueXml.InnerXml = valueToSet;
applicationSettingsSection.Settings.Add(element);
newConfig.Save();
}
}
if (!settingFound)
{
result = string.Format(StringResources.SettingNotFound, settingToFind);
return false;
}
}
catch (Exception ex)
{
result = ex.Message;
return false;
}
return true;
}
/// <summary>
/// Gets the settings in a section group of the config file.
/// </summary>
/// <param name="settingsType">Examples include "userSettings" and "applicationSettings"</param>
/// <param name="config">The config file to be interrogated.</param>
/// <returns>A collection of settings from the requested section of the config file.</returns>
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 System.Configuration.ClientSettingsSection;
}
return clientSettingsSection?.Settings;
}
}
}