Joseph Doherty 842b94fb39 graccesscli: fix attribute value reader (typed IMxValue + IgnoreCase)
The MxValueDetails reader was the root of the false "writeback gap"
diagnosis. Three problems compounded:

1. ReadProperty(attr, "Value") used case-sensitive late-binding via
   InvokeMember. The COM-side property is exposed as `value` (lowercase)
   on IAttribute, so the lookup silently returned null.

2. Even if the MxValue was retrieved, the accessor probe loop
   (Invoke(value, "GetBoolean") -> "GetInteger" -> ... -> "GetString")
   relied on IDispatch late-binding. The MxValue interface's accessors
   are vtable-only — they aren't reachable through IDispatch — so every
   call threw, and the reader reported "no supported scalar accessor
   succeeded" even when the typed accessor would have returned the
   value cleanly.

3. The probe loop ordering put GetString last, so for any value that
   somehow survived the type errors silently, an earlier accessor could
   have returned a wrong-typed result.

Fix:

- Add `BindingFlags.IgnoreCase` to ReadProperty + Invoke. COM IDispatch
  is case-insensitive at the IDL level; .NET InvokeMember is not unless
  explicitly told to be. Comment explains the trap.
- AttributeValueDetails now uses typed `attr.value` (and falls back to
  the same lookup via obj.ConfigurableAttributes when the runtime proxy
  returns null), bypassing the late-binding gap entirely.
- MxValueDetails casts to IMxValue and dispatches on
  GetDataType().ToString(), calling the typed scalar accessor for the
  declared type (GetBoolean / GetInteger / GetFloat / GetDouble /
  GetString / GetElapsedTime). MxBigString and MxInternationalizedString
  share the GetString path. MxTime is left as a follow-up; its
  VBFILETIME field layout differs across interop builds.
- Replaced the misleading "Attribute value is not exposed" / "no
  scalar accessor succeeded" messages with specific diagnostics that
  identify the actual failure (wrong type cast, typed accessor exception,
  unhandled MxDataType).

Live verification on $DelmiaReceiver.ProcessRecipe.DeclarationsText:

  BEFORE fix: `attribute value get` → Supported: false, Value: null,
              "Attribute value is not exposed by this GRAccess attribute."
  AFTER fix:  `attribute value get` → Supported: true, DataType: MxString,
              Value: "// roundtrip-test marker (graccesscli scripts set
              --field DeclarationsText)\n"

The reader now correctly surfaces the value graccesscli's writes have
been persisting all along. This is the gap that produced the "writeback
gap" mirage in the previous round of investigation.

Tests still 66/66.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 21:50:16 -04:00
S
Description
No description provided
3.4 MiB
Languages
C# 93.3%
TSQL 4.2%
PowerShell 1.5%
Shell 0.7%
Python 0.3%