diff --git a/playbook/shopfloor-setup/gea-shopfloor-cmm/09-Setup-CMM.ps1 b/playbook/shopfloor-setup/gea-shopfloor-cmm/09-Setup-CMM.ps1 index f1a5953..4bf9d7b 100644 --- a/playbook/shopfloor-setup/gea-shopfloor-cmm/09-Setup-CMM.ps1 +++ b/playbook/shopfloor-setup/gea-shopfloor-cmm/09-Setup-CMM.ps1 @@ -175,6 +175,24 @@ foreach ($dir in $pcdmisDirs) { } } +# ============================================================================ +# Step 2.5b: GE PC-DMIS FRONT END dir (PCDToIGES.exe error-log path) +# ============================================================================ +# PCDToIGES.exe (in every bay's C:\geaofi\Scripts) writes its error log to +# C:\GE PC-DMIS FRONT END\PCDToIGES.ERR inside its catch block. The legacy +# "GE PC-DMIS FRONT END" front-end setup that created this dir is not part of +# imaging, so on a fresh bay it is absent - and then ANY PCDToIGES failure +# becomes an unhandled DirectoryNotFoundException that crashes the export and +# MASKS the real error. Create it + grant the operator Modify so errors log. +$frontEnd = 'C:\GE PC-DMIS FRONT END' +try { + if (-not (Test-Path -LiteralPath $frontEnd)) { New-Item -ItemType Directory -Path $frontEnd -Force | Out-Null; Write-CMMLog "Created $frontEnd" } + foreach ($sid in '*S-1-5-32-545','*S-1-5-11') { # BUILTIN\Users, NT AUTHORITY\Authenticated Users + & icacls "$frontEnd" /grant "${sid}:(OI)(CI)M" /T /C 2>&1 | Out-Null + } + Write-CMMLog "Granted Users + Authenticated Users Modify on $frontEnd" +} catch { Write-CMMLog "Failed to ensure ${frontEnd}: $_" "WARN" } + # ============================================================================ # Step 2.6: First-run-as-admin for each installed PC-DMIS version # ============================================================================ @@ -315,27 +333,23 @@ if (Test-Path -LiteralPath $restoreScript) { } # ============================================================================ -# Step 2.5: drop Register-PCDMIS-COM.bat on the SupportUser desktop +# Step 2.5: drop Register-PCDMIS-COM.bat on the Public desktop # ============================================================================ # PC-DMIS COM must be registered for goCMM to connect, but /regserver no-ops # until PC-DMIS is licensed - which happens manually post-image (clmadmin.exe). # So we cannot register at imaging time; instead leave a one-click helper the -# tech runs AFTER activating the license. SupportUser is a pre-existing profile -# (see 03-ShellDefaults), so its Desktop exists now. Public Desktop would get -# reorganized by 06-OrganizeDesktop's sweep, so target SupportUser directly; -# fall back to Public Desktop only if the SupportUser profile is absent. +# tech runs AFTER activating the license. Public Desktop so it is visible to +# whoever logs in (operator or SupportUser). NOTE: 06-OrganizeDesktop sweeps the +# Public Desktop root into category subfolders, so it may end up under +# "Shopfloor Tools" rather than the bare desktop - still on the Public desktop. $regBat = Join-Path $stagingRoot 'Register-PCDMIS-COM.bat' if (Test-Path -LiteralPath $regBat) { - $deskTargets = @() - if (Test-Path 'C:\Users\SupportUser') { $deskTargets += 'C:\Users\SupportUser\Desktop' } - else { $deskTargets += 'C:\Users\Public\Desktop' } - foreach ($d in $deskTargets) { - try { - if (-not (Test-Path $d)) { New-Item -Path $d -ItemType Directory -Force | Out-Null } - Copy-Item -LiteralPath $regBat -Destination (Join-Path $d 'Register-PCDMIS-COM.bat') -Force - Write-CMMLog "Staged Register-PCDMIS-COM.bat -> $d" - } catch { Write-CMMLog "Failed to stage Register-PCDMIS-COM.bat to ${d}: $_" 'WARN' } - } + $d = 'C:\Users\Public\Desktop' + try { + if (-not (Test-Path $d)) { New-Item -Path $d -ItemType Directory -Force | Out-Null } + Copy-Item -LiteralPath $regBat -Destination (Join-Path $d 'Register-PCDMIS-COM.bat') -Force + Write-CMMLog "Staged Register-PCDMIS-COM.bat -> $d" + } catch { Write-CMMLog "Failed to stage Register-PCDMIS-COM.bat to ${d}: $_" 'WARN' } } else { Write-CMMLog "Register-PCDMIS-COM.bat not in staging ($regBat) - desktop helper NOT placed" 'WARN' } diff --git a/playbook/shopfloor-setup/gea-shopfloor-cmm/scripts/Ensure-PCDMISFrontEnd.bat b/playbook/shopfloor-setup/gea-shopfloor-cmm/scripts/Ensure-PCDMISFrontEnd.bat new file mode 100644 index 0000000..fdb42da --- /dev/null +++ b/playbook/shopfloor-setup/gea-shopfloor-cmm/scripts/Ensure-PCDMISFrontEnd.bat @@ -0,0 +1,21 @@ +@echo off +REM Ensure-PCDMISFrontEnd.bat - launcher for Ensure-PCDMISFrontEnd.ps1 +REM +REM Creates C:\GE PC-DMIS FRONT END + grants the operator write access, so +REM PCDToIGES.exe can write its error log there instead of crashing with +REM "Could not find a part of the path 'C:\GE PC-DMIS FRONT END\PCDToIGES.ERR'". +REM +REM Needs admin - self-elevates. + +net session >nul 2>&1 +if %errorlevel% neq 0 ( + echo Requesting administrator rights... + powershell -NoProfile -Command "Start-Process -FilePath '%~f0' -Verb RunAs" + exit /b +) + +set "HERE=%~dp0" +powershell.exe -NoProfile -ExecutionPolicy Bypass -File "%HERE%Ensure-PCDMISFrontEnd.ps1" + +echo. +pause diff --git a/playbook/shopfloor-setup/gea-shopfloor-cmm/scripts/Ensure-PCDMISFrontEnd.ps1 b/playbook/shopfloor-setup/gea-shopfloor-cmm/scripts/Ensure-PCDMISFrontEnd.ps1 new file mode 100644 index 0000000..d959aa6 --- /dev/null +++ b/playbook/shopfloor-setup/gea-shopfloor-cmm/scripts/Ensure-PCDMISFrontEnd.ps1 @@ -0,0 +1,47 @@ +# Ensure-PCDMISFrontEnd.ps1 - create C:\GE PC-DMIS FRONT END + grant operator write. +# +# WHY: PCDToIGES.exe (geaofi\Scripts) writes its error log to +# C:\GE PC-DMIS FRONT END\PCDToIGES.ERR in its catch block. If that dir does +# not exist, ANY PCDToIGES failure becomes an unhandled DirectoryNotFoundException +# that CRASHES the export and MASKS the real error (observed on freshly imaged CMM +# bays - the legacy "GE PC-DMIS FRONT END" front-end setup is not part of imaging, +# so the dir is absent). Creating it + making it operator-writable lets the real +# error log instead of crashing, and gives the front-end a working dir. +# +# Run as administrator. Idempotent - safe to re-run; re-asserts the ACL. + +$ErrorActionPreference = 'Continue' +$dir = 'C:\GE PC-DMIS FRONT END' + +$logDir = 'C:\Logs\CMM' +New-Item -ItemType Directory -Path $logDir -Force -EA SilentlyContinue | Out-Null +$ts = Get-Date -Format 'yyyyMMdd-HHmmss' +$log = Join-Path $logDir "pcdmis-frontend-$ts.log" +function Log($m){ $line = "[{0}] {1}" -f (Get-Date -Format 'HH:mm:ss'), $m; Write-Host $line; Add-Content -Path $log -Value $line -EA SilentlyContinue } + +Log "==== Ensure-PCDMISFrontEnd on $env:COMPUTERNAME ====" + +if (Test-Path -LiteralPath $dir) { + Log "Dir already exists: $dir" +} else { + try { New-Item -ItemType Directory -Path $dir -Force -EA Stop | Out-Null; Log "Created $dir" } + catch { Log "ERROR: could not create $dir - $($_.Exception.Message)"; exit 1 } +} + +# Operator (locked-down, non-admin) must be able to write PCDToIGES.ERR here. +# Modify = read/write/create/delete. SIDs, not names, to stay locale-independent. +foreach ($sid in '*S-1-5-32-545','*S-1-5-11') { # BUILTIN\Users, NT AUTHORITY\Authenticated Users + & icacls "$dir" /grant "${sid}:(OI)(CI)M" /T /C 2>&1 | Out-Null +} +Log "Granted Users + Authenticated Users Modify on $dir" + +# Verify an operator-style write works +$probe = Join-Path $dir '.write-test' +try { Set-Content -LiteralPath $probe -Value 'ok' -EA Stop; Remove-Item -LiteralPath $probe -EA SilentlyContinue; Log "Write-test OK" } +catch { Log "WARN: write-test failed - $($_.Exception.Message)" } + +Log "==== DONE ====" +Write-Host "" +Write-Host "C:\GE PC-DMIS FRONT END ready. Re-run the measurement; if PCDToIGES still" -ForegroundColor Green +Write-Host "errors, the real cause now logs to $dir\PCDToIGES.ERR" -ForegroundColor Green +exit 0