Skip to content

Fix/adc v2027 net8 fallback - Autodesk desktop connector#3266

Merged
jmcouffin merged 11 commits intodevelopfrom
fix/adc-v2027-net8-fallback
Apr 7, 2026
Merged

Fix/adc v2027 net8 fallback - Autodesk desktop connector#3266
jmcouffin merged 11 commits intodevelopfrom
fix/adc-v2027-net8-fallback

Conversation

@tay0thman
Copy link
Copy Markdown
Contributor

@tay0thman tay0thman commented Apr 5, 2026

fix(adc): ADC v2027 compatibility — filesystem fallback for Revit 2025/2026 (.NET 8)

Description

ADC v2027 (v7.8.1.11) broke pyrevit.interop.adc on Revit 2025/2026 (.NET 8). The Keynote Manager shows "Autodesk Desktop Connector is not available" even though ADC is installed, running, and files are synced locally.

Root cause: ADC v2027 removed the .NET 8-compatible API DLL from FOS\AddInProcess\Civil3DOE. Both remaining API surfaces — the legacy Autodesk.DesktopConnector.API.dll and the new Autodesk.DesktopConnector.API.Public.dll — were compiled against .NET Framework's System.ServiceModel (WCF), which does not exist on .NET 8. This is an Autodesk regression with no assembly-level workaround.

Fix: Adds a three-tier fallback architecture to adc.py:

Tier Method When it activates
1 — Public API DesktopConnectorApiClient (v2027+) Future-proof: will activate automatically if Autodesk fixes their DLL
2 — Legacy API DesktopConnectorService (v15–v17) Revit 2023/2024 (.NET FW) or ADC v15–v17 with Civil3DOE on .NET 8
3 — Filesystem Process detection + workspace directory walking ADC v2027 on Revit 2025/2026 — bypasses broken API entirely

