---
title: Console application execution lifecycle
summary: Orchestrates the standard initialize/validate/run/uninitialize template-method lifecycle shared by all console and batch applications built on this library.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Presentation.ConsoleApplication
reference_type: package
operation_id: OP-CA-001
trigger: A downstream subclass's Sub Main instantiates a clsConsoleBase/clsBatchBase subclass and calls Execute()
---

# Console application execution lifecycle

This is the template-method lifecycle every console or batch application built on this library follows. `clsConsoleBase.Execute()` fixes the order of initialization, command-line validation, main-logic execution, and teardown; a batch subclass (`clsBatchBase`) does not override `Execute()` itself but overrides `Initialize()`/`Uninitialize()` to add multi-stream log registration and a batch header/footer around the same lifecycle.

| Field | Value |
| --- | --- |
| **Operation ID** | OP-CA-001 |
| **Trigger** | Downstream `Sub Main` instantiates a `clsConsoleBase`/`clsBatchBase` subclass and calls `Execute()` |
| **Inputs** | Command-line arguments (`Environment.GetCommandLineArgs`); for a batch subclass, also the set of currently defined environment variables |
| **Outputs** | `ReturnCode` / `Environment.ExitCode`; console output (batch header/footer, prompts); for a batch subclass, flushed/closed log-stream files |
| **Primary components** | `clsConsoleBase.Execute`, `clsConsoleBase.Initialize`, `clsConsoleBase.Uninitialize`, `clsBatchBase.Initialize`, `clsBatchBase.Uninitialize`, `clsBatchBase.WriteBatchHeader`, `clsBatchBase.WriteBatchFooter` |
| **Entry point** | `Presentation\SAIF.Presentation.ConsoleApplication\clsConsoleBase.vb` |

## Steps

1. **Construct the application object.** The subclass's constructor runs `clsConsoleBase.New()`, which records `m_StartTime = Now` for later use by `RunningTime`/`WriteBatchFooter`.
2. **Initialize.** `Execute()` calls `Initialize()`.
   - Base behavior (`clsConsoleBase.Initialize`): sets `ReturnCode = ReturnCodes.UnknownError` as the default exit code, then reads `Environment.GetCommandLineArgs`, and for each argument strips a single leading `/` or `-` and upper-cases it before storing it ([BR-002](../business-rules.md#br-002-case-insensitive-command-line-switch-matching)).
   - If the subclass is a `clsBatchBase`: `Initialize()` is overridden — it calls `MyBase.Initialize()` first (running the base behavior above), then scans every current environment variable name and pre-registers any whose upper-cased name matches the pattern `FILE?` (e.g., `FILE0`…`FILE4`) into an internal log-stream table with an empty placeholder value, then calls `WriteBatchHeader()`, which writes `"<AppName> began at <StartTime>"` to the console via `WriteStatusMsg`.
3. **Check for a debug flag.** `Execute()` calls `ParamExists("DEBUG")` ([BR-005](../business-rules.md#br-005-command-line-parameter-names-match-by-prefix-not-exact-equality)); the result is not currently wired to any observable behavior in this library.*
4. **Validate the command line.** `Execute()` calls the abstract `ValidateCommandLine()`, implemented by the concrete downstream application.
5. **Branch on validation result** ([BR-003](../business-rules.md#br-003-command-line-validation-gates-application-logic)):
   - If `True`: `Execute()` calls the abstract `RunAppLogic()`, the concrete application's main logic.
   - If `False`: `Execute()` writes `"Press enter to continue..."` to the console and blocks on `Console.Read()` instead of calling `RunAppLogic()`.
6. **Uninitialize.** `Execute()` always calls `Uninitialize()` after the branch above, regardless of which path was taken.
   - If the subclass is a `clsBatchBase`: `Uninitialize()` is overridden — it calls `WriteBatchFooter()` first, which writes `"<AppName> ended at <EndTime>"` and `"<AppName> ran for <seconds> seconds"` to the console; then, for every log-stream entry that was actually opened as a `StreamWriter` (not left as its empty placeholder string), it flushes and closes that stream; only then does it call `MyBase.Uninitialize()` (the base implementation is a no-op).
7. **Return.** `Execute()` returns; the process's `Environment.ExitCode` reflects whatever value was last assigned to `ReturnCode` (defaulting to `UnknownError` from step 2 unless `RunAppLogic()` or another step explicitly sets a different value).*

## Process flow

The following diagram visualizes the `Execute()` template-method lifecycle, including the batch-specific extensions to `Initialize()`/`Uninitialize()`.

```mermaid
flowchart TD
	Start([Sub Main calls Execute]) --> Init[Initialize:<br>default ReturnCode,<br>parse command line]
	Init --> IsBatch{Batch subclass?}
	IsBatch -->|Yes| BatchInit[Pre-register FILE?<br>environment variables;<br>write batch header]
	IsBatch -->|No| Debug
	BatchInit --> Debug{DEBUG flag present?}
	Debug --> Validate{ValidateCommandLine}
	Validate -->|True| Run[RunAppLogic]
	Validate -->|False| Prompt["Press enter to continue..."]
	Run --> Uninit[Uninitialize]
	Prompt --> Uninit
	Uninit --> IsBatch2{Batch subclass?}
	IsBatch2 -->|Yes| BatchUninit[Write batch footer;<br>flush/close opened log streams]
	IsBatch2 -->|No| End
	BatchUninit --> End([Return; ExitCode reflects ReturnCode])
```

## Failure and edge-case behavior

- When `ValidateCommandLine()` returns `False`, `RunAppLogic()` is never invoked; the process instead waits indefinitely on `Console.Read()` for operator input before proceeding to `Uninitialize()` ([BR-003](../business-rules.md#br-003-command-line-validation-gates-application-logic)).
- `Uninitialize()` always runs after the validate/run branch, so batch log streams are flushed and closed even when `RunAppLogic()` was never called.
- `ReturnCode` defaults to `UnknownError` at the start of `Initialize()`; if the concrete `RunAppLogic()` implementation completes without explicitly setting `ReturnCode`, the process exits with `UnknownError` rather than `Success`.*
- The `/DEBUG` check in `Execute()` calls `ParamExists("DEBUG")` but the result is not used to alter logging or control flow anywhere in this library's source.*
- `clsBatchBase.Uninitialize` only flushes/closes log-stream entries whose stored value is not still the placeholder empty string — a stream that was pre-registered but never actually written to via `WriteAppLogMsg` is left unopened and is skipped.

> **Note:** Statements marked with `*` were inferred from code structure, naming
> conventions, or contextual evidence where direct confirmation was not available
> in source artifacts.

## Related documentation

- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)

## Sources

- `Presentation\SAIF.Presentation.ConsoleApplication\clsConsoleBase.vb`
- `Presentation\SAIF.Presentation.ConsoleApplication\clsBatchBase.vb`
