v1.3.0: Fixed header UI + auto-elevate to Administrator
- GE Aerospace ASCII banner stays fixed at top of console - Live status line updates (Processing, Cleaned, Failed, etc.) - Live stats counter in header (Cleaned/Failed counts) - Batch file auto-elevates to Administrator via UAC 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,9 +36,15 @@
|
||||
|
||||
.NOTES
|
||||
Author: GE Aerospace - Rutland
|
||||
Version: 1.2.1
|
||||
Version: 1.3.0
|
||||
Date: 2025-12-12
|
||||
|
||||
v1.3.0 - Fixed header UI:
|
||||
- GE Aerospace ASCII banner stays at top
|
||||
- Live status updates in header (Processing, Cleaned, Failed)
|
||||
- Live stats counter (Cleaned/Failed count)
|
||||
- Auto-elevate to Administrator via batch file
|
||||
|
||||
v1.2.0 - Immediate processing:
|
||||
- Process file immediately when eDNC releases it (50ms initial delay)
|
||||
- Aggressive retry: 100ms -> 200ms -> 400ms -> 800ms (15 attempts)
|
||||
@@ -68,38 +74,82 @@ param(
|
||||
)
|
||||
|
||||
# Script info
|
||||
$ScriptVersion = "1.2.1"
|
||||
$ScriptVersion = "1.3.0"
|
||||
$ScriptName = "eDNC Special Character Fix"
|
||||
|
||||
# Display banner
|
||||
Write-Host ""
|
||||
Write-Host " ____ ____ " -ForegroundColor Cyan
|
||||
Write-Host " / ___|| ___| / \ ___ _ __ ___ ___ _ __ __ _ ___ ___ " -ForegroundColor Cyan
|
||||
Write-Host "| | _ | _| / _ \ / _ \ '__/ _ \/ __| '_ \ / _`` |/ __/ _ \" -ForegroundColor Cyan
|
||||
Write-Host "| |_| || |___ / ___ \ __/ | | (_) \__ \ |_) | (_| | (_| __/" -ForegroundColor Cyan
|
||||
Write-Host " \____||_____| /_/ \_\___|_| \___/|___/ .__/ \__,_|\___\___|" -ForegroundColor Cyan
|
||||
Write-Host " |_| " -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host " $ScriptName" -ForegroundColor White
|
||||
Write-Host " by Cam P. | v$ScriptVersion" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
Write-Host "================================================================" -ForegroundColor DarkGray
|
||||
# Header display function
|
||||
function Show-Header {
|
||||
param([int]$Cleaned = 0, [int]$Failed = 0, [string]$Status = "Watching...")
|
||||
|
||||
$headerLines = @(
|
||||
""
|
||||
" ____ ____ "
|
||||
" / ___|| ___| / \ ___ _ __ ___ ___ _ __ __ _ ___ ___ "
|
||||
"| | _ | _| / _ \ / _ \ '__/ _ \/ __| '_ \ / _`` |/ __/ _ \"
|
||||
"| |_| || |___ / ___ \ __/ | | (_) \__ \ |_) | (_| | (_| __/"
|
||||
" \____||_____| /_/ \_\___|_| \___/|___/ .__/ \__,_|\___\___|"
|
||||
" |_| "
|
||||
""
|
||||
" $ScriptName"
|
||||
" by Cam P. | v$ScriptVersion"
|
||||
""
|
||||
" Folder: $WatchFolder"
|
||||
" Filter: $FileFilter | Cleaned: $Cleaned | Failed: $Failed"
|
||||
""
|
||||
" Status: $Status"
|
||||
"================================================================"
|
||||
)
|
||||
|
||||
# Save cursor, go to top, draw header
|
||||
[Console]::SetCursorPosition(0, 0)
|
||||
|
||||
for ($i = 0; $i -lt $headerLines.Count; $i++) {
|
||||
$line = $headerLines[$i]
|
||||
# Clear line and write
|
||||
Write-Host ("`r" + $line.PadRight([Console]::WindowWidth - 1)) -NoNewline
|
||||
|
||||
# Apply colors
|
||||
[Console]::SetCursorPosition(0, $i)
|
||||
if ($i -ge 1 -and $i -le 6) {
|
||||
Write-Host $line -ForegroundColor Cyan
|
||||
} elseif ($i -eq 8) {
|
||||
Write-Host $line -ForegroundColor White
|
||||
} elseif ($i -eq 9) {
|
||||
Write-Host $line -ForegroundColor Gray
|
||||
} elseif ($i -eq 14) {
|
||||
if ($Status -like "*ERROR*" -or $Status -like "*FAILED*") {
|
||||
Write-Host $line -ForegroundColor Red
|
||||
} elseif ($Status -like "*CLEANED*") {
|
||||
Write-Host $line -ForegroundColor Green
|
||||
} else {
|
||||
Write-Host $line -ForegroundColor Yellow
|
||||
}
|
||||
} elseif ($i -eq 15) {
|
||||
Write-Host $line -ForegroundColor DarkGray
|
||||
} else {
|
||||
Write-Host $line
|
||||
}
|
||||
}
|
||||
|
||||
return $headerLines.Count
|
||||
}
|
||||
|
||||
# Initialize console
|
||||
Clear-Host
|
||||
$script:HeaderHeight = Show-Header -Status "Initializing..."
|
||||
|
||||
# Validate watch folder exists
|
||||
if (-not (Test-Path $WatchFolder)) {
|
||||
Write-Host "[ERROR] Watch folder does not exist: $WatchFolder" -ForegroundColor Red
|
||||
Show-Header -Status "ERROR: Watch folder does not exist!"
|
||||
[Console]::SetCursorPosition(0, $script:HeaderHeight + 1)
|
||||
Write-Host "Please create the folder or specify a different path." -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Display configuration
|
||||
Write-Host "Configuration:" -ForegroundColor Yellow
|
||||
Write-Host " Watch Folder: $WatchFolder"
|
||||
Write-Host " File Filter: $FileFilter"
|
||||
Write-Host " Subfolders: $IncludeSubfolders"
|
||||
Write-Host " Removing bytes: $($CharactersToRemove -join ', ') (0x$($CharactersToRemove | ForEach-Object { '{0:X2}' -f $_ } | Join-String -Separator ', 0x'))"
|
||||
Write-Host ""
|
||||
Write-Host "Watching for files... Press Ctrl+C to stop" -ForegroundColor Green
|
||||
# Update header with ready status
|
||||
Show-Header -Status "Watching for files... (Ctrl+C to stop)" | Out-Null
|
||||
[Console]::SetCursorPosition(0, $script:HeaderHeight + 1)
|
||||
Write-Host "Removing bytes: $($CharactersToRemove -join ', ') (0x$($CharactersToRemove | ForEach-Object { '{0:X2}' -f $_ } | Join-String -Separator ', 0x'))" -ForegroundColor DarkGray
|
||||
Write-Host ""
|
||||
|
||||
# Statistics
|
||||
@@ -127,6 +177,24 @@ $action = {
|
||||
# Get parameters from message data
|
||||
$charsToRemove = $Event.MessageData.CharsToRemove
|
||||
$debounceSeconds = $Event.MessageData.DebounceSeconds
|
||||
$statusLine = $Event.MessageData.StatusLine
|
||||
|
||||
# Helper to update status line in header
|
||||
$updateStatus = {
|
||||
param($msg, $color = "Yellow")
|
||||
$savedPos = [Console]::CursorTop
|
||||
[Console]::SetCursorPosition(0, $statusLine)
|
||||
Write-Host (" Status: " + $msg).PadRight([Console]::WindowWidth - 1) -ForegroundColor $color
|
||||
[Console]::SetCursorPosition(0, $savedPos)
|
||||
}
|
||||
|
||||
# Helper to update stats line in header
|
||||
$updateStats = {
|
||||
$savedPos = [Console]::CursorTop
|
||||
[Console]::SetCursorPosition(0, 12)
|
||||
Write-Host (" Filter: $($Event.MessageData.FileFilter) | Cleaned: $($script:FilesProcessed) | Failed: $($script:FailedFiles)").PadRight([Console]::WindowWidth - 1) -ForegroundColor White
|
||||
[Console]::SetCursorPosition(0, $savedPos)
|
||||
}
|
||||
|
||||
# Debounce check - skip if we processed this file recently
|
||||
$now = Get-Date
|
||||
@@ -137,6 +205,7 @@ $action = {
|
||||
}
|
||||
}
|
||||
|
||||
& $updateStatus "Processing: $fileName" "Yellow"
|
||||
Write-Host "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') | $changeType | $fileName" -ForegroundColor White
|
||||
|
||||
# Brief initial delay to let eDNC finish (50ms)
|
||||
@@ -186,8 +255,11 @@ $action = {
|
||||
Write-Host " [CLEANED] Removed $removed byte(s)" -ForegroundColor Green
|
||||
$script:FilesProcessed++
|
||||
$script:BytesRemoved += $removed
|
||||
& $updateStatus "CLEANED: $fileName ($removed bytes)" "Green"
|
||||
& $updateStats
|
||||
} else {
|
||||
Write-Host " [OK] No special characters found" -ForegroundColor Gray
|
||||
& $updateStatus "OK: $fileName (no changes)" "Gray"
|
||||
}
|
||||
|
||||
# Mark as recently processed
|
||||
@@ -197,18 +269,23 @@ $action = {
|
||||
catch [System.IO.IOException] {
|
||||
$retryCount++
|
||||
if ($retryCount -lt $maxRetries) {
|
||||
# Exponential backoff: 500ms, 1s, 2s, 4s, 8s, 16s...
|
||||
# Exponential backoff: 100ms, 200ms, 400ms, 800ms...
|
||||
$delay = [math]::Min($baseDelay * [math]::Pow(2, $retryCount - 1), 16000)
|
||||
Write-Host " [RETRY] File locked, waiting $([math]::Round($delay/1000, 1))s... ($retryCount/$maxRetries)" -ForegroundColor Yellow
|
||||
& $updateStatus "RETRY: $fileName ($retryCount/$maxRetries)" "Yellow"
|
||||
Start-Sleep -Milliseconds $delay
|
||||
} else {
|
||||
Write-Host " [FAILED] Could not access file after $maxRetries attempts" -ForegroundColor Red
|
||||
$script:FailedFiles++
|
||||
& $updateStatus "FAILED: $fileName" "Red"
|
||||
& $updateStats
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host " [ERROR] $($_.Exception.Message)" -ForegroundColor Red
|
||||
$script:FailedFiles++
|
||||
& $updateStatus "ERROR: $fileName" "Red"
|
||||
& $updateStats
|
||||
break
|
||||
}
|
||||
finally {
|
||||
@@ -224,6 +301,8 @@ $action = {
|
||||
$messageData = @{
|
||||
CharsToRemove = $CharactersToRemove
|
||||
DebounceSeconds = $script:DebounceSeconds
|
||||
StatusLine = 14 # Line number for status updates
|
||||
FileFilter = $FileFilter
|
||||
}
|
||||
|
||||
# Register event handlers
|
||||
|
||||
Reference in New Issue
Block a user