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

6.1 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
DataPRO/Modules/InstallerCustomActions/RegAddProductCode/AddProductCode.cs
2026-04-16T04:43:28.721583+00:00 Qwen/Qwen3-Coder-Next-FP8 1 c22465a70e9ccf40

RegAddProductCode

Documentation: AddProductCode.cs — Installer Custom Action for Registry Policy Configuration


1. Purpose

This module implements a Windows Installer custom action (AddProductCode) responsible for configuring Windows Installer security policies in the registry prior to or during DataPRO installation. Specifically, it enforces the SecureRepairPolicy setting and adds the DataPRO product code to the SecureRepairWhitelist, enabling the installer to perform repair operations on DataPRO.exe and its dependencies without being blocked by Windows Installers secure repair restrictions. It also validates architecture compatibility between the installer process (32- or 64-bit) and the operating system, terminating the installation with a user-facing error if a mismatch is detected (e.g., 32-bit installer on 64-bit OS), to prevent downstream failures such as incompatible SQL LocalDB version conflicts.


2. Public Interface

The class AddProductCode exposes only one public entry point:

static int Main(string[] args)

  • Signature: private static int Main(string[] args)
  • Behavior:
    Entry point for the custom action. Parses args[0] as architectureVersion ("x86" or "x64"), logs environment details (process bitness, OS bitness), and performs architecture validation:
    • If architectureVersion == "x86" and OS is 64-bit → shows error message and returns 1.
    • If architectureVersion == "x64" and OS is 32-bit → shows error message and returns 1.
    • Otherwise, calls AddCodeToRegistry() and returns 0 (success) or 1 (failure if registry write fails).
    • Logging is performed via EventLog.WriteEntry under source "DataPROInstaller".

Note

: Though declared private, this method is the de facto public entry point for the custom action as invoked by the Windows Installer (e.g., via CustomAction table). It is not called internally.


3. Invariants

  • Architecture Consistency:
    The installer process bitness must match the target OS bitness relative to the requested architecture (args[0]). Mismatches cause early termination with exit code 1.
  • Registry Hive & View:
    All registry modifications target HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\Installer using RegistryView.Registry64, ensuring writes occur in the 64-bit view even on 64-bit systems (i.e., not redirected to WOW6432Node).
  • Policy Values:
    The following must be set:
    • SecureRepairPolicy (DWORD) = 2 (enables secure repair for whitelisted products).
    • SecureRepairWhitelist\{C4889149-0CAF-44C1-B226-8F6E73684DF4} (DWORD) = 0 (adds product code to whitelist).
  • Exit Codes:
    • 0: Success (registry updated or already correct).
    • 1: Failure due to architecture mismatch or registry write error.

4. Dependencies

Imports / External Dependencies:

  • System.Diagnostics.EventLog for installer logging.
  • Microsoft.Win32.RegistryKey, RegistryHive, RegistryView, RegistryValueKind for registry access.
  • System.Windows.Forms.MessageBox for user-facing error messages.
  • RegAddProductCode.Properties.Settings.Default static configuration values:
    • Settings.Default.InstallerKey: Registry path "SOFTWARE\\Policies\\Microsoft\\Windows\\Installer"
    • Settings.Default.SecureRepairPolicy: Policy value name "SecureRepairPolicy"
    • Settings.Default.SecureRepairWhitelistKey: Subkey path "SOFTWARE\\Policies\\Microsoft\\Windows\\Installer\\SecureRepairWhitelist"
    • Settings.Default.ProductCode: Product code GUID "{C4889149-0CAF-44C1-B226-8F6E73684DF4}"
    • Settings.Default.MissingKey: Format string for error messages (e.g., "Registry key missing: {0}").

Usage:

  • Called by: Windows Installer as a custom action (likely in a WiX or similar MSI project).
  • Depends on:
    • Administrative privileges (required to write to HKLM\SOFTWARE\Policies\...).
    • EventLog source "DataPROInstaller" must exist or be creatable by the installer process.

5. Gotchas

  • Hardcoded Product Code:
    The product code "{C4889149-0CAF-44C1-B226-8F6E73684DF4}" is hardcoded in both Settings.Default.ProductCode and the whitelist logic. Changing the product code in the installer project requires updating this value manually—no dynamic injection is present.

  • Silent Failure Risk in 32-bit on 64-bit:
    The comment explains that allowing a 32-bit installer on 64-bit OS could cause the SQL LocalDB 2014 prerequisite to fail silently, leading to runtime DB version incompatibility. This is a preventive guard, but the fix is architectural (blocking 32-bit installers entirely on 64-bit OS), not a workaround.

  • Registry View Hardcoded to 64-bit:
    RegistryView.Registry64 is used unconditionally—even on 32-bit OSes. While OpenBaseKey with Registry64 on a 32-bit OS is safe (it falls back to the native view), this may be unintentional or legacy. No explicit fallback to RegistryView.Registry32 exists.

  • No Rollback Handling:
    If AddCodeToRegistry() succeeds but the main installer fails later, the registry changes are not rolled back. The policy settings remain in place.

  • Commented-Out UI Error:
    The line // MessageBox.Show(result); is commented out in Main(), meaning registry errors are only logged to Event Log, not shown to the user. This may reduce visibility during silent installs.

  • No Exception Handling Granularity:
    AddCodeToRegistry() catches all exceptions generically and returns only the message string. Specific exceptions (e.g., UnauthorizedAccessException, SecurityException) are not differentiated.

  • Assumes Installer Runs with Admin Rights:
    The code assumes the custom action runs with elevated privileges. If not, registry writes will fail silently (or with generic error), and no fallback is implemented.


End of documentation.