98 lines
6.5 KiB
Markdown
98 lines
6.5 KiB
Markdown
---
|
||
source_files:
|
||
- DataPRO/InstallShieldBranch/Brancher.cs
|
||
- DataPRO/InstallShieldBranch/BrancherForm.Designer.cs
|
||
- DataPRO/InstallShieldBranch/BrancherForm.cs
|
||
generated_at: "2026-04-16T03:44:36.880838+00:00"
|
||
model: "Qwen/Qwen3-Coder-Next-FP8"
|
||
schema_version: 1
|
||
sha256: "568e59c2bcd65525"
|
||
---
|
||
|
||
# InstallShieldBranch
|
||
|
||
## Documentation: InstallShieldBranch Module
|
||
|
||
---
|
||
|
||
### 1. Purpose
|
||
|
||
This module provides a Windows Forms-based utility application (`Brancher.exe`) that performs binary string replacement in InstallShield `.ise` project files. Its primary purpose is to facilitate creation of variant builds (e.g., version or configuration branches) by scanning a source `.ise` file and producing a modified copy with specific byte sequences substituted. It is intended for internal use in the DataPRO build pipeline to automate branching of InstallShield projects without manual editing.
|
||
|
||
---
|
||
|
||
### 2. Public Interface
|
||
|
||
#### `static class Brancher`
|
||
- **`[STAThread] static void Main(string[] args)`**
|
||
Entry point for the application. Initializes Windows Forms visual styles and launches the `BrancherForm` modal UI.
|
||
|
||
#### `class BrancherForm : Form`
|
||
- **`BrancherForm()`**
|
||
Constructor. Initializes components, sets up a `BackgroundWorker` (`_worker`) with `WorkerReportsProgress = true` and `WorkerSupportsCancellation = true`, and attaches `worker_DoWork` to the `DoWork` event. *Note: Progress reporting and cancellation are configured but unused in current implementation.*
|
||
|
||
- **`private void button1_Click(object sender, EventArgs e)`**
|
||
Event handler for the "Branch" button click. Invokes `_worker.RunWorkerAsync()` to execute the binary replacement operation on a background thread.
|
||
|
||
#### `public static class BinaryUtility`
|
||
- **`public static IEnumerable<byte> GetByteStream(BinaryReader reader)`**
|
||
Reads the entire stream in 1024-byte chunks and yields each byte. Stops when a read returns fewer than 1024 bytes.
|
||
|
||
- **`public static void Replace(BinaryReader reader, BinaryWriter writer, IEnumerable<Tuple<byte[], byte[]>> searchAndReplace)`**
|
||
Reads all bytes from `reader`, applies all `searchAndReplace` transformations (in order), and writes the result to `writer`.
|
||
|
||
- **`public static IEnumerable<byte> Replace(IEnumerable<byte> source, IEnumerable<Tuple<byte[], byte[]>> searchAndReplace)`**
|
||
Applies each `(from, to)` pair in `searchAndReplace` *sequentially* to the `source` byte sequence, chaining replacements. Later replacements operate on the output of earlier ones.
|
||
|
||
- **`public static IEnumerable<byte> Replace(IEnumerable<byte> input, IEnumerable<byte> from, IEnumerable<byte> to)`**
|
||
Replaces *non-overlapping* occurrences of the `from` byte sequence with the `to` sequence in `input`. Uses a greedy leftmost match strategy; partial matches are discarded if not completed.
|
||
|
||
---
|
||
|
||
### 3. Invariants
|
||
|
||
- **File paths are hardcoded**: The source file path is always `@"C:\Projects\TestSetups\Installer_DataPRO_x64_DEV_2_05.ise"` and the output path is always `@"C:\Projects\TestSetups\Installer_DataPRO_x64_DEV_3_00 - New.ise"`. No configuration or user input modifies these.
|
||
- **Replacement order matters**: The `searchAndReplace` list is processed in order (first `_VED` → `_VED`, then `50_2` → `00_3`). Subsequent replacements operate on the result of prior ones.
|
||
- **No overlapping matches**: The `Replace` algorithm does not support overlapping matches; partial matches that fail to complete are discarded and not re-evaluated.
|
||
- **No progress or cancellation**: Although `_worker` is configured for progress reporting and cancellation, neither is used in `worker_DoWork`. The operation runs to completion without user feedback or abort capability.
|
||
- **UI thread safety**: UI interaction (e.g., `MessageBox.Show`) occurs on the UI thread after `DoWork` completes, as `BackgroundWorker` marshals `RunWorkerCompleted` to the UI thread (though `MessageBox.Show` is called *inside* `DoWork*, which is unsafe and may cause deadlocks—see *Gotchas*).
|
||
|
||
---
|
||
|
||
### 4. Dependencies
|
||
|
||
- **External Dependencies**:
|
||
- `System.Windows.Forms` (for `Application`, `Form`, `Button`, `MessageBox`, `BackgroundWorker`)
|
||
- `System.IO` (for `BinaryReader`, `BinaryWriter`, `FileStream`)
|
||
- `System.Linq`, `System.Collections.Generic`, `System.Threading.Tasks` (for LINQ, `List<T>`, `Tuple<T1,T2>`, `IEnumerable<T>`)
|
||
|
||
- **Internal Dependencies**:
|
||
- **Consumed by**: None (this is a standalone executable).
|
||
- **Consumes**: Only core .NET libraries; no external third-party dependencies.
|
||
|
||
- **Assumed environment**:
|
||
- Windows OS (due to `System.Windows.Forms` dependency).
|
||
- Read/write access to `C:\Projects\TestSetups\` directory.
|
||
- The source `.ise` file must exist at the hardcoded path.
|
||
|
||
---
|
||
|
||
### 5. Gotchas
|
||
|
||
- **Unsafe UI call in background thread**: `MessageBox.Show("Done")` is called inside `worker_DoWork`, which executes on a background thread. This violates Windows Forms threading rules and may cause deadlocks or exceptions. It should be moved to the `RunWorkerCompleted` event handler instead.
|
||
|
||
- **Hardcoded paths**: The input/output paths are hardcoded and unlikely to be portable. No mechanism exists to specify alternate paths (e.g., via command-line args or UI).
|
||
|
||
- **Ineffective first replacement pair**: The first `Tuple` in `searchAndReplace` maps `_VED` → `_VED` (identical). This is a no-op and likely a remnant of commented-out logic.
|
||
|
||
- **Commented-out replacements**: Two earlier replacement pairs (for `_TNI` and `10_2` → `20_2`) are commented out, suggesting this tool evolved from a previous branching need. Their presence indicates possible tech debt or incomplete refactoring.
|
||
|
||
- **No error handling**: `worker_DoWork` lacks `try`/`catch`. Exceptions (e.g., file not found, access denied) will crash the application without user feedback.
|
||
|
||
- **Binary replacement semantics**: The `Replace` algorithm replaces *first occurrences* greedily but does not handle variable-length replacements robustly (e.g., overlapping or nested patterns). It assumes fixed-length or non-conflicting patterns.
|
||
|
||
- **No validation of input file**: The code assumes the input `.ise` file is valid and contains the expected byte patterns. No checksums or schema checks are performed.
|
||
|
||
- **No cleanup of resources**: While `BinaryReader`/`BinaryWriter` are disposed via `using`, the `BackgroundWorker` instance (`_worker`) is never disposed, potentially leaking resources if the form is closed prematurely.
|
||
|
||
- **No unit tests or documentation for `BinaryUtility.Replace`**: The replacement algorithm’s correctness (especially for edge cases like empty `from`, or `from` longer than `to`) is not verified in source. |