init
This commit is contained in:
@@ -0,0 +1,436 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user