Azure 管道 运行 Qt 应用程序

Azure Pipeline run Qt application

Simpe Qt 应用程序 'untitled.exe':

#include <QCoreApplication>
#include <QtCore>

void parseCmd(const QCoreApplication &app)
{
   QCommandLineParser parser;
   parser.addHelpOption();
   parser.addVersionOption();
   parser.process(app);
}

int main(int argc, char *argv[])
{
   QCoreApplication a(argc, argv);
   QCoreApplication::setApplicationVersion("1.0");

   parseCmd(a);

   return a.exec();
}

输出:

2020-12-15T19:06:08.1133300Z ##[section]Starting: Test code...
2020-12-15T19:06:08.1434531Z ==============================================================================
2020-12-15T19:06:08.1434873Z Task         : Command line
2020-12-15T19:06:08.1435197Z Description  : Run a command line script using Bash on Linux and macOS and cmd.exe on Windows
2020-12-15T19:06:08.1435509Z Version      : 2.178.0
2020-12-15T19:06:08.1436101Z Author       : Microsoft Corporation
2020-12-15T19:06:08.1436429Z Help         : https://docs.microsoft.com/azure/devops/pipelines/tasks/utility/command-line
2020-12-15T19:06:08.1436801Z ==============================================================================
2020-12-15T19:06:09.5889046Z Generating script.
2020-12-15T19:06:09.6545863Z ========================== Starting Command Output ===========================
2020-12-15T19:06:09.7002067Z ##[command]"C:\windows\system32\cmd.exe" /D /E:ON /V:OFF /S /C "CALL "D:\a\_temp\cc51db57-c085-4347-873f-ed28f0e7af53.cmd""
2020-12-15T19:06:09.7240225Z         1 file(s) copied.
2020-12-15T19:06:09.7388204Z  Volume in drive D is Temp
2020-12-15T19:06:09.7389142Z  Volume Serial Number is 405E-826C
2020-12-15T19:06:09.7389470Z 
2020-12-15T19:06:09.7389984Z  Directory of D:\a\s\Release_WIN_x64
2020-12-15T19:06:09.7390270Z 
2020-12-15T19:06:09.7390552Z 12/15/2020  07:06 PM    <DIR>          .
2020-12-15T19:06:09.7392444Z 12/15/2020  07:06 PM    <DIR>          ..
2020-12-15T19:06:09.7393989Z 12/15/2020  07:06 PM    <DIR>          bearer
2020-12-15T19:06:09.7394372Z 12/15/2020  07:06 PM    <DIR>          iconengines
2020-12-15T19:06:09.7394795Z 12/15/2020  07:06 PM    <DIR>          imageformats
2020-12-15T19:06:09.7395287Z 12/08/2020  02:33 PM         3,409,920 libcrypto-1_1-x64.dll
2020-12-15T19:06:09.7395702Z 12/08/2020  02:33 PM           682,496 libssl-1_1-x64.dll
2020-12-15T19:06:09.7399561Z 12/15/2020  07:06 PM            47,104 MainApp-1.0.0.exe
2020-12-15T19:06:09.7400169Z 12/15/2020  07:06 PM           594,944 MaintenanceTool-1.0.0.exe
2020-12-15T19:06:09.7400757Z 12/15/2020  07:06 PM    <DIR>          platforms
2020-12-15T19:06:09.7401416Z 05/11/2020  08:46 AM         5,998,712 Qt5Core.dll
2020-12-15T19:06:09.7401954Z 05/11/2020  08:47 AM         7,085,176 Qt5Gui.dll
2020-12-15T19:06:09.7404188Z 05/11/2020  08:47 AM         1,349,240 Qt5Network.dll
2020-12-15T19:06:09.7404743Z 05/11/2020  03:05 PM           329,848 Qt5Svg.dll
2020-12-15T19:06:09.7405277Z 05/11/2020  08:47 AM         5,516,920 Qt5Widgets.dll
2020-12-15T19:06:09.7405719Z 12/15/2020  07:06 PM    <DIR>          styles
2020-12-15T19:06:09.7406168Z 12/15/2020  07:05 PM            10,240 untitled.exe
2020-12-15T19:06:09.7406588Z               10 File(s)     25,024,600 bytes
2020-12-15T19:06:09.7407293Z                7 Dir(s)  11,920,207,872 bytes free
2020-12-15T19:06:09.8738006Z ##[error]Cmd.exe exited with code '-1073741701'.
2020-12-15T19:06:09.9214918Z ##[section]Finishing: Test code...

我尝试 运行 在 azure 管道中 运行 使用 -v 参数(应该显示版本号)失败 运行。

由于所有 dll 都已到位,应用程序正在崩溃,因为其他应用程序也很相似,例如 'MainApp' 和 'MaintenanceTool' - 使用相同的 'core' 内容。

当我 运行 'MainApp' 或 'MaintenanceTool' - azure 永远等待,停止管道的唯一方法是取消。

奇怪的是我可以编译,但不能 运行 :/

发现问题,这是针对 Azure 管道的。

因为 Qt class QCommandLineParser 使用的 'qApp' 可以是 Core 或 GUI 应用程序(在我的例子中是 QApplication)——当我们 运行 应用程序带有 -v(默认选项)对于 QCommandLineParser)was/is 显示带有版本的 MessageBox(仅显示 GUI 弹出窗口)。

所以当我们在 'command line pipe line' 中使用它时 - 我们无法在 taht 对话框中单击“确定”。

根据 中的代码,我可以使用 QCommandLineParser 来确定 GUI 模式还是 CLI 模式吗? 我做了一些只是印刷版的例子 - 因为这是我的要求:)

#include <QApplication>
#include <QMessageBox>
#include <iostream> // For std::
#include <QtCore>

// Use any other flags from cmd ...
struct Options {
   bool version = false;
};

Options parseCmd()
{
   QCommandLineParser parser;

   // parser.addVersionOption(); DO NOT USE THIS!

   QCommandLineOption showVer("ver", "Show program version.");
   parser.addOption(showVer);

   // Procs args
   parser.process(*qApp);

   // Save data
   Options opts = {};
   opts.version = parser.isSet(showVer);

   return opts;
}

int main(int argc, char *argv[])
{
   std::cout << "Create core app" << std::endl;
   QCoreApplication::setApplicationVersion("1.0");

   // Create base core app
   QScopedPointer<QCoreApplication> app(new QCoreApplication(argc, argv));

   // Parse cmd parameters
   std::cout << "Parse cmd params" << std::endl;
   Options opt = parseCmd();

   // If only display version
   if(opt.version)
   {
      std::cout << "Display version" << std::endl;
      std::cout << qApp->applicationVersion().toStdString() << std::endl;
   } else
   {
      std::cout << "Run in gui mode" << std::endl;
      // Reset app to GUI mode
      app.reset();
      app.reset(new QApplication(argc, argv));
   }

   //
   if(qobject_cast<QApplication*>(qApp))
   {
      std::cout << "Show QMessageBox" << std::endl;
      // Create any GUI stuff here
      QMessageBox::information(nullptr, "Hello", "Hello, World!");
   }
   else
   {
      std::cout << "Send quit message" << std::endl;
      // As we run QCoreApplication only for parsing cmd params ...
      QMetaObject::invokeMethod(qApp, "quit", Qt::QueuedConnection);
   }

   //
   return app->exec();
}

我们还需要在项目文件中添加一行:'''CONFIG += console'''

QT       += core gui widgets
CONFIG   += console
TEMPLATE =  app
SOURCES  += main.cpp

以及我们如何在命令行中 'show' 版本 ;)