Skip to content

adc

Wrapping Autodesk Desktop Connector API.

Supports two API surfaces
  • LEGACY (ADC v15-v17): Autodesk.DesktopConnector.API.DesktopConnectorService Full file-level ops (lock, unlock, sync, properties). Requires WCF on .NET Framework; had a dedicated .NET 8 build at FOS/AddInProcess/Civil3DOE (removed in v2027).

  • PUBLIC (ADC v2027+): Autodesk.DesktopConnector.API.Public.DesktopConnectorApiClient Subscription-level ops only (projects, drives, availability). No file-level lock/unlock/sync - degrades gracefully. Native .NET 8 support, no WCF dependency.

Attributes

ADC_NAME = 'Autodesk Desktop Connector' module-attribute

ADC_SHORTNAME = 'ADC' module-attribute

ADC_DRIVE_SCHEMA = '{drive_name}://' module-attribute

ADC_ROOT = 'C:\\Program Files\\Autodesk\\Desktop Connector' module-attribute

API = None module-attribute

API_PUBLIC = None module-attribute

ADC_DEFAULT_INSTALL_PATH = ADC_ROOT module-attribute

ADC_API_DLL = 'Autodesk.DesktopConnector.API.dll' module-attribute

ADC_API_DLL_PATH = op.join(ADC_ROOT, ADC_API_DLL) module-attribute

Classes

Functions

is_available()

Check if ADC service is available. Falls back to process detection if API calls fail.

Source code in pyrevitlib/pyrevit/interop/adc.py
def is_available():
    """Check if ADC service is available.
    Falls back to process detection if API calls fail."""
    if API_PUBLIC:
        try:
            client = _get_pub_client()
            try:
                client.GetDesktopConnectorInfo()
                return True
            finally:
                client.Dispose()
        except Exception as ex:
            pass
    if API:
        try:
            _get_adc().Discover()
            return True
        except Exception as ex:
            pass
    # Filesystem fallback: ADC process running + workspace dirs exist
    # Verify workspace roots actually contain org subdirectories
    if _adc_process_running():
        for ws_root in _find_workspace_roots():
            try:
                import os as _os

                entries = _os.listdir(ws_root)
                if any(op.isdir(op.join(ws_root, e)) for e in entries):
                    return True
            except Exception:
                pass
    return False

get_drive_paths()

Get dict of local paths for ADC drives.

Source code in pyrevitlib/pyrevit/interop/adc.py
def get_drive_paths():
    """Get dict of local paths for ADC drives."""
    if API_PUBLIC:
        try:
            return {s.Name: s.Path for s in _get_pub_subscriptions()}
        except Exception:
            pass
    if API:
        adc = _get_adc()
        return {x.Name: x.WorkspaceLocation for x in _get_drives_info(adc)}
    # Filesystem fallback: list workspace root contents
    import os as _os

    result = {}
    for ws_root in _find_workspace_roots():
        try:
            for org in _os.listdir(ws_root):
                org_path = op.join(ws_root, org)
                if op.isdir(org_path):
                    result[org] = org_path
        except Exception:
            pass
    return result

get_local_path(path)

Convert ADC cloud drive path to local path.

Source code in pyrevitlib/pyrevit/interop/adc.py
def get_local_path(path):
    """Convert ADC cloud drive path to local path."""
    # Try Public API first (v2027+)
    if API_PUBLIC:
        try:
            sub, schema = _pub_drive_from_path(path)
            if sub:
                return _pub_drive_path_to_local(sub, schema, path)
        except Exception as ex:
            pass
    # Try Legacy API
    if API:
        try:
            adc = _get_adc()
            drv_info = _get_drive_from_path(adc, path)
            if drv_info:
                return _drive_path_to_local_path(drv_info, path)
        except Exception as ex:
            pass
    # Filesystem fallback
    resolved = _resolve_path_from_filesystem(path)
    if resolved:
        return resolved
    return None

lock_file(path)

Lock given file. No-op if only Public API available.

Source code in pyrevitlib/pyrevit/interop/adc.py
def lock_file(path):
    """Lock given file. No-op if only Public API available."""
    if not API:
        return
    adc = _get_adc()
    item = _get_item(adc, path)
    adc.LockFile(item.Id)

is_locked(path)

Check if file is locked. Returns (False, None) if unavailable.

Source code in pyrevitlib/pyrevit/interop/adc.py
def is_locked(path):
    """Check if file is locked. Returns (False, None) if unavailable."""
    if not API:
        return False, None
    adc = _get_adc()
    item = _get_item(adc, path)
    lock_status = _get_item_lockstatus(adc, item)
    return lock_status.State == API.LockState.LockedByOther, lock_status.LockOwner

unlock_file(path)

Unlock given file. No-op if only Public API available.

Source code in pyrevitlib/pyrevit/interop/adc.py
def unlock_file(path):
    """Unlock given file. No-op if only Public API available."""
    if not API:
        return
    adc = _get_adc()
    item = _get_item(adc, path)
    adc.UnlockFile(item.Id)

is_synced(path)

Check if file is synchronized. Assumes True if unavailable.

Source code in pyrevitlib/pyrevit/interop/adc.py
def is_synced(path):
    """Check if file is synchronized. Assumes True if unavailable."""
    if not API:
        return True
    adc = _get_adc()
    item = _get_item(adc, path)
    drive = _get_item_drive(adc, item)
    prop_val = _get_item_property_id_value(
        adc, drive, item, "DesktopConnector.Core.LocalState"
    )
    if prop_val is None:
        prop_val = _get_item_property_id_value(adc, drive, item, "LocalState")
    return prop_val.Value == "Cached" or prop_val.Value == "Synced"

sync_file(path, force=False)

Force ADC to sync given file. No-op if only Public API available.

Source code in pyrevitlib/pyrevit/interop/adc.py
def sync_file(path, force=False):
    """Force ADC to sync given file. No-op if only Public API available."""
    if not API:
        return
    if not force and is_synced(path):
        return
    adc = _get_adc()
    item = _get_item(adc, path)
    local_path = _ensure_local_path(adc, path)
    for proc_id in _get_all_processids():
        adc.FileClosedWithinRunningProcess(proc_id, local_path)
    adc.SyncFiles([item.Id])