Files
2026-04-17 14:55:32 -04:00

6.6 KiB

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/InstallerCustomActions/MigrateConfiguration/ConfigurationMigration.cs
2026-04-16T04:43:59.723876+00:00 Qwen/Qwen3-Coder-Next-FP8 1 499179ba93465fb0

MigrateConfiguration

Documentation: ConfigurationMigration.cs

1. Purpose

This module implements a configuration migration mechanism for DataPRO installer custom actions. Its primary role is to preserve user- and application-specific settings from the most recently installed previous version of DataPRO when a new version is installed, ensuring continuity of configuration without overwriting user-modified values with fresh defaults. It operates during installation by reading the old configuration file (if present), comparing settings against the new defaults, and migrating only those that differ (with special handling for DownloadFolder to avoid reverting to outdated defaults). It also handles migration of license files (.lic) from previous installations.


2. Public Interface

The module is internal static class ConfigurationMigration. While not public, it exposes one method intended for use by the installer custom action infrastructure:

  • UpdateConfigurationIfPossible(string targetDir, Version installingVersion, string setupExeDir, out string result)
    Purpose: Orchestrates configuration migration.
    Behavior:
    • Determines the most recently installed previous version using PreviousInstall.GetMostRecentlyInstalledSubKeyName.
    • Retrieves the installation path of that version via PreviousInstall.GetMostRecentlyInstalledPath.
    • Calls MigrateLicenseFile to copy license files.
    • Returns via result a status string indicating whether the config was updated, skipped, or failed.
    • Does not migrate ApplicationSettings or UserSettings sections itself—this appears to be omitted in the active code (commented out in Main). Only license migration is performed in the current implementation.

Note: The Main(string[] args) method is private static and serves as the entry point for the custom action. It parses command-line arguments (targetDir, installingVersion, noUI, setupExeDir), initializes event logging, and calls UpdateConfigurationIfPossible. It also shows a MessageBox with migration results if noUI != "TRUE".


3. Invariants

  • Version ordering: Migration only occurs if a strictly older version is detected (installingVersion must be greater than the previously installed version).
  • Path assumptions:
    • The old config file is assumed to reside at <oldInstallPath>\DataPRO.exe (via StringResources.RegistryDataPROExe).
    • License files are searched up to 2 subdirectories deep from either the current install directory (setupExeDir) or the old install path.
  • Setting migration logic:
    • A setting is migrated only if:
      1. It exists in both old and new config files.
      2. Its value in the old config differs from the new default (i.e., the value in the new config file before migration).
      3. Exception for DownloadFolder: It is not migrated if the old value equals StringResources.DataUpOneLevel (the old default), to avoid reverting to outdated paths.
  • No partial migration of sections: If MigrateSettings fails for either UserSettings or ApplicationSettings, the entire section is skipped.
  • License file detection: A file is considered a DataPRO license only if it is a .lic file containing both <License> and <LicenseAttributes> XML elements.

4. Dependencies

Internal dependencies (within module):

  • StringResources (from MigrateConfiguration.Resources) — provides string constants (e.g., DownloadFolder, UserSettings, ApplicationSettings, DataUpOneLevel, DataUpTwoLevels, ImportArchiveUpTwoLevels, DTSPlugins, etc.).
  • PreviousInstall — used to query registry for previous installation metadata (GetMostRecentlyInstalledSubKeyName, GetMostRecentlyInstalledPath).
  • ConfigInitializationHelper — used in MigrateSettings via GetNewSettings (not shown in this file; inferred from usage).
  • SettingElementCollection, SettingElement, ClientSettingsSection, Configuration — from System.Configuration.

External dependencies (imports):

  • System.Configuration
  • System.Windows.Forms (for MessageBox.Show)
  • System.IO
  • DTS.Common.Utilities
  • Installer.Common

Depended upon by:

  • The Windows Installer custom action that invokes ConfigurationMigration.Main(string[] args) with command-line arguments.

5. Gotchas

  • Critical omission: The Main method contains commented-out code blocks that were intended to:
    • Pre-set DownloadFolder and ImportArchiveFolder to current defaults before migration.
    • Call MigrateUserSettings and MigrateAppSettings (via UpdateConfigurationIfPossible or directly).
    • Fix runtime module paths (FixRunTimeModulesPath).
      As written, only license migration is active. Configuration settings (UserSettings, ApplicationSettings) are not migrated in the current implementation.
  • Hardcoded recursion depth: FindLicenseInPath only searches 2 subdirectories deep (subDirectoriesToCheck = 2). Deeper nested license files will be missed.
  • Assumption of default install paths: GetOldSettings assumes the old config file is at <oldInstallPath>\DataPRO.exe. If the previous installation used a custom path, migration will fail.
  • No rollback on failure: If license copying fails, the error is reported but no cleanup or fallback occurs.
  • Event logging is non-functional: The EventLog.Source is set to "MySource" (hardcoded), but the source "DataPROInstaller" is created earlier. This mismatch may cause logging failures.
  • noUI check is fragile: noUI != "TRUE" is case-sensitive and exact. "true" or "True" would not suppress the UI.
  • SettingElementCollection mutability: The code removes and re-adds SettingElement instances to newSettings. This assumes SettingElementCollection allows modification after Configuration load, which may be fragile depending on .NET version or config file locking.
  • Missing null checks: GetConfigSettings accesses configurationSectionGroup.Sections[0] without verifying Sections.Count > 0, risking IndexOutOfRangeException if the section exists but is empty.

None identified from source alone for behavioral quirks beyond the above — but the commented-out code strongly suggests this module is partially implemented or in a transitional state.