You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过system()函数启停程序及WinCC OA相关技术咨询

WinCC OA控制脚本中system()启动Node.js模拟器的进程管理与输出问题

问题描述

我在WinCC OA控制台的控制脚本里使用system()函数启动一款基于Node.js开发的模拟器应用:

  1. 启动控制脚本后模拟器可正常运行,但停止控制脚本时,模拟器仍会继续运行,希望能在停止脚本时自动终止该任务;
  2. 在WinCC OA外部运行模拟器时,输出内容会实时显示在命令行中;但用system()捕获stdout到变量时,只能等模拟器结束、system()调用返回后才能访问变量,且在WinCC OA中运行时完全看不到输出,希望能显示命令行窗口或实现实时输出。

附上当前使用的代码:

main()
{
  string path = getPath(MSG_REL_PATH);
  dyn_string splittedPath = strsplit(path, "/");
  string mainProjectPath;

  // 获取主项目路径
  for (int i = 1; i <= (dynlen(splittedPath) - 2); i++)
  {
    mainProjectPath += (splittedPath[i] + "/");
  }

  // 拼接模拟器路径
  string sPath = mainProjectPath + "simulator";

  DebugN("simulatorPath " + sPath);

  string stdOut, stdErr;
  mapping options = makeMapping("program", "D:\\Programs\\nodejs\\npm.cmd",  "arguments", makeDynString("start"),  "workingDir", sPath);
  int pid = system(options, stdOut, stdErr);
  
}

解决方案

问题1:停止控制脚本时终止启动的模拟器进程

WinCC OA的system()默认启动独立进程,不会随控制脚本终止而自动结束。可以通过保存进程PID+注册脚本退出回调的方式解决:

  1. 声明全局变量存储PID(避免局部变量在脚本运行中被销毁):

    int g_simulatorPid;
    
  2. 在main()中启动进程时赋值PID:

    g_simulatorPid = system(options, stdOut, stdErr);
    
  3. 注册脚本退出处理函数,在脚本停止时终止进程:

    void onScriptExit() {
      if (g_simulatorPid != 0) {
        // 若npm start启动了多层子进程,用taskkill递归终止整个进程树
        string killCmd = "taskkill /F /T /PID " + intToString(g_simulatorPid);
        system(killCmd);
        DebugN("模拟器进程已终止");
      }
    }
    
    main() {
      // 注册退出回调
      registerScriptExitFunction(onScriptExit);
      // ... 原有路径处理和进程启动代码
    }
    

    注:直接调用killProcess(g_simulatorPid)可能只能终止npm进程,无法终止其启动的Node.js子进程,因此推荐用Windows的taskkill /T参数递归终止整个进程树。


问题2:实现实时输出或显示命令行窗口

方法1:弹出命令行窗口运行(直接显示实时输出)

修改system()的options映射,添加showWindow参数设为TRUE,同时不捕获stdout/stdErr,让输出直接显示在弹出的cmd窗口中:

mapping options = makeMapping(
  "program", "D:\\Programs\\nodejs\\npm.cmd",
  "arguments", makeDynString("start"),
  "workingDir", sPath,
  "showWindow", TRUE // 弹出命令行窗口
);
int pid = system(options); // 不捕获输出,让内容实时显示在窗口

这种方式和在WinCC OA外部运行模拟器的效果完全一致,输出会实时展现在弹出的控制台窗口中。

方法2:不弹出窗口,实时捕获输出到WinCC OA控制台

使用WinCC OA的systemAsync()异步函数配合回调,实时读取stdout/stdErr并打印到WinCC OA控制台:

// 实时输出回调
void onSimOutput(string output) {
  DebugN("模拟器实时输出:" + output);
}

// 错误输出回调
void onSimError(string error) {
  DebugN("模拟器错误:" + error);
}

// 进程退出回调
void onSimExit(int exitCode) {
  DebugN("模拟器退出,退出码:" + intToString(exitCode));
}

main() {
  // ... 原有路径处理代码
  mapping options = makeMapping(
    "program", "D:\\Programs\\nodejs\\npm.cmd",
    "arguments", makeDynString("start"),
    "workingDir", sPath
  );
  int pid = systemAsync(options, onSimOutput, onSimError, onSimExit);
}

systemAsync()会在进程运行过程中持续触发onSimOutput和onSimError回调,实现实时输出的效果。


内容的提问来源于stack exchange,提问作者svh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:33:11