如何隐藏在 Qt 应用程序中打开的 Windows 终端?

Posted

技术标签:

【中文标题】如何隐藏在 Qt 应用程序中打开的 Windows 终端?【英文标题】:How to hide windows Terminal opened in Qt app? 【发布时间】:2019-05-08 10:27:09 【问题描述】:

首先,有类似的问题,但我认为这是一个不同的问题,因为 Windows 终端仅在我调用 system() 时出现,而不是在应用程序启动时出现。

我有一个带有 Qt 用 C++ 编写的 gui 程序,并使用 MinGW 编译器在带有.pro 文件的 qmake 中构建。操作系统是虚拟盒子中的 Windows 10。

我在 Ubuntu 中编写了代码,它可以按预期工作(根本看不到操作系统终端),但现在我正在 Windows 中对其进行测试。我的问题是,每当我在代码中调用system() 或类似名称来执行另一个程序(假设在后台)时,Windows 都会在我的 gui 前面打开一个 cmd 终端。我的程序中有很多这样的调用,因此在运行时有很多这些窗口会弹出和消失。

我将 main() 设置为 WinMain() 并从 qmake 配置中删除了控制台,但这并没有显示任何效果。

我的.pro 文件(已删除 cmets):

QT       += core gui

CONFIG -= console
QMAKE_CXXFLAGS += -std=c++11

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = regionfind-gui
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
        regionfind.cpp \
        sagacmd.cpp

HEADERS += \
        regionfind.h \
        sagacmd.h \
        processingsteps.h
FORMS += \
        regionfind.ui

RESOURCES += \
        images.qrc

构建命令(从 QtCreator 生成):

C:\Qt\Qt5.12.3\5.12.3\mingw73_64\bin\qmake.exe C:\Users\dev\Documents\regionfind-gui\regionfind-gui.pro -spec win32-g++ && C:/Qt/Qt5.12.3/Tools/mingw730_64/bin/mingw32-make.exe qmake_all

如何摆脱这些终端窗口?当命令没有任何输出时,它们不会打开,但我无法抑制一般输出或类似输出,因为在某些情况下,我使用以下代码存储输出并将其打印到我的 gui 中:

array<char, 128> buffer;
string result = getDescription(getStep()) + command + "\n";
unique_ptr<FILE, decltype(&pclose) > pipe(popen(command.c_str(), "r"), pclose);
if(!pipe) throw std::runtime_error("popen() failed");
while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr)  
 result += checkOutput(buffer.data());
 getGui()->txtOutput->append(QString::fromStdString(removeNewlineAtEnd(buffer.data())));
 getGui()->txtOutput->repaint();
 cout << buffer.data() << flush;;

示例:system("mkdir C:\\Users\dev\\Documents\\testfolder") 不打开窗口(无输出),但 system("driverquery") 可以。

【问题讨论】:

抱歉转贴。我删除了我的第一次尝试,因为我认为错误在其他地方,但它不是,所以现在再次发布。 是为所有保持打开的命令打开一个终端还是每个命令打开一个终端? @nwp 每次调用都会打开一个新终端,一旦命令终止,它们就会关闭 转换到QProcess 可能是有意义的,这样您就可以知道您生成的进程会发生什么,而不必猜测它们是否成功。它还绕过了控制台问题。 我去看看,谢谢。 【参考方案1】:

您可以使用QProcess 类来做到这一点:

    QObject *parent;
    ...
    QString program = "driverquery";

    QProcess *myProcess = new QProcess(parent);
    myProcess->start(program);
    if (myProcess->waitForStarted(-1)) 
        while(myProcess->waitForReadyRead(-1)) 
            getGui()->txtOutput->append( myProcess->readAllStandardOutput() );
       
    
    // else report error or whatever

在使用命令应用程序的情况下,您可以执行以下操作:

    QObject *parent;
    ...
    QString program = "driverquery";

    QProcess *myProcess = new QProcess(parent);
    QString command = QString("cmd.exe %1 \"%2 \"").arg(" /C ").arg(program);
    myProcess->start(command);
    if (myProcess->waitForStarted(-1)) 
        while(myProcess->waitForReadyRead(-1)) 
            getGui()->txtOutput->append( myProcess->readAllStandardOutput() );
       
    
    // else report error or whatever

【讨论】:

我在摆弄它,目前它在start(program) 崩溃,可能是因为我还没有掌握父对象的窍门。我会进一步尝试并让你知道。使用QProcess::execute(...) 的静态执行有效,但缺少输出的返回。 我把QObject *parent;放在哪里是为了说明使用你的父对象,也许是QMainWindow。所以你必须初始化new QProcess(&lt;yourQObject*&gt;) driverquery.exe 是一个控制台应用程序。默认情况下,通过CreateProcessW 使用重定向到管道的标准 I/O 运行它仍将分配一个控制台并创建一个窗口,除非采取措施来抑制控制台窗口(即 CREATE_NO_WINDOW 创建标志)或使用处理STARTUPINFOQProcess 在重定向标准 I/O 时是否默认抑制或隐藏控制台窗口? 我进行了编辑以向您展示如何使用控制台 cmd.exe @Gasteizko 它可以工作,但它仍然会打开命令窗口。现在它们是空的而不是显示输出,但它们仍然存在。

以上是关于如何隐藏在 Qt 应用程序中打开的 Windows 终端?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Python 在 Windows 上打开隐藏的应用程序?

如何在 Qt 中打开和最小化外部应用程序到系统托盘

qt如何在windows上打开usb摄像头?

如何在 Qt 中检测 Windows 事件?

如何在启用自动隐藏的 Windows 中检测任务栏的高度和方向?

Eric IDE,Qt 文件对话框:显示隐藏文件