CAM API
  • CAM API
v3.0.3
Search Results for

    Show / Hide Table of Contents

    ENCY CAM IPC API — Application Domain

    This document covers the out-of-process (IPC) Application interfaces used when controlling a ENCY CAM instance from an external process (e.g., a standalone executable, a Prime shell, or another tool).

    IPC interfaces mirror the in-process CAMAPI interfaces but add TExecuteContext parameters to every call that crosses the process boundary.


    Table of Contents

    1. ICamIpcApplication — remote application instance
    2. ICamIpcListApplication — managing multiple instances
    3. IPC application event handlers
    4. ICamIpcPaths — system path properties
    5. IIpcExtensionManager — managing extensions over IPC
    6. ICamIpcUtilityManager / ICamIpcUtilityInfo
    7. IIpcLogger — logging from an IPC context
    8. ICamIpcXmlPropPointer / ICamIpcXmlPropArray — XML property tree

    ICamIpcApplication

    The remote proxy for a single running ENCY CAM process. All methods that read from or write to the remote application take a TExecuteContext so the IPC layer can route the call and track the result.

    Connection management properties

    Property Type Description
    ProcessId integer OS process ID of the ENCY instance
    IsAlive boolean Whether the instance is running and responding
    IsBusy boolean Whether the instance is currently processing an IPC request
    IsWindowed boolean Whether the instance has a visible window
    ExecutablePath string Path to the ENCY executable
    MainForm ICamIpcApplicationMainForm* Proxy for the main window (available immediately without context)
    MachinesLibrary ICamIpcMachinesLibrary* Machine library manager
    MacroManager ICamIpcMacroManager* Macro system manager
    Paths ICamIpcPaths* System path information
    UserTechOperationList ICamIpcUserTechOperationList* User tech operation list

    Connection lifecycle methods

    Method Description
    WaitForStarted(timeout, out ResultStatus) Blocks until the ENCY instance is ready or the timeout (ms) elapses
    Close(asyncMode, out ResultStatus) → IListString* Sends a close request; returns any error strings
    StartAsyncWork(out ResultStatus) Starts the local IPC server to receive async callbacks from ENCY
    StopAsyncWork(out ResultStatus) Stops the local IPC server
    GetPort(out ResultStatus) → integer Returns the TCP/named-pipe port the IPC server listens on
    RegisterWorkingThread(threadHandle, out ResultStatus) Registers a thread to process async IPC commands
    UnregisterWorkingThread(threadHandle, out ResultStatus) Unregisters a working thread

    Remote application methods (require TExecuteContext)

    Method Description
    GetLogFilePath(ctx) → string Path to the ENCY log file
    GetActiveProject(ctx) → ICamIpcProject* Returns the active project proxy
    GetExtensionManager(ctx) → IIpcExtensionManager* Returns the extension manager proxy
    GetUtilityManager(ctx) → ICamIpcUtilityManager* Returns the utility manager proxy
    GetMachiningToolsManager(ctx) → ICamIpcMachiningToolsManager* Returns the tools manager proxy
    GetPLMManager(ctx) → IIpcPLMManager* Returns the PLM manager proxy
    GetMainFormTimeOut(timeout) → ICamIpcApplicationMainForm* Returns the main form proxy, waiting up to timeout ms
    OpenProject(fileName, addToReOpen, ctx) Opens a project file
    SaveCurrentProject(fileName, ctx) Saves the current project
    ExportCurrentProject(targetFileName, overwrite, ctx) Exports the project with all snapshots
    GetMainWorkMode(ctx) → TMainWorkMode Returns the current work mode
    SetMainWorkMode(workMode, ctx) Sets the work mode
    SetActiveProjectMachine(machineInfo, ctx) Assigns a machine to the current project
    OpenProjectFromPLM(plmItemId, connectionId, ctx) Opens a PLM project

    Event handling over IPC

    IPC events require a listener object in addition to the handler:

    CreateListener(ctx) → ICamIpcEventListener*
    GetDefaultListener() → ICamIpcEventListener*
    RegisterHandler(handlerIdent, handler, listener, ctx)
    UnregisterHandler(handlerIdent, ctx)
    

    A listener encapsulates the transport channel that delivers events from ENCY back to the external process. Typically you use GetDefaultListener() for the default channel and CreateListener(ctx) when you need an isolated channel per module.

    Usage pattern

    // Obtain an ICamIpcApplication proxy (from ICamIpcSingletons or Prime):
    var ctx = new TExecuteContext();
    app.WaitForStarted(10_000, out var status);
    if (status.Code == TResultStatusCode.rsError)
        throw new Exception(status.Description);
    
    // Open a project:
    app.OpenProject(@"C:\projects\part.encam", addToReOpen: false, ref ctx);
    
    // Read the work mode:
    var mode = app.GetMainWorkMode(ref ctx);
    
    // Get active project:
    var project = app.GetActiveProject(ref ctx);
    

    ICamIpcListApplication

    A collection of ICamIpcApplication instances. Returned by the singletons or Prime to enumerate all running ENCY processes.

    Count: integer
    Get(index, ctx) → ICamIpcApplication*
    GetByProcessId(processId, ctx) → ICamIpcApplication*
    Add(item)
    RemoveByProcessId(processId)
    RemoveAt(index)
    Clear()
    

    IPC Application Event Handlers

    These are the IPC equivalents of the in-process application event handlers. They are registered via ICamIpcApplication.RegisterHandler.

    Interface Method Fires when
    ICamIpcHandlerApplicationAfterLoad ApplicationAfterLoad(handlerIdent, application) ENCY has finished loading
    ICamIpcHandlerApplicationBeforeClose ApplicationBeforeClose(handlerIdent, application) ENCY is about to close
    ICamIpcHandlerApplicationAfterClose ApplicationAfterClose(handlerIdent) ENCY has closed
    ICamIpcHandlerApplicationNewProject ApplicationNewProject(handlerIdent) A new empty project is being created
    ICamIpcHandlerApplicationActiveProjectChanged ApplicationActiveProjectChanged(handlerIdent, newProject) The active project reference changed
    ICamIpcHandlerApplicationBeforeLoadProject ApplicationBeforeLoadProject(handlerIdent, project) A project is about to be loaded
    ICamIpcHandlerApplicationAfterLoadProject ApplicationAfterLoadProject(handlerIdent, project) A project has finished loading
    ICamIpcHandlerApplicationBeforeSaveProject ApplicationBeforeSaveProject(handlerIdent, project) The current project is about to be saved
    ICamIpcHandlerApplicationAfterSaveProject ApplicationAfterSaveProject(handlerIdent, project) Any project has been saved
    ICamIpcHandlerApplicationUpdateStartProgress ApplicationUpdateStartProgress(handlerIdent, caption, percent) Startup progress updated
    ICamIpcHandlerApplicationUpdateProcessState ApplicationUpdateProcessState(handlerIdent, caption, percent) Running process progress updated

    ICamIpcPaths

    Exposed directly on ICamIpcApplication.Paths. Contains the same path properties as the in-process ICamApiPaths, plus a unique instance identifier.

    Methods and properties

    Member Description
    GetInstanceId() → string Unique identifier of this ENCY instance in IPC messages
    MainProgramFolder Root installation folder
    InterpretersFolder NC interpreter files
    ModelsFolder Default models folder
    NCProgramsFolder Default NC programs folder
    ExamplesFolder Example projects
    PostprocessorsFolder Postprocessor files
    OperationsFolder XML files with additional operation info
    MachinesFolder Machine definition files
    LibrariesFolder Help library files
    ConfigFolder Configuration files
    UserExtensionsFolder User-installed extensions
    TryReducePath(fullPath) → string Converts an absolute path to a portable CAM-variable form
    TryUnfoldPath(reducedPath) → string Expands a portable CAM-variable path to an absolute path

    IIpcExtensionManager

    The IPC proxy for the ENCY extension manager. All methods take a TExecuteContext.

    Library and storage management

    Method Description
    RegisterLibrary(storageType, descFilePath, ctx) → IIpcExtensionLibraryInfo* Registers an extension library from a JSON description file
    UnRegisterLibrary(libraryPath, ctx) Removes a library registration
    RegisterLibraryFromFolder(storageType, folderPath, out needReload, ctx) → IIpcExtensionLibraryInfo* Finds the settings.json in folderPath, copies the library into ENCY's own folder, then registers it. needReload reports that a restart is required to pick it up
    GetPendingDeletionLibraries() → IIpcListExtensionLibraryInfo* Libraries whose unregistration could not complete because the DLL was locked (a _del_ cleanup artifact is still on disk). Stale entries are dropped automatically, so a non-empty result means a real leftover. No ctx parameter
    ReloadStorage(storageType, ctx) Re-reads a storage layer
    GetLibrariesInfo() → IIpcListExtensionLibraryInfo* Lists all registered libraries
    GetLibraryInfo(extensionTypeId, ctx) → IIpcExtensionLibraryInfo* Gets library info by extension type ID
    FreeLibrary(libraryPath, ctx) Unloads all extensions from a library

    Extension enable/disable

    Method Description
    GetLibraryDisabled(storageType, libraryPath, ctx) → boolean Whether the library is disabled for a storage layer
    GetExtensionDisabled(storageType, extensionIdent, ctx) → boolean Whether a specific extension is disabled
    SetLibraryDisabled(storageType, libraryPath, disabled, ctx) Enables or disables a library for a storage layer
    SetExtensionDisabled(storageType, extensionIdent, disabled, ctx) Enables or disables an extension
    GetFieldInherited(storageType, entityIdent, field, ctx) → boolean Checks if a field value is inherited
    SetFieldInherited(storageType, entityIdent, field, ctx) Resets a field to use the inherited value
    GetLibraryLoaded(libraryPath, ctx) → boolean Whether a library is currently loaded

    Extension discovery and instantiation

    Method Description
    GetExtensionTypeGroups(ctx) → IListString* Lists all available extension type group names
    GetExtensionTypeInfo(extensionTypeId, ctx) → IIpcExtensionTypeInfo* Gets type metadata for one extension
    GetExtensionTypeInfos(extensionTypeGroup, ctx) → IIpcListExtensionTypeInfo* Lists all extension types in a group
    GetExtensionTypeInfosFromLibrary(libraryPath, ctx) → IIpcListExtensionTypeInfo* Lists all extensions declared in a library DLL
    CreateExtension(extensionTypeId, ctx) → IIpcExtension* Creates (loads) a new extension instance
    CreateExtensions(extensionTypeIds, ctx) → IIpcListExtension* Creates multiple extensions (semicolon-separated IDs)
    GetExtension(extensionInstanceId, ctx) → IIpcExtension* Returns an existing extension instance by ID
    GetSingletonExtension(extensionTypeId, ctx) → IIpcExtension* Returns the single shared instance of a singleton extension by its type id; narrow to a concrete interface with AsInstanceOf on the client
    FreeExtension(extensionInstanceId, ctx) Unloads an extension instance

    Extension settings

    Named key/value settings owned by an extension type and stored by the extension manager, for deployment-provided configuration (server URL, license key, shared folder). Resolution is a cascade, independent of the disabled/inherited machinery above:

    stCurrentUser → stAllUsers → stDealer → stSystem → manifest default
    
    Method Description
    GetExtensionSetting(extensionTypeId, key, out found, ctx) → string Effective value after the whole cascade; found is false when nothing defines the key
    GetExtensionSettingSourceLevel(extensionTypeId, key, out found, out fromDefault, ctx) → TStorageType Where the effective value came from. When fromDefault is true the value is the manifest default and the returned tier is meaningless
    GetExtensionSettingKeys(extensionTypeId, ctx) → IListString* Union of all keys defined across every tier and the defaults
    SetExtensionSetting(storageType, extensionTypeId, key, value, ctx) Write a value into one tier and persist it
    RemoveExtensionSetting(storageType, extensionTypeId, key, ctx) Drop the key from one tier so the next tier down (or the default) becomes effective again

    ExtensionManagerHelper wraps all five and throws on rsError, so no TExecuteContext is passed by the caller. GetExtensionSetting folds the found flag into the return value — it returns null when nothing defines the key:

    using var emCom = appCom.ExtensionManager();
    const string extensionTypeId = "My.Company.MyExtension";
    
    var url = emCom.GetExtensionSetting(extensionTypeId, "serverUrl");
    if (url == null)
        throw new Exception("The 'serverUrl' setting is not configured for this installation");
    
    var level = emCom.GetExtensionSettingSourceLevel(
        extensionTypeId, "serverUrl", out var found, out var fromDefault);
    
    if (found && !fromDefault && level == TStorageType.stAllUsers)
    {
        // machine-wide value — override it for this user only
        emCom.SetExtensionSetting(TStorageType.stCurrentUser, extensionTypeId, "serverUrl", url);
    }
    
    // back to the inherited value
    emCom.RemoveExtensionSetting(TStorageType.stCurrentUser, extensionTypeId, "serverUrl");
    
    // enumerate everything this extension is configured with
    using var keysCom = emCom.GetExtensionSettingKeys(extensionTypeId);
    

    Writing to a tier that has no storage in this installation (stDebugMode outside a debug session) fails instead of silently doing nothing. A key marked secret is kept in memory for the session only and never written to disk — the calls look identical, but the value is gone after a restart.

    Settings are keyed by extension type id alone, so they can be written and read for an id that is not registered — handy for provisioning an extension before it is installed. TStorageType comes from the CAMAPI.Extensions namespace even in IPC clients.

    The in-process equivalents live on IExtensionManager and have no helper wrappers — see ../api/entry-points.md.

    Storage type enum — TStorageType

    The configuration tier a library, flag, or setting belongs to. Tiers are merged in priority order — the highest-priority tier carrying a value wins.

    Value Priority Scope Writable
    stSystem Lowest Machine-wide, shipped with the installation No
    stDealer 2 Machine-wide, provisioned by the distributor No
    stAllUsers 3 Machine-wide Yes
    stCurrentUser 4 Current user Yes
    stDebugMode 5 Current user, only while a debug session provides the folder Yes
    stTestMode Highest Automated test runs Yes

    Macro build support

    Method Description
    GetApiVersion(ctx) → string Current CAM Open API version — use as the macro .NET SDK version
    GetApiDependencies(ctx) → IListString* Reference assemblies a built macro must compile against — use as the macro .NET References

    Helper (ExtensionManagerHelper): emCom.GetApiVersion(), emCom.GetApiDependencies(). These feed the macro builder's .NET language settings (see ICamIpcMacroManager below) — without them the generated macro project cannot resolve CAMAPI types.


    ICamIpcMacroManager

    IPC mirror of ICamApiMacroManager — list and run existing macros, and create new ones. See docs/api/application.md for the full conceptual model; this section gives the IPC helper surface. (Writing the body of a macro itself is covered in docs/macros.)

    using var macroMgrCom = appCom.MacroManager();   // ComWrapper<ICamIpcMacroManager>
    

    Listing and running

    int count = macroMgrCom.Count();
    using var info = macroMgrCom.GetMacroById("MyMacro");   // or macroMgrCom.GetMacro(index)
    macroMgrCom.Execute("MyMacro", paramsJson);             // paramsJson "" = recorded defaults
    

    paramsJson is a per-step override dictionary: {"stepIndex": {"key": "value"}}.

    Helpers (MacroManagerHelper):

    Helper Description
    Count() Number of macros
    GetMacro(i) / GetMacroById(id) → ComWrapper<ICamIpcMacroInfo> Macro metadata
    Execute(id, paramsJson = "") Run a macro
    CreateMacroInstance() / AddMacro(info) / RemoveMacro(id, deleteSources) Manage macros
    GetMacroBuilder() → ComWrapper<ICamIpcMacroBuilder> Build macros (below)
    NotifyMacroStep(i) / OpenInEditor(info) Step notify / open source

    ICamIpcMacroInfo

    MacroInfoHelper: getters Id(), Caption(), Description(), MacroPath(), ExecutablePath(), LanguageId(), ExecuteExtensionId(), StepCount(), GetStep(i); setters SetId(v) … SetExecuteExtensionId(v) (for the CreateMacroInstance → fill → AddMacro flow).

    Discovering overridable step parameters

    MacroStepInfoHelper: DisplayText(), ParamCount(), GetParam(i), GroupCaption(). MacroStepParamHelper: Key(), LabelText(), ParamType() (TMacroCommandParamType), Required(), DefaultValue(), ValuesString().

    Creating a macro programmatically

    using var builderCom = macroMgrCom.GetMacroBuilder();
    using var cmdsCom    = builderCom.GetCommandsManager();
    
    cmdsCom.Start();
    using (var cd = cmdsCom.CreateCommandData(TMacroCommandType.mctCreateOperation))
    {
        cd.SetStr("OperationType", "HoleMachiningOp");
        cd.SetStr("TypeCaption",   "Hole machining");
        cd.SetStr("Name",          "Op1");
        cmdsCom.RegisterCommand(cd);
    }
    cmdsCom.Stop();
    
    using var main = builderCom.CreateMainSettings();
    main.SetId("MyMacro");
    main.SetCaption("My macro");
    main.SetCreateOperations(true);
    main.SetOutputFolder(outputFolder);
    main.SetExecuteExtensionId("Extension.MacroRunner.Dotnet");
    
    using var lang = builderCom.CreateLanguageSettings("dotnet");
    lang.SetTargetFramework("net8.0-windows");
    // CRITICAL: SDKVersion + References — without them the generated .csproj cannot resolve
    // CAMAPI types (CS0246). Source both from the extension manager.
    using var emCom = appCom.ExtensionManager();
    lang.SetSDKVersion(emCom.GetApiVersion());
    lang.SetReferences(emCom.GetApiDependencies());
    
    string sourcePath = builderCom.CreateMacro(main, lang);
    string builtPath  = builderCom.Save();
    

    Alternative — capture the current project instead of authoring commands:

    cmdsCom.AddStrategyState();   // or AddMachineState() / AddWorkpieceState() / AddRecognizeFeature()
    

    Command field-key schema (authoritative, at runtime)

    Get the schema provider (ICamIpcMacroCommandSchema) from the commands manager; GetFlatCommand returns an ICamIpcMacroCommandFieldList (indexed list of field descriptors). The Fields() helper reads it in one pass:

    using var schemaCom = cmdsCom.GetCommandSchema();
    using var fieldsCom = schemaCom.GetFlatCommand(TMacroCommandType.mctCreateOperation);
    foreach (var f in fieldsCom.Fields())
    {
        // f.Key (string), f.FieldType (TMacroCommandParamType), f.Required (bool)
    }
    

    Variant (model-item) commands — some commands accept different key sets depending on a discriminator field (e.g. mctSetWorkpiecePrimitive, whose keys depend on the item class). GetFlatCommand returns the common keys including the discriminator; pass a discriminator value to GetClassItemCommand for the variant keys:

    using var boxCom = schemaCom.GetClassItemCommand(
        TMacroCommandType.mctSetWorkpiecePrimitive, "TBoxLinkItem");
    // discriminators: "TBoxLinkItem", "TCylLinkItem", "TStockLinkItem", "TAutoLinkItem"
    

    An empty list (GetCount() == 0) means the command type / discriminator has no documented schema yet.

    Command bag and helpers

    • MacroCommandSchemaHelper: GetFlatCommand(type), GetClassItemCommand(type, discriminator) → ComWrapper<ICamIpcMacroCommandFieldList> (on the provider from GetCommandSchema).
    • MacroCommandFieldListHelper: GetCount(), GetKey(i), GetFieldType(i), GetRequired(i), and Fields() to read the whole list at once.
    • MacroCommandDataHelper: CommandType(), GetStr/GetInt/GetFloat/GetBool(key), SetStr/SetInt/SetFloat/SetBool(key, value) (setters work only on a bag from CreateCommandData).
    • Language "dotnet" → .NET macro (TargetFramework/SDKVersion/References via MacroBuilderLanguageSettingsHelper); "script" → script macro.
    • List-bearing commands (which the scalar bag cannot hold) have dedicated typed methods on the commands manager: RegisterSetDriveFaceItemProperties, RegisterAddFixture, RegisterSetFixtureItemStock/Color/Caption.

    ICamIpcUtilityManager / ICamIpcUtilityInfo

    ICamIpcUtilityManager

    GetListInfo(ctx) → ICamIpcListUtilityInfo*
    Execute(uid, ctx)
    Reload()
    GetUtilsUiInfoJson(ctx) → string
    

    ICamIpcUtilityInfo — read-only utility descriptor

    GetUid(ctx) → string
    GetUiVisible(ctx) → boolean
    GetName(ctx) → string
    GetHint(ctx) → string
    GetIconPath(ctx) → string
    

    Usage example

    var utilMgr = app.GetUtilityManager(ref ctx);
    var list    = utilMgr.GetListInfo(ref ctx);
    int count   = list.Count();
    for (int i = 0; i < count; i++)
    {
        var info = list.Get(i);
        string uid  = info.GetUid(ref ctx);
        string name = info.GetName(ref ctx);
        Console.WriteLine($"{uid}: {name}");
    }
    
    // Execute by UID:
    utilMgr.Execute("MyUtility.UID", ref ctx);
    

    IIpcLogger

    Writes log entries into the ENCY log stream from an external process.

    Methods

    Method Description
    log(event: LogItem) Writes a fully-populated log entry
    debug(message) Writes a leDebug entry
    verbose(message) Writes a leVerbose entry
    info(message) Writes a leInfo entry
    head(message) Writes a leHead entry
    warning(message) Writes a leWarning entry
    error(message) Writes a leError entry
    IsEventTypeActive(eventType) → boolean Whether entries of that severity are currently being recorded
    Notify(eventType, message, title) Shows a user-visible notification in the host application, in addition to logging

    Use IsEventTypeActive to skip building an expensive message that would be discarded:

    if (logger.IsEventTypeActive(TLogEventType.leDebug))
        logger.debug(BuildExpensiveDump());
    

    Notify is not just a log write — it surfaces a toast/message to the user, so reserve it for things they must actually see.

    LogItem is the same struct used in the in-process API — see api/application.md.

    Moved and retyped. IIpcLogger now lives in CAMIPC.IpcInteraction (it was in CAMIPC.Helper), and IIpcInteraction.Logger is now typed IIpcLogger* instead of IExtensionLogger*. Client code that assigned an IExtensionLogger to that property, or imported the interface from CAMIPC.Helper, must be updated.

    // Obtain via ICamIpcSingletons:
    IIpcLogger logger = /* from singletons */;
    
    logger.info("IPC session started");
    logger.warning("Connection latency is high");
    logger.error("Failed to load project");
    
    logger.log(new LogItem {
        EventType = TLogEventType.leInfo,
        message   = "structured entry",
        srcModule = "MyTool"
    });
    

    ICamIpcXmlPropPointer / ICamIpcXmlPropArray

    IPC proxies for navigating the ENCY XML-property tree (the internal data model). These are the IPC equivalents of IST_XMLPropPointer / IST_XMLPropArray.

    ICamIpcXmlPropPointer

    Member Type Description
    GetInstanceId() → string — IPC instance identifier
    Flt[name] double RW Read/write a float child property by name
    Int[name] integer RW Read/write an integer child property by name
    Bol[name] boolean RW Read/write a boolean child property by name
    Str[name] WideString RW Read/write a string child property by name
    Ptr[name] ICamIpcXmlPropPointer* R Navigate to a child pointer property
    Arr[name] ICamIpcXmlPropArray* R Navigate to a child array property
    CStr[name] WideString R Calculated (formula-expanded) string value
    // Example: read cutting speed from a tech-operation property tree
    double speed = op.Ptr["CuttingConditions"].Flt["CuttingSpeed"];
    
    // Write a parameter:
    op.Ptr["CuttingConditions"].Flt["FeedRate"] = 0.15;
    

    ICamIpcXmlPropArray

    Member / Method Description
    TopItem RW — index of the last item (count − 1)
    Itm[index] R — get item by index
    AddItem(item) → integer Appends an item; returns the new index
    Insert(item, index) Inserts before index
    Delete(index) Removes item at index
    ExtractItem(index) → ICamIpcXmlPropPointer* Removes and returns item at index
    Clear() Removes all items
    IndexOf(item) → integer Returns the index of an item, or −1
    CreateNewItem(id) → ICamIpcXmlPropPointer* Creates a new typed item (if allowed by schema)
    // Iterate over an array property:
    var arr = root.Arr["Operations"];
    for (int i = 0; i <= arr.TopItem; i++)
    {
        var item = arr.Itm[i];
        string name = item.Str["Name"];
        Console.WriteLine(name);
    }
    
    In this article