If you work with Moses 3D simulation software and Cloos welding robots, you might encounter an issue where exporting robot programs (.L files) fails silently or throws initialization errors.
Here is a breakdown of why this happens and how to fix it by creating a custom API interceptor wrapper.
The Problem
When exporting a program (e.g., Rohr1), Moses creates a CSV file containing parameters and writes a configuration file named QTIApi.CFG inside C:\Cloos\QTI\:1;C:\Moses\Konfiguration\CLOOS\DRASS\ROB\CFG 2;C:\Moses\MSTEILE\PROGD\Rohr1 3;DE
Moses then triggers the Cloos command-line tool QTIAPI.exe with a single command:
QTIAPI.exe /CMD 5 Rohr1
Instead of generating Rohr1.L, the export fails. Checking the official Cloos log at %ProgramData%\Cloos Schweisstechnik\QTI\QTIAPI.log reveals the following error:
4 /CMD 5 Rohr1 QTI could not be initialized
Root Cause
QTIAPI.exe treats every execution as a stateless, isolated session. When invoked directly with /CMD 5, it does not automatically parse QTIApi.CFG on its own.Before running conversion commands, QTIAPI.exe expects two mandatory setup calls during runtime:
- /cfg 1 "<Robot Configuration Path>" to initialize the system configuration.
- /cfg 2 "<Working Directory Path>" to set where files should be read and written.
Because Moses calls QTIAPI.exe /CMD 5 directly without passing the /cfg flags first, QTIAPI.exe fails to initialize.
The Solution: A C# API Interceptor
To resolve this, rename the original executable to QTIAPI_real.exe and replace QTIAPI.exe with a lightweight custom C# wrapper.When Moses calls QTIAPI.exe /CMD 5 Rohr1, the wrapper intercepts the call and executes the full sequence:
Moses Export
│
▼
QTIAPI.exe (Custom Wrapper)
│
├── 1. Intercepts original parameters
├── 2. Reads and parses QTIApi.CFG
├── 3. Executes: QTIAPI_real.exe /cfg 1 "C:\Moses\Konfiguration\..."
├── 4. Executes: QTIAPI_real.exe /cfg 2 "C:\Moses\MSTEILE\..."
└── 5. Executes: QTIAPI_real.exe /CMD 5 Rohr1
│
▼
QTIAPI_real.exe ──► Successfully generates Rohr1.L
Implementation Steps
Step 1: Rename the Original Binary
Navigate to C:\Cloos\QTI\ and rename QTIAPI.exe to QTIAPI_real.exe.
Step 2: Compile the Wrapper Executable
Open PowerShell on your system and run the following script to compile the wrapper directly into C:\Cloos\QTI\QTIAPI.exe:
$code = @'
using System;
using System.Diagnostics;
using System.IO;
class Program {
static void Main(string[] args) {
string logFile = @"C:\Cloos\QTI\execution_trap.log";
string realExe = @"C:\Cloos\QTI\QTIAPI_real.exe";
string cfgFile = @"C:\Cloos\QTI\QTIApi.CFG";
// Step 1: Log intercepted call
string originalArgs = string.Join(" ", args);
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] Intercepted call: " + originalArgs + "\r\n");
if (!File.Exists(realExe)) {
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] ERROR: QTIAPI_real.exe not found.\r\n");
return;
}
// Step 2: Read and parse QTIApi.CFG
if (File.Exists(cfgFile)) {
string[] lines = File.ReadAllLines(cfgFile);
foreach (string line in lines) {
if (string.IsNullOrWhiteSpace(line)) continue;
string[] parts = line.Split(';');
if (parts.Length >= 2) {
string id = parts[0].Trim();
string path = parts[1].Trim();
// Step 3 & 4: Issue /cfg 1 and /cfg 2 prior to command execution
if (id == "1" || id == "2") {
string cfgArgs = "/cfg " + id + " \"" + path + "\"";
ExecuteRealExe(realExe, cfgArgs, logFile);
}
}
}
} else {
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] WARNING: QTIApi.CFG not found at " + cfgFile + "\r\n");
}
// Step 5: Execute original command
ExecuteRealExe(realExe, originalArgs, logFile);
}
static void ExecuteRealExe(string exePath, string arguments, string logFile) {
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] Executing: QTIAPI_real.exe " + arguments + "\r\n");
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = exePath;
startInfo.Arguments = arguments;
startInfo.UseShellExecute = false;
using (Process process = Process.Start(startInfo)) {
process.WaitForExit();
}
}
}
'@
Add-Type -TypeDefinition $code -OutputAssembly "C:\Cloos\QTI\QTIAPI.exe" -OutputType ConsoleApplication
Verification
- Run a program export inside Moses.
- Check C:\Cloos\QTI\execution_trap.log to confirm the sequence:
[11.09.2026 17:42:58] Intercepted call: /CMD 5 Rohr1
[11.09.2026 17:42:58] Executing: QTIAPI_real.exe /cfg 1 "C:\Moses\Konfiguration\CLOOS\DRASS\ROB\CFG"
[11.09.2026 17:43:00] Executing: QTIAPI_real.exe /cfg 2 "C:\Moses\MSTEILE\PROGD\Rohr1"
[11.09.2026 17:43:01] Executing: QTIAPI_real.exe /CMD 5 Rohr1
- Check %ProgramData%\Cloos Schweisstechnik\QTI\QTIAPI.log to confirm code 0 (Success):
0 /CMD 5 Rohr1
The target .L parameter file will now be successfully created in your project output folder.