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

Qt应用如何从批处理脚本捕获触发事件并安全停止(Win10)

Win10下Qt应用响应UPS断电关机触发的安全停止方案

一、Win10系统触发事件的两种方式

1. UPS管理软件自定义脚本(推荐)

多数UPS厂商的管理工具(如APC PowerChute、施耐德UPS监控软件)支持配置断电后即将关机前执行自定义命令,直接将你的批处理脚本路径填入对应设置项即可。这种方式能精准关联UPS断电事件,避免误触发。

2. Windows组策略关机脚本

如果没有专用UPS管理软件,可通过系统组策略配置关机触发脚本:

  • 按Win+R输入gpedit.msc打开本地组策略编辑器
  • 导航至计算机配置 > Windows 设置 > 脚本(关机/开机)
  • 双击「关机」,点击「添加」选择你的批处理脚本文件

注意:组策略脚本为系统级执行,需确保脚本拥有足够权限(可右键脚本选「以管理员身份运行」测试)。

二、批处理触发Qt应用事件的简洁方法

方法1:发送自定义Windows消息(推荐)

编写批处理脚本,通过工具向Qt应用进程发送自定义消息,需先准备一个轻量的SendMessage.exe工具(可通过C语言编译一个极简程序,核心调用SendMessage API):

@echo off
:: 获取Qt应用的进程ID
for /f "tokens=2" %%i in ('tasklist /fi "imagename eq YourQtApp.exe" /fo table /nh') do set APP_PID=%%i
:: 发送自定义消息(WM_USER+123为自定义消息标识)
SendMessage.exe %APP_PID% 0x0401+122 0 0
:: 可选:延时等待安全流程完成
timeout /t 15 /nobreak >nul

方法2:创建信号文件(跨平台友好)

批处理中创建一个临时文件作为触发信号:

@echo off
:: 创建信号文件
echo. > "C:\ProgramData\shutdown_trigger.signal"
:: 延时等待安全流程完成
timeout /t 15 /nobreak >nul

三、Qt应用监听外部事件实现

方式1:监听自定义Windows消息

在Qt主窗口类中重写nativeEvent函数,捕获自定义消息:

#include <windows.h>
#include <QMainWindow>

// 定义自定义消息标识(WM_USER+123,避免与系统消息冲突)
const UINT WM_SHUTDOWN_TRIGGER = WM_USER + 123;

class MainWindow : public QMainWindow
{
    Q_OBJECT
protected:
    bool nativeEvent(const QByteArray &eventType, void *message, long *result) override
    {
        MSG *winMsg = static_cast<MSG*>(message);
        if (winMsg->message == WM_SHUTDOWN_TRIGGER) {
            // 执行硬件安全停止流程
            safeShutdownHardware();
            *result = 0;
            return true;
        }
        return QMainWindow::nativeEvent(eventType, message, result);
    }

private:
    void safeShutdownHardware()
    {
        // 这里编写关闭硬件、保存状态的逻辑
        // 例如:关闭电机、保存配置文件等
    }
};

方式2:监听信号文件变化

使用Qt的QFileSystemWatcher监控信号文件的创建:

#include <QFileSystemWatcher>
#include <QFile>
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr) : QMainWindow(parent)
    {
        QFileSystemWatcher *watcher = new QFileSystemWatcher(this);
        const QString triggerPath = "C:/ProgramData/shutdown_trigger.signal";
        // 先确保文件不存在,避免启动时误触发
        QFile::remove(triggerPath);
        watcher->addPath(triggerPath);

        connect(watcher, &QFileSystemWatcher::fileChanged, this, [=](const QString &path){
            // 执行安全停止流程
            safeShutdownHardware();
            // 删除信号文件,避免重复触发
            QFile::remove(path);
            // 重新添加监控(文件删除后需重新添加)
            watcher->addPath(path);
        });
    }

private:
    void safeShutdownHardware()
    {
        // 硬件安全停止逻辑
    }
};

四、关键注意事项

  • 权限匹配:批处理和Qt应用需拥有操作硬件的足够权限,建议以管理员身份运行
  • 延时设置:根据安全停止流程的耗时,在批处理或UPS软件中设置足够的延时(如10-30秒),确保流程完成后再关机
  • 测试验证:手动执行批处理脚本,确认Qt应用能正确触发安全停止流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 00:57:28