Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. executing cmd.exe with some console application
Forum Updated to NodeBB v4.3 + New Features

executing cmd.exe with some console application

Scheduled Pinned Locked Moved Unsolved General and Desktop
20 Posts 4 Posters 3.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Robert M.
    QProcess process;
    QString cmd = QString::fromStdString("cmd.exe");
    QStringList params;
    params << "/C" << "pause";
    process.start(cmd, params);
    

    This code does not display console window. Why? How to make it correct?
    I use Win10.

    JonBJ Online
    JonBJ Online
    JonB
    wrote on last edited by JonB
    #4

    @Robert-M said in executing cmd.exe with some console application:

    This code does not display console window. Why?

    What about it makes you think it should display any kind of console window? It will not.

    How to make it correct?

    I believe (I am not a Windows Qt user) you must do one of:

    • In .pro add CONFIG += console. But that will display a console the whole time, and I don't think is compatible with GUI application.

    • You probably want to look into the Windows AllocConsole() function.

    • IIRC, use Windows CreateProcess... calls, instead of QProcess, which do allow console creation.

    • Find a "terminal" which will execute your command. For example under Linux you could run it by invoking xterm -e ...; I don't know about Windows.

    1 Reply Last reply
    0
    • R Offline
      R Offline
      Robert M.
      wrote on last edited by
      #5

      I know how to do it in Linux, my solution works fine in Linux. I do not know how to do it in Windows.

      JonBJ 2 Replies Last reply
      0
      • R Robert M.

        I know how to do it in Linux, my solution works fine in Linux. I do not know how to do it in Windows.

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #6

        @Robert-M
        What is your solution which works in Linux then?

        I suggested the ways you can do it in Windows. Sorry if that's not what you wanted to hear or if Windows/cmd does not work the way you would like it to.

        R 1 Reply Last reply
        0
        • R Robert M.

          I know how to do it in Linux, my solution works fine in Linux. I do not know how to do it in Windows.

          JonBJ Online
          JonBJ Online
          JonB
          wrote on last edited by JonB
          #7

          @Robert-M
          There may be a way to get Qt's QProcess to control the arguments being passed to Windows CreateProcess, which I said you will need to do in order to have it create a new console for the sub-process. Have a look at void QProcess::setCreateProcessArgumentsModifier(QProcess::CreateProcessArgumentModifier modifier) and the discussion at typedef QProcess::CreateProcessArgumentModifier. I have not tried it, but in the sample code there I see

          args->flags |= CREATE_NEW_CONSOLE;
          

          Try that, and then try it for your pause command. You may, or may not, need the cmd /k it shows there rather than cmd /c, depending what you want to happen about the console when your command finishes.

          Note that what you will want/expect to happen to the console after your command executes will depend on what command you are issuing. Likely not the same for echo versus pause.

          1 Reply Last reply
          1
          • R Offline
            R Offline
            Robert M.
            wrote on last edited by
            #8

            I tried (according to Qt documentation):

            QProcess process;
            process.setCreateProcessArgumentsModifier([] (QProcess::CreateProcessArguments *args)
               {
                   args->flags |= CREATE_NEW_CONSOLE;
                   args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
                   args->startupInfo->dwFlags |= STARTF_USEFILLATTRIBUTE;
                   args->startupInfo->dwFillAttribute = BACKGROUND_BLUE | FOREGROUND_RED
                                                      | FOREGROUND_INTENSITY;
               });
            process.start("C:\\Windows\\System32\\cmd.exe", QStringList() << "/c" << "pause");
            

            but it does not display console window. Using /k instead of /c does not help.

            1 Reply Last reply
            0
            • JonBJ JonB

              @Robert-M
              What is your solution which works in Linux then?

              I suggested the ways you can do it in Windows. Sorry if that's not what you wanted to hear or if Windows/cmd does not work the way you would like it to.

              R Offline
              R Offline
              Robert M.
              wrote on last edited by
              #9

              In Linux I call process->start(...) with xterm.

              R 1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #10

                Did you try using startDetached instead of start?

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                R JonBJ 2 Replies Last reply
                2
                • VRoninV VRonin

                  Did you try using startDetached instead of start?

                  R Offline
                  R Offline
                  Robert M.
                  wrote on last edited by
                  #11

                  You are great! Thanks a lot!

                  process.setProgram("C:\\Windows\\System32\\cmd.exe");
                  process.setArguments({"/k", "pause"});
                  qint64 pid;
                  process.startDetached(&pid);
                  

                  displays console with pause text.

                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    Did you try using startDetached instead of start?

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by
                    #12

                    @VRonin said in executing cmd.exe with some console application:

                    Did you try using startDetached instead of start?

                    Interesting. But why does that allow the new console where start does not? :)

                    1 Reply Last reply
                    0
                    • VRoninV Offline
                      VRoninV Offline
                      VRonin
                      wrote on last edited by VRonin
                      #13

                      start is designed explicitly to avoid popping new consoles up, see the comment block in https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess_win.cpp.html#550

                      we [...] do not want console tools launched from a GUI app to create new console windows (behavior consistent with UNIX).

                      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                      ~Napoleon Bonaparte

                      On a crusade to banish setIndexWidget() from the holy land of Qt

                      JonBJ 2 Replies Last reply
                      2
                      • VRoninV VRonin

                        start is designed explicitly to avoid popping new consoles up, see the comment block in https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess_win.cpp.html#550

                        we [...] do not want console tools launched from a GUI app to create new console windows (behavior consistent with UNIX).

                        JonBJ Online
                        JonBJ Online
                        JonB
                        wrote on last edited by JonB
                        #14

                        @VRonin said in executing cmd.exe with some console application:

                        see the comment block in https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess_win.cpp.html#550

                        // However, we also do not want console tools launched from a GUI app to
                        // create new console windows (behavior consistent with UNIX).
                        DWORD dwCreationFlags = (GetConsoleWindow() ? 0 : CREATE_NO_WINDOW);
                        

                        Well no wonder then :) But we don't get told this is a difference from startDetached() :) I will try to remember this for the future.

                        P.S.
                        Isn't just lovely to see UNIX written? :)

                        1 Reply Last reply
                        0
                        • VRoninV VRonin

                          start is designed explicitly to avoid popping new consoles up, see the comment block in https://code.woboq.org/qt5/qtbase/src/corelib/io/qprocess_win.cpp.html#550

                          we [...] do not want console tools launched from a GUI app to create new console windows (behavior consistent with UNIX).

                          JonBJ Online
                          JonBJ Online
                          JonB
                          wrote on last edited by JonB
                          #15

                          @VRonin said in executing cmd.exe with some console application:

                          start is designed explicitly to avoid popping new consoles u

                          Not tested, but can't you change this in the same way in your setCreateProcessArgumentsModifier() anyway, just add the first line to whatever you want:

                          args->flags &= ~CREATE_NO_WINDOW;  // switch that *off*
                          args->flags |= CREATE_NEW_CONSOLE;
                          ...
                          

                          ?

                          If this works for start() like the OP says it apparently is working for startDetached() the advantage is you can still wait for sub-process completion, if desired.

                          1 Reply Last reply
                          2
                          • VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #16

                            Indeed you can!

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            1 Reply Last reply
                            1
                            • R Robert M.

                              In Linux I call process->start(...) with xterm.

                              R Offline
                              R Offline
                              Robert M.
                              wrote on last edited by VRonin
                              #17

                              I have one problem in Linux. I invoke xterm with dirtyphp.sh script:

                                  QProcess process;
                                  QString exec = QString::fromStdString(terminal);
                                  QStringList params;
                                  params << "-hold" << "-e"; 
                                  bool p0 = true;
                                  for (std::string s : explode(std::string(" "), dirtyphp_command)) {
                                      if (p0) {
                                          std::string s0 = str_replace("'", "", s) + ".sh";
                                          params << s0.c_str();
                                          p0 = false;
                                      } else {
                                          params << str_replace("'", "", s).c_str();
                                      }
                                  }
                                  process.start(exec, params);
                                  process.waitForFinished();
                              

                              In dirtyphp.sh script I am waiting for CTRL+C at the end:

                              d=`dirname $0`
                              if [ "$d" = "" ]
                              then
                              	d="."
                              fi
                              $d/dirtyphp $@
                              echo 'Hit CTRL+C';
                              while true 
                              do
                              	sleep 1
                              done 
                              

                              The problem is that xterm window is closed automatically without waiting for CTRL+C and the user cannot browse output produced by program dirtyphp in xterm window. I do not understand why - the loop and the end of dirtyphp.sh script should be infinite.

                              JonBJ 1 Reply Last reply
                              0
                              • R Robert M.

                                I have one problem in Linux. I invoke xterm with dirtyphp.sh script:

                                    QProcess process;
                                    QString exec = QString::fromStdString(terminal);
                                    QStringList params;
                                    params << "-hold" << "-e"; 
                                    bool p0 = true;
                                    for (std::string s : explode(std::string(" "), dirtyphp_command)) {
                                        if (p0) {
                                            std::string s0 = str_replace("'", "", s) + ".sh";
                                            params << s0.c_str();
                                            p0 = false;
                                        } else {
                                            params << str_replace("'", "", s).c_str();
                                        }
                                    }
                                    process.start(exec, params);
                                    process.waitForFinished();
                                

                                In dirtyphp.sh script I am waiting for CTRL+C at the end:

                                d=`dirname $0`
                                if [ "$d" = "" ]
                                then
                                	d="."
                                fi
                                $d/dirtyphp $@
                                echo 'Hit CTRL+C';
                                while true 
                                do
                                	sleep 1
                                done 
                                

                                The problem is that xterm window is closed automatically without waiting for CTRL+C and the user cannot browse output produced by program dirtyphp in xterm window. I do not understand why - the loop and the end of dirtyphp.sh script should be infinite.

                                JonBJ Online
                                JonBJ Online
                                JonB
                                wrote on last edited by JonB
                                #18

                                @Robert-M
                                If you think it's even executing that script and getting as far as the while true loop (goodness knows), put some debugging into the loop, like an echo or a read.

                                Or maybe put a set -x at the start of the script so you can see what is going on?

                                1 Reply Last reply
                                0
                                • R Offline
                                  R Offline
                                  Robert M.
                                  wrote on last edited by
                                  #19

                                  I changed the loop to the following:
                                  while true
                                  do
                                  echo -n _
                                  done
                                  I see no underscores in xterm window.
                                  Qt reports:
                                  QProcess: Destroyed while process ("xterm") is still running.
                                  I modified waitForFinish call:
                                  process.waitForFinish(-1);
                                  and now I can see underscores.
                                  Problem solved.

                                  JonBJ 1 Reply Last reply
                                  0
                                  • R Robert M.

                                    I changed the loop to the following:
                                    while true
                                    do
                                    echo -n _
                                    done
                                    I see no underscores in xterm window.
                                    Qt reports:
                                    QProcess: Destroyed while process ("xterm") is still running.
                                    I modified waitForFinish call:
                                    process.waitForFinish(-1);
                                    and now I can see underscores.
                                    Problem solved.

                                    JonBJ Online
                                    JonBJ Online
                                    JonB
                                    wrote on last edited by JonB
                                    #20

                                    @Robert-M
                                    bool QProcess::waitForFinished(int msecs = 30000) means that waitForFinished() only waits up to 30 seconds, and then your QProcess process; goes out of scope and causes the error. If your sub-process takes longer that is why you wanted waitForFinished(-1).

                                    1 Reply Last reply
                                    0

                                    • Login

                                    • Login or register to search.
                                    • First post
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved