CMM: gocmm-debug - capture the real startup NRE (PC-DMIS COM not registered)
debug.log from the bay shows the part group enumerates fine (14 .geop files
opened), then goCMM connects to PC-DMIS over COM and throws:
System.ArgumentNullException: Value cannot be null. Parameter name: type
at System.Activator.CreateInstance(Type type)
at GEAE.Common.CMM.CMMInterfaces.PCDMIS.PCDMIS.<ConnectToSoftware>b__43_0()
-> System.NullReferenceException at ConnectToSoftware(...)
Root cause: PC-DMIS automation server is not COM-registered, so
Type.GetTypeFromProgID returns null -> CreateInstance(null) throws -> the NRE
is the downstream symptom. Not part-group, not permissions, not calibration.
- PROBE 4: pull the .NET Runtime / Application Error crash stack for goCMM from
the Application log so the next run captures the null in one shot.
- PROBE 5: (a) part-group UNC reachability; (b) PC-DMIS COM registration check
(PCDLRN.* ProgID -> CLSID -> LocalServer32) that names the missing registration
and the Pcdlrn.exe /regserver fix; plus install presence for context.
- .bat header documents the COM root cause.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,16 @@ REM
|
||||
REM *** RUN THIS AS THE OPERATOR (the locked-down shop-floor user). ***
|
||||
REM *** DO NOT right-click "Run as administrator" - that hides the bug. ***
|
||||
REM
|
||||
REM Diagnoses two goCMM failures:
|
||||
REM Diagnoses goCMM startup failures:
|
||||
REM 1. "Requested registry access is not allowed" - dumps the goCMM key ACL
|
||||
REM to confirm lockdown stripped the BUILTIN\Users write grant.
|
||||
REM 2. "Object reference not set to an instance of an object" at start -
|
||||
REM PROBE 3 compares the registry 'Selected Part Group' against the
|
||||
REM ApplicationSettings.xml part groups (case-sensitive) and names the
|
||||
REM mismatch (host form / \shared vs \SHARED) that nulls SelectedPartGroup.
|
||||
REM to confirm lockdown stripped the BUILTIN\Users write grant (PROBE 1-2).
|
||||
REM 2. "Object reference not set to an instance of an object" at start:
|
||||
REM - PROBE 3: part-group match (reg vs ApplicationSettings.xml, case-sensitive).
|
||||
REM - PROBE 4: pulls the actual .NET crash stack from the Application log.
|
||||
REM - PROBE 5: part-group UNC reachability + PC-DMIS COM registration.
|
||||
REM Confirmed root cause to date: PC-DMIS COM server NOT registered ->
|
||||
REM goCMM's Activator.CreateInstance gets a null type -> NRE. Fix: run
|
||||
REM Pcdlrn.exe once elevated (/regserver). PROBE 5 reports this directly.
|
||||
REM Output lands in C:\Logs\CMM\.
|
||||
|
||||
setlocal
|
||||
|
||||
@@ -161,6 +161,87 @@ try {
|
||||
} catch { W " ERROR in part-group probe: $($_.Exception.Message)" }
|
||||
W ""
|
||||
|
||||
W "================ PROBE 4: goCMM crash events (Application log) - the actual stack ================"
|
||||
# The NRE reproduces even for admin, so it is NOT a rights problem. The faulting
|
||||
# stack names the null object. .NET pushes it to the Application log under
|
||||
# '.NET Runtime' / 'Application Error' / 'Windows Error Reporting'.
|
||||
try {
|
||||
$since = (Get-Date).AddDays(-14)
|
||||
$ev = Get-WinEvent -FilterHashtable @{ LogName='Application'; StartTime=$since } -ErrorAction SilentlyContinue |
|
||||
Where-Object { $_.ProviderName -match '\.NET Runtime|Application Error|Windows Error Reporting|Application Hang' -and "$($_.Message)" -match 'goCMM' }
|
||||
if (-not $ev) {
|
||||
W " (no goCMM-related crash events in the last 14 days - launch goCMM once, then re-run this)"
|
||||
} else {
|
||||
foreach ($e in ($ev | Select-Object -First 5)) {
|
||||
W (" ---- {0} [{1}] EventId={2} ----" -f $e.TimeCreated, $e.ProviderName, $e.Id)
|
||||
foreach ($line in ("$($e.Message)" -split "`r?`n")) { W (" " + $line) }
|
||||
W ""
|
||||
}
|
||||
W " >> The topmost goCMM / GEA_OFI frame in the stack above is where the null is dereferenced. <<"
|
||||
}
|
||||
} catch { W " ERROR reading event log: $($_.Exception.Message)" }
|
||||
W ""
|
||||
|
||||
W "================ PROBE 5: part-group UNC reachability + PC-DMIS install ================"
|
||||
# (a) Can THIS bay open the Selected Part Group share? An unreachable / unauthenticated
|
||||
# UNC -> goCMM enumerates null -> startup NRE, regardless of local rights (admin too).
|
||||
try {
|
||||
$base32 = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine','Registry32')
|
||||
$kpg = $base32.OpenSubKey($key32native, $false)
|
||||
$pg = if ($kpg) { [string]$kpg.GetValue('Selected Part Group','') } else { '' }
|
||||
if ($kpg) { $kpg.Close() }
|
||||
if ($pg) {
|
||||
W (" part group UNC: $pg")
|
||||
if (Test-Path -LiteralPath $pg -ErrorAction SilentlyContinue) {
|
||||
$n = @(Get-ChildItem -LiteralPath $pg -ErrorAction SilentlyContinue).Count
|
||||
W (" >> REACHABLE - $n item(s) under it. (not the NRE cause) <<")
|
||||
} else {
|
||||
W " >> *** UNREACHABLE *** bay cannot open the part-group UNC (share offline, not on the"
|
||||
W " >> production net yet, or no credential to \\tsgwp00525\SHARED). goCMM enumerating this"
|
||||
W " >> path returns null -> startup NRE even for admin. Check net connectivity + share auth. <<"
|
||||
}
|
||||
} else { W " (no Selected Part Group in registry)" }
|
||||
} catch { W " ERROR testing part-group UNC: $($_.Exception.Message)" }
|
||||
W ""
|
||||
# (b) PC-DMIS COM automation - THE confirmed root cause (see debug.log). goCMM
|
||||
# connects via Activator.CreateInstance on the PC-DMIS COM type. If the
|
||||
# automation server is not registered, Type.GetTypeFromProgID returns null
|
||||
# -> CreateInstance(null) -> "ArgumentNullException: ... Parameter name: type"
|
||||
# -> ConnectToSoftware derefs null -> NRE. PC-DMIS can be RUNNING and still
|
||||
# not be COM-registered. Stack: GEAE.Common.CMM.CMMInterfaces.PCDMIS.ConnectToSoftware.
|
||||
$comOk = $false
|
||||
foreach ($pgid in 'PCDLRN.Application','PCDLRN.Automation','Pcdlrn.Application','PCDLRN.Object') {
|
||||
foreach ($cls in "HKLM:\SOFTWARE\Classes\$pgid","HKLM:\SOFTWARE\Classes\WOW6432Node\$pgid") {
|
||||
if (Test-Path $cls) {
|
||||
$clsid = (Get-ItemProperty -Path "$cls\CLSID" -ErrorAction SilentlyContinue).'(default)'
|
||||
$comOk = $true
|
||||
$srv = $null
|
||||
if ($clsid) {
|
||||
foreach ($cb in "HKLM:\SOFTWARE\Classes\CLSID\$clsid\LocalServer32","HKLM:\SOFTWARE\Classes\WOW6432Node\CLSID\$clsid\LocalServer32") {
|
||||
if (Test-Path $cb) { $srv = (Get-ItemProperty -Path $cb -EA SilentlyContinue).'(default)' }
|
||||
}
|
||||
}
|
||||
W (" COM ProgID registered: $pgid CLSID=$clsid server=$srv")
|
||||
}
|
||||
}
|
||||
}
|
||||
if (-not $comOk) {
|
||||
W " >> *** PC-DMIS COM SERVER NOT REGISTERED *** no PCDLRN.* ProgID in HKCR. This is exactly the"
|
||||
W " >> null behind 'ArgumentNullException: ... Parameter name: type' in debug.log -> goCMM startup NRE."
|
||||
W " >> FIX: run the installed Pcdlrn.exe once ELEVATED (self-registers), or 'Pcdlrn.exe /regserver'."
|
||||
W " >> Then confirm the registered build matches the goCMM-expected PC-DMIS version (the version gate). <<"
|
||||
}
|
||||
# install presence (context for the COM verdict)
|
||||
$pcdlrn = $null
|
||||
foreach ($d in 'C:\Program Files\Hexagon','C:\Program Files (x86)\Hexagon','C:\Program Files\WAI','C:\Program Files (x86)\WAI') {
|
||||
if (Test-Path $d) {
|
||||
$hit = Get-ChildItem $d -Filter 'Pcdlrn.exe' -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1
|
||||
if ($hit) { $pcdlrn = $hit.FullName; W (" Pcdlrn.exe: $($hit.FullName) v$((Get-Item $hit.FullName).VersionInfo.FileVersion)"); break }
|
||||
}
|
||||
}
|
||||
if (-not $pcdlrn) { W " Pcdlrn.exe NOT found in standard dirs - PC-DMIS not installed where expected." }
|
||||
W ""
|
||||
|
||||
W "================ UAC / registry virtualization ================"
|
||||
(reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableLUA 2>&1 | Out-String) | W
|
||||
(reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v EnableVirtualization 2>&1 | Out-String) | W
|
||||
|
||||
Reference in New Issue
Block a user