Skip to content

C++ DLL Quickstart

Target: Windows x64, native C++ host. Include heimer_oem.h, link HeimerCleanOem.lib, and deploy HeimerCleanOem.dll with the reviewed runtime folder. The DLL uses Windows WinHTTP and current-user DPAPI; no Python interpreter is loaded into your application's process.

1. Start the headless runtime

For a development session:

HeimerCleanOemRuntime.exe --partner-id sample-vendor --protocol-id OEM-CONTRACT-001

The runtime prints its API version and the absolute path to session.dpapi. Its port is selected automatically unless you supply --port. The descriptor contains a protected per-process session, not a license or an administrator token.

Run the host and SDK under the same Windows user. State is isolated by partner and protocol under that user's HeimerCleanOEM directory. One OEM runtime can own a Windows user profile at a time. The pilot must be deployed separately from the normal desktop runtime; optimization rejects a detected desktop/worker conflict.

The runtime requires a non-elevated interactive user and refuses administrator/SYSTEM service execution. If your application has an elevated component, supervise the OEM runtime from its standard-user component; do not turn it into a privileged local broker. Service/elevation support requires a separate reviewed contract.

In your application, launch the runtime from your trusted installation directory using CreateProcessW with CREATE_NO_WINDOW. Keep its handle and supervise it. Read its startup descriptor path through redirected output or your installation configuration. No Windows service or startup task is installed automatically.

2. Connect and read status

#include "heimer_oem.h"
#include <cstdio>

void ReadStatus(const wchar_t* sessionPath) {
    HeimerOemClient client = nullptr;
    if (HeimerOem_Open(sessionPath, &client) != HC_OEM_OK) {
        // Start/check your runtime, then open its current descriptor again.
        return;
    }

    char* json = nullptr;
    uint32_t httpStatus = 0;
    uint32_t result = HeimerOem_Request(
        client, "GET", "/v1/status", nullptr, &json, &httpStatus);
    if (json) {
        // Parse this UTF-8 JSON into your own UI model.
        std::puts(json);
        HeimerOem_Free(json);
    }
    HeimerOem_Close(client);
}

Calls are synchronous: make network/engine requests from a worker thread, not your UI event thread. Always free response buffers with HeimerOem_Free, including JSON error responses. Close a client only after its outstanding calls have finished.

3. Activate the agreed OEM license

The stock pilot supports automatic activation from a prepaid OEM pool. The installer provides pool configuration once; the end user needs no HeimerClean account or key-entry screen. The manual company-license path below remains available for compatibility.

Call POST /v1/license/activate with:

{"license_key":"YOUR-OEM-LICENSE-KEY"}

Your license must contain signed OEM permission for the same partner ID and protocol reference used at startup. Optimization also needs licensed temporary-file and memory cleanup features. An ordinary desktop key cannot enable OEM execution by changing a local configuration flag.

Keep company/customer license keys out of source code and logs. Privileged license issuance credentials belong on the licensing operator's server and must never be included in the DLL or partner installer.

4. Start a job and show its result

A read-only integration check:

{"operation":"temp.scan","idempotency_key":"scan-request-0001"}

An optimization request, after your UI obtains customer/deployment consent:

{"operation":"optimize","idempotency_key":"cleanup-request-0001","consent":true}

Send the JSON as POST /v1/jobs. Save the returned id, then poll GET /v1/jobs/{id} until the state is succeeded, failed or cancelled. Display the returned summary in your own UI. Reuse the same idempotency key only when retrying the same request; a new user action needs a new key.

HeimerOem_Request returns HC_OEM_HTTP_ERROR for a non-2xx response. Inspect httpStatus and the JSON error.code; a transport error is different from a license or busy response.

5. Stop safely

Wait until work is finished, then send {} to POST /v1/shutdown. Busy shutdown is refused. Closing the DLL client releases that client only; it does not terminate the runtime. Do not forcibly terminate a running cleanup job.

After a runtime restart, close the old client and reopen the new session descriptor. Keep DLL/runtime files in a protected installation directory, use absolute trusted DLL paths, and avoid current-directory DLL searching.

Next: Local API · Webhooks · Compatibility