ci: add github action for release builds and include pending feature updates

This commit is contained in:
2025-12-22 16:25:57 +01:00
parent 157828f49d
commit 89445a901f
3 changed files with 232 additions and 6 deletions

65
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,65 @@
name: Release Build
on:
push:
tags:
- 'v*'
workflow_dispatch:
permissions:
contents: write
jobs:
build-and-release:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
cache: true
- name: Get Version
id: get_version
run: |
if [[ $GITHUB_REF == refs/tags/* ]]; then
VERSION=${GITHUB_REF#refs/tags/v}
else
VERSION="0.0.0-dev"
fi
echo "Detected Version: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Update Version in Files
run: |
echo "Updating version in PrintCleaner.manifest to ${VERSION}.0"
# Update Manifest (Format: 1.0.0.0)
sed -i "s/version=\"[0-9]*\\.[0-9]*\\.[0-9]*\\.[0-9]*\"/version=\"${VERSION}.0\"/" PrintCleaner.manifest
echo "Updating version in PrintCleaner.ps1 to ${VERSION}"
# Update PowerShell Script
sed -i "s/\$AppVersion = \"0.0.0\"/\$AppVersion = \"${VERSION}\"/" PrintCleaner.ps1
- name: Generate Resources (Icon & Manifest)
run: |
# Install rsrc dependency if not present (handled by go.mod, but go run ensures it)
go run github.com/akavel/rsrc -manifest PrintCleaner.manifest -ico icon.ico -arch amd64 -o rsrc.syso
- name: Build
run: |
output_name="PrintCleaner_v${VERSION}.exe"
echo "Building $output_name..."
GOOS=windows GOARCH=amd64 go build -o "$output_name" main.go
echo "ARTIFACT_NAME=$output_name" >> $GITHUB_ENV
- name: Create Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: ${{ env.ARTIFACT_NAME }}
draft: false
prerelease: false
generate_release_notes: true

View File

@@ -3,7 +3,7 @@
<assemblyIdentity <assemblyIdentity
type="win32" type="win32"
name="PrintCleaner.App" name="PrintCleaner.App"
version="1.0.0.0" version="1.0.12.0"
processorArchitecture="amd64" processorArchitecture="amd64"
/> />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">

View File

@@ -6,6 +6,7 @@
This script provides a text-based interface to: This script provides a text-based interface to:
1. Remove all printers and drivers (preserving Microsoft defaults). 1. Remove all printers and drivers (preserving Microsoft defaults).
2. Clear the Windows Print Spooler queue. 2. Clear the Windows Print Spooler queue.
3. Uninstall bundled printer software.
Requires Administrator privileges. Requires Administrator privileges.
.NOTES .NOTES
@@ -15,9 +16,10 @@
#> #>
# --- Configuration --- # --- Configuration ---
$Host.UI.RawUI.WindowTitle = "PrintCleaner" $AppVersion = "0.0.0" # Replaced by build script
$Host.UI.RawUI.WindowTitle = "PrintCleaner v$AppVersion"
$global:running = $true $global:running = $true
$menuOptions = @("List Installed Printers", "Clean Print Queue", "Remove All Printers & Drivers", "Exit") $menuOptions = @("List Installed Printers", "Clean Print Queue", "Remove All Printers & Drivers", "Uninstall Printer Software", "Exit")
$selectionIndex = 0 $selectionIndex = 0
# --- Helper Functions --- # --- Helper Functions ---
@@ -35,7 +37,7 @@ function Show-Header {
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 " " -ForegroundColor Cyan Write-Host " v$AppVersion " -ForegroundColor DarkGray
Write-Host "Use UP/DOWN arrows to navigate, ENTER to select." -ForegroundColor Gray Write-Host "Use UP/DOWN arrows to navigate, ENTER to select." -ForegroundColor Gray
Write-Host "" Write-Host ""
} }
@@ -62,6 +64,34 @@ function Wait-Key {
} }
} }
function Get-InstalledSoftware {
$paths = @(
"HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*",
"HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
)
# Use array subexpression to safely collect output objects.
# This avoids the "Hash table" addition error because we aren't using += on potentially mixed types.
$list = @(foreach ($path in $paths) {
$items = Get-ItemProperty $path -ErrorAction SilentlyContinue
foreach ($item in $items) {
# FORCE STRING CONVERSION IMMEDIATELY
$name = [string]$item.DisplayName
$cmd = [string]$item.UninstallString
if (-not [string]::IsNullOrWhiteSpace($name) -and -not [string]::IsNullOrWhiteSpace($cmd)) {
# Output object to pipeline (collected by @())
[PSCustomObject]@{
DisplayName = $name
UninstallString = $cmd
}
}
}
})
return $list
}
# --- Action Functions --- # --- Action Functions ---
function Invoke-ListPrinters { function Invoke-ListPrinters {
@@ -198,6 +228,136 @@ function Invoke-RemovePrinters {
Wait-Key Wait-Key
} }
function Invoke-UninstallSoftware {
Show-Header
Write-Host "SEARCHING FOR PRINTER SOFTWARE..." -ForegroundColor Yellow
Write-Host "Scanning registry for common printer brands..." -ForegroundColor DarkGray
# Common printer brands/keywords
$brands = @("HP", "Hewlett-Packard", "Canon", "Epson", "Brother", "Xerox", "Kyocera", "Ricoh", "Lexmark", "Konica", "Samsung", "Oki", "Zebra", "Dymo", "Dell")
$allSoftware = Get-InstalledSoftware
# Simple array, no ArrayList to avoid potential type issues
$matches = @()
# Filter software list
foreach ($sw in $allSoftware) {
foreach ($brand in $brands) {
if ($sw.DisplayName -match "(?i)\b$brand\b") { # Case insensitive regex match
$matches += $sw
break
}
}
}
if ($matches.Count -eq 0) {
Write-Host "`nNo printer-related software found." -ForegroundColor Green
Wait-Key
return
}
# Selection Loop
while ($true) {
Show-Header
Write-Host "FOUND PRINTER SOFTWARE" -ForegroundColor Cyan
Write-Host "----------------------" -ForegroundColor Cyan
Write-Host "The following software matched printer keywords."
Write-Host "Select an item to launch its uninstaller." -ForegroundColor DarkGray
Write-Host ""
for ($i = 0; $i -lt $matches.Count; $i++) {
# DISPLAY COMMAND IN MENU FOR DEBUGGING
$truncCmd = $matches[$i].UninstallString
if ($truncCmd.Length -gt 50) { $truncCmd = $truncCmd.Substring(0, 47) + "..." }
Write-Host " [$($i+1)] $($matches[$i].DisplayName)" -ForegroundColor White
Write-Host " Cmd: $truncCmd" -ForegroundColor DarkGray
}
Write-Host ""
Write-Host " [A] Uninstall ALL Listed Software (Auto-Silent)" -ForegroundColor Yellow
Write-Host ""
Write-Host "Enter selection (or 'q' to return): " -NoNewline -ForegroundColor Yellow
$input = Read-Host
if ($input -eq 'q') {
return
}
if ($input -match '^[Aa]$') {
Write-Host "`nWARNING: This will attempt to silently uninstall ALL listed software." -ForegroundColor Red
Write-Host "Are you sure? (Y/N): " -NoNewline -ForegroundColor Yellow
$confirm = Read-Host
if ($confirm -match '^[Yy]$') {
$count = 0
$total = $matches.Count
foreach ($app in $matches) {
$count++
$percent = [int](($count / $total) * 100)
Write-Progress -Activity "Uninstalling Software" -Status "Removing: $($app.DisplayName)" -PercentComplete $percent
$rawCmd = $app.UninstallString
if ([string]::IsNullOrWhiteSpace($rawCmd)) {
Write-Host " [!] Skipping: Uninstall string is empty." -ForegroundColor DarkGray
continue
}
$finalCmd = "$rawCmd"
# Add silent flags
if ($rawCmd -match "msiexec") {
if ($rawCmd -notmatch "/qn" -and $rawCmd -notmatch "/quiet") {
$finalCmd = "$finalCmd /qn /norestart"
}
} elseif ($rawCmd -match "uninstall.exe" -or $rawCmd -match "setup.exe") {
if ($rawCmd -notmatch "/S" -and $rawCmd -notmatch "/silent") {
$finalCmd = "$finalCmd /S /silent /quiet /norestart"
}
}
Write-Host "[$count/$total] $($app.DisplayName)" -ForegroundColor Yellow
Write-Host " Cmd: $finalCmd" -ForegroundColor DarkGray
try {
Start-Process -FilePath "cmd.exe" -ArgumentList "/c", "$finalCmd" -Wait -WindowStyle Hidden
} catch {
Write-Host " [!] Error launching: $($_.Exception.Message)" -ForegroundColor Red
}
Start-Sleep -Seconds 1
}
Write-Progress -Activity "Uninstalling Software" -Completed
Write-Host "`nDone processing list." -ForegroundColor Green
Wait-Key
return
}
}
elseif ($input -match '^\d+$' -and [int]$input -le $matches.Count -and [int]$input -gt 0) {
$idx = [int]$input - 1
$app = $matches[$idx]
Write-Host "Launching uninstaller for: $($app.DisplayName)..." -ForegroundColor Yellow
$cmdToRun = $app.UninstallString
if ([string]::IsNullOrWhiteSpace($cmdToRun)) {
Write-Host "[ERROR] Uninstall string is empty. (Debug: '$cmdToRun')" -ForegroundColor Red
Start-Sleep -Seconds 2
continue
}
Write-Host "Cmd: $cmdToRun" -ForegroundColor DarkGray
try {
Start-Process -FilePath "cmd.exe" -ArgumentList "/c", "$cmdToRun" -PassThru
Start-Sleep -Seconds 2
} catch {
Write-Host "Error launching uninstaller: $($_.Exception.Message)" -ForegroundColor Red
Start-Sleep -Seconds 2
}
}
}
}
# --- Main Loop --- # --- Main Loop ---
if (-not (Test-Administrator)) { if (-not (Test-Administrator)) {
@@ -231,7 +391,8 @@ while ($global:running) {
0 { Invoke-ListPrinters } 0 { Invoke-ListPrinters }
1 { Invoke-CleanQueue } 1 { Invoke-CleanQueue }
2 { Invoke-RemovePrinters } 2 { Invoke-RemovePrinters }
3 { $global:running = $false } 3 { Invoke-UninstallSoftware }
4 { $global:running = $false }
} }
} }
27 { # Escape 27 { # Escape
@@ -242,4 +403,4 @@ while ($global:running) {
Clear-Host Clear-Host
try { $Host.UI.RawUI.CursorSize = 25 } catch {} # Restore cursor try { $Host.UI.RawUI.CursorSize = 25 } catch {} # Restore cursor
Write-Host "Exiting PrintCleaner. Goodbye!" -ForegroundColor Cyan Write-Host "Exiting PrintCleaner. Goodbye!" -ForegroundColor Cyan