The filesystem fallback detects the ADC tray process, parses the cloud path schema (Autodesk Forma://org/project/...), and resolves it to the local file under %USERPROFILE%\DC\ACCDocs\. Lock/unlock/sync degrade to no-ops — ADC handles sync transparently at the OS level.

Also restructures the Keynote Manager's ADC diagnostic into two tiers: a safe diagnostic (tests Public API only, no AppDomain poisoning) that runs for all users, and a deep diagnostic (probes legacy DLLs + WCF) gated behind PYREVIT_ADC_DIAG=1 environment variable.

Critical design decision: When API.Public.dll exists (v2027), the legacy load is never attempted (exclusive elif). DesktopConnectorService() triggers WCF resolution whose failure is cached in the .NET AppDomain, poisoning all subsequent assembly loads — including unrelated code.

Files changed

  • pyrevitlib/pyrevit/interop/adc.py — Three-tier load sequence, WCF preloading, filesystem fallback with workspace directory scanning, graceful degradation for lock/sync operations
  • extensions/.../Keynotes.pushbutton/script.py — Two-tier diagnostic system (_adc_diagnose_safe / _adc_diagnose_deep), restructured _determine_kfile() to call is_available() on clean AppDomain before any diagnostic runs

Compatibility matrix

ADC Version Revit 2023/2024 (.NET FW) Revit 2025/2026 (.NET 8)
v15–v17 Tier 2 — full ops (unchanged) Tier 2 via Civil3DOE — full ops (unchanged)
v2027 Tier 2 from root — full ops Tier 3 — filesystem fallback (new)

Checklist

  • Code follows the PEP 8 style guide.
  • Code has been formatted with Black using the command:
pipenv run black {source_file_or_directory}
  • Changes are tested and verified to work as expected.

Related Issues


Additional Notes

Testing performed

All four combinations verified on physical hardware:

Configuration Result
ADC v17.x + Revit 2024 (.NET FW) ✅ Legacy API — full ops, unchanged behavior
ADC v17.x + Revit 2026 (.NET 8) ✅ Legacy API via Civil3DOE — full ops, unchanged behavior
ADC v2027 + Revit 2024 (.NET FW) ✅ Legacy API from root — full ops
ADC v2027 + Revit 2026 (.NET 8) ✅ Filesystem fallback — keynote opens, lock/sync skipped

Autodesk regression

This should also be reported to Autodesk: ADC v2027 ships zero functional .NET 8 API surfaces. The FOS\AddInProcess\Civil3DOE DLL was removed and the replacement API.Public.dll has a transitive WCF dependency that prevents instantiation on .NET 8. All Revit 2025/2026 add-ins that depend on the ADC API are affected.

Diagnostic workflow for users reporting issues

Users experiencing ADC issues can set the environment variable PYREVIT_ADC_DIAG=1 before launching Revit. This enables the deep diagnostic tier which probes legacy DLLs, WCF assemblies, and prints a detailed report to the pyRevit output window. Without the env var, only the safe (non-poisoning) diagnostic runs.


Thank you for contributing to pyRevit! 🎉

jmcouffin and others added 5 commits April 2, 2026 00:22
Refine GitHub Actions workflow to improve reference commit logic for pull requests. Updated condition to handle merged pull requests more effectively.
ADC v2027 (v7.8.1.11) removed the .NET 8-compatible API DLL from
FOS/AddInProcess/Civil3DOE. Both remaining API CLSsurfaces (legacy API.dll
and new API.Public.dll) were compiled against .NET Framework's unified
System.ServiceModel, making them unusable on Revit 2025/2026 (.NET 8).

Fix: three-tier fallback in adc.py
- Tier 1: Public API (future-proof for when Autodesk fixes the DLL)
- Tier 2: Legacy API (ADC v15-v17, exclusive elif to prevent AppDomain poison)
- Tier 3: Filesystem fallback (process detection + workspace dir walking)

Also restructures Keynote Manager diagnostic into safe/deep tiers to
prevent WCF AppDomain poisoning during troubleshooting.

Tested on: ADC v17.x + Revit 2024, ADC v17.x + Revit 2026,
           ADC v2027 + Revit 2024, ADC v2027 + Revit 2026.

Closes #XXXX
Copy link
Copy Markdown
Contributor

@devloai devloai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Summary:

  • Fixes ADC v2027 compatibility regression on Revit 2025/2026 (.NET 8) where both legacy and public API DLLs have broken WCF dependencies
  • Adds a three-tier fallback: Public API → Legacy API → Filesystem (process detection + workspace directory walking)
  • Restructures Keynote Manager ADC diagnostics into safe (always-on) and deep (env-gated) tiers to avoid AppDomain poisoning
  • Gracefully degrades lock/sync operations when only the Public API is available

Review Summary:

This is a well-motivated fix for a real Autodesk regression, and the AppDomain-poisoning concern is correctly identified and handled. The three-tier architecture is sound. A few bugs were found:

High priority: The AssemblyResolve handler registered in _preload_wcf_for_public_api is never unregistered and its partial-match fallback (req in cn or cn in req) could silently redirect unrelated assemblies for the entire Revit session. Additionally, is_available()'s filesystem fallback can return True when get_local_path() will subsequently return None (mismatched org/drive), giving users a confusing secondary error.

Medium priority: _pub_drive_path_to_local uses str.replace() (replaces all occurrences) instead of a prefix-strip. The 10-character fuzzy project folder match in _resolve_path_from_filesystem risks false-positive matches. A dead-code guard condition in _determine_kfile (line 1278) always evaluates _kfile_handler != 'unknown' as False. The _try_wcf_shim function mutates adc.API without updating adc._api_mode, leaving module state inconsistent.

Low priority: NuGet version directories are sorted lexicographically rather than semantically (affects minor versions ≥ 10). Black formatting was explicitly skipped per the PR checklist but is a repository requirement.

Suggestions

  • Run pipenv run black on both changed files to satisfy the mandatory Black formatting requirement before merging. Apply
  • Add a dedicated get_local_path overload to is_available() so the filesystem fallback can pre-validate the cloud path's org segment and avoid a misleading secondary error when path resolution fails. Apply

Apply all quick fixes (7 quick fixes)

- Apply Black formatter to both changed files
- Fix .None enum access for Black parser compatibility (getattr pattern)
- Remove partial-match from AssemblyResolve handler (exact keys only)
- Use prefix-strip instead of str.replace in path resolution
- Replace 10-char fuzzy match with full startswith comparison
- Validate workspace roots contain org dirs in filesystem fallback
- Remove dead-code guard in _determine_kfile
- Remove adc.API mutation from diagnostic _try_wcf_shim
- Add semantic version sorting for NuGet directory scanning
@tay0thman
Copy link
Copy Markdown
Contributor Author

@devloai Made corrections and pushed a new commit 55a9245
your job is to review and report back

Copy link
Copy Markdown
Contributor

@devloai devloai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ All previous review issues addressed

Excellent work on commit 55a92451. Every issue from the previous review has been cleanly resolved:

# Issue Status
1 AssemblyResolve partial-match fallback (unrelated assembly redirection risk) ✅ Removed — exact key lookup only in adc.py
2 str.replace() in _pub_drive_path_to_local (all-occurrences risk) ✅ Fixed — path[len(drive_schema):] prefix-strip
3 10-char fuzzy project folder match (wrong-project false positives) ✅ Fixed — full bidirectional startswith
4 is_available() filesystem fallback returning True for empty workspace roots ✅ Fixed — now validates org subdirs exist
5 Dead-code _kfile_handler != 'unknown' guard ✅ Removed — _determine_kfile fully restructured
6 adc.API = api_module module state mutation in diagnostic ✅ Removed — _try_wcf_shim is observe-only
7 Lexicographic NuGet version sort (fails for minor ≥ 10) ✅ Fixed — _ver_key() semantic sort
8 Black formatting not applied ✅ Applied throughout both files

One minor note (non-blocking): _try_wcf_shim in script.py (lines 545–547) still has the partial-match AssemblyResolve fallback — but this is intentionally in the deep diagnostic (poison-aware) path and is clearly scoped/commented as such. Acceptable design choice.

The three-tier fallback architecture is well-structured, the AppDomain-poisoning concern is properly guarded, and the diagnostic system is a nice addition for user-facing debugging. LGTM 👍

@jmcouffin
Copy link
Copy Markdown
Contributor

Tested by user in #3089 🏁

@jmcouffin
Copy link
Copy Markdown
Contributor

@tay0thman can you remove all the now unnecessary logging please.

I'll review and merge after that

@tay0thman
Copy link
Copy Markdown
Contributor Author

@jmcouffin Removed all Logging and pushed commit ef91266

@jmcouffin jmcouffin changed the title Fix/adc v2027 net8 fallback Fix/adc v2027 net8 fallback - Autodesk desktop connector Apr 7, 2026
@jmcouffin jmcouffin merged commit d25bf81 into develop Apr 7, 2026
@jmcouffin jmcouffin deleted the fix/adc-v2027-net8-fallback branch April 7, 2026 20:32
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

📦 New work-in-progress (wip) builds are available for 6.3.0.26097+2031-wip

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 7, 2026

📦 New work-in-progress (wip) builds are available for 6.3.0.26097+2314-wip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Keynote Manager and Autodesk Desktop Connector Issues

2 participants