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. QProcess start for mstsc (Remote Desktop) generates finished() signal immediately
Forum Updated to NodeBB v4.3 + New Features

QProcess start for mstsc (Remote Desktop) generates finished() signal immediately

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 4 Posters 759 Views 2 Watching
  • 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.
  • M Offline
    M Offline
    m4kas
    wrote on last edited by m4kas
    #1

    Hi QT forum.
    I'm working on QT application (Windows) that can initiate RDP session with other machine and I'm facing problems with keeping track of started "mstsc" process, as "process->start" call for RDP application immediately generates the "finished()" signal despite the fact, that RDP session is in progress. After RDP session is closed, no additional "finished()" signal occur.

    I'm using next code:

    QProcess *process = new QProcess();
    rdp_processes_list.append(process);
    connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(rdp_process_finished(int, QProcess::ExitStatus)));
    connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(rdp_process_error(QProcess::ProcessError)));
    // start cmd and start mstsc app with /wait key to wait till RDP session is closed.
    process->start("cmd", QStringList() << "/c" << "start" << "/wait" << "mstsc" << "/v" << machine_address);
    // returns true if process started successfully
    process->waitForStarted(-1);
    

    Tried also to do same without cmd involved:

    process->start("mstsc", QStringList() << "/v" << machine_address);
    

    And observe the same result - finished() signal is being generated immediately.

    Passing "cmd /c start /w mstsc /v 172.16.30.113" command into Windows Run menu (Win + R) opens cmd, which opens my RDP session. CMD is closed right after RDP session is closed and this is the expected behavior, which I want to be used by QT.

    Tried also to execute notepad app in same way:

    QProcess *process = new QProcess();
    rdp_processes_list.append(process);
    connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(rdp_process_finished(int, QProcess::ExitStatus)));
    connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(rdp_process_error(QProcess::ProcessError)));
    // start cmd and start mstsc app with /wait key to wait till RDP session is closed.
    process->start("notepad");
    // returns true if process started successfully
    process->waitForStarted(-1);
    

    And in this case I observe another (correct) behavior - finished() signal is being generated right after notepad app is closed, so this may rather be related to mstsc app behavior. Can someone please suggest me what else I can try to fix / workaround it?

    QT version used: 5.13.2

    1 Reply Last reply
    0
    • M Offline
      M Offline
      m4kas
      wrote on last edited by m4kas
      #16

      As mentioned on microsoft forum post, most likely when building 32-bit app (which I was doing), it makes mstsc call of 32-bit version mstsc, which calls the correct 64-bit version and closes original process that was called from QT app.
      Switched my QT project to build 64 bit application and it fixed my problem - now finished() signal is being emitted exactly after RDP session finished.
      @Christian-Ehrlicher @JonB @mrjj thanks for your inputs.
      Issue is solved.

      mrjjM 1 Reply Last reply
      4
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        According to mstsc help /v needs the ip directly -->

        process->start("mstsc", {"/v:"+ machine_address});

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        M 1 Reply Last reply
        1
        • Christian EhrlicherC Christian Ehrlicher

          According to mstsc help /v needs the ip directly -->

          process->start("mstsc", {"/v:"+ machine_address});

          M Offline
          M Offline
          m4kas
          wrote on last edited by
          #3

          @Christian-Ehrlicher
          Thanks for your message.
          Call as you suggested still immediately generates finished() signal.

          JonBJ 1 Reply Last reply
          0
          • M m4kas

            @Christian-Ehrlicher
            Thanks for your message.
            Call as you suggested still immediately generates finished() signal.

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

            @m4kas
            I'm afraid I know nothing about mstsc. But as your code stands, for all I know it might not be on the path of the cmd and we would not know.

            I would start by hooking slots for anything on stdout and particularly on stderr. Windows/DOS has a way of sending you messages on stderr when (failing to) start processes. Note that this is not the same as hooking to error signal. I would also look at what the finished exit status is, just in case there is a clue there. Finally I would also hook onto started & stateChanged signals. That's what I do when debugging odd behaviour!

            M 1 Reply Last reply
            2
            • JonBJ JonB

              @m4kas
              I'm afraid I know nothing about mstsc. But as your code stands, for all I know it might not be on the path of the cmd and we would not know.

              I would start by hooking slots for anything on stdout and particularly on stderr. Windows/DOS has a way of sending you messages on stderr when (failing to) start processes. Note that this is not the same as hooking to error signal. I would also look at what the finished exit status is, just in case there is a clue there. Finally I would also hook onto started & stateChanged signals. That's what I do when debugging odd behaviour!

              M Offline
              M Offline
              m4kas
              wrote on last edited by
              #5

              @JonB
              Thanks for your reply and suggestions.
              finished() signal is being emitted with QProcess::NormalExit exitStatus
              Agree, stderr can contain something useful even though the RDP session with the target machine is being started correctly (at least, from user perspective), so I'll start with trying to read info from stderr and processing started & stateChanged signals.

              JonBJ 1 Reply Last reply
              0
              • M m4kas

                @JonB
                Thanks for your reply and suggestions.
                finished() signal is being emitted with QProcess::NormalExit exitStatus
                Agree, stderr can contain something useful even though the RDP session with the target machine is being started correctly (at least, from user perspective), so I'll start with trying to read info from stderr and processing started & stateChanged signals.

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

                @m4kas
                Do those. Also while I think of it cmd /k ... is the same as cmd /c ... but should keep the Command Prompt window open. Try that to see what it has to show?

                M 1 Reply Last reply
                1
                • JonBJ JonB

                  @m4kas
                  Do those. Also while I think of it cmd /k ... is the same as cmd /c ... but should keep the Command Prompt window open. Try that to see what it has to show?

                  M Offline
                  M Offline
                  m4kas
                  wrote on last edited by
                  #7

                  @JonB
                  With /k finished() signal is not being emitted at all, even after RDP session is closed.

                  1 Reply Last reply
                  0
                  • M Offline
                    M Offline
                    m4kas
                    wrote on last edited by
                    #8

                    Updated my code in next way:

                    void MainWindow::on_tbl_machines_doubleClicked(const QModelIndex &index)
                    {
                        QString machine_address = ui->tbl_machines->model()->index(index.row(), 1).data().toString();
                        QString machine_user = ui->tbl_machines->model()->index(index.row(), 4).data().toString();
                        QString machine_password = ui->tbl_machines->model()->index(index.row(), 5).data().toString();
                    
                        // cmdkey /generic:<servername> /user:<username> /pass:<password>
                        QStringList arg_list= QStringList() << QString("/generic:%1").arg(machine_address) << QString("/user:%1").arg(machine_user) << QString("/pass:%1").arg(machine_password);
                        QProcess::execute("cmdkey", arg_list);
                    
                        QProcess *process = new QProcess();
                        rdp_processes_list.append(process);
                        connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(rdp_process_finished(int, QProcess::ExitStatus)));
                        connect(process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(rdp_process_error(QProcess::ProcessError)));
                        connect(process, SIGNAL(started()), this, SLOT(rdp_process_started()));
                        connect(process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(rdp_process_state_changed(QProcess::ProcessState)));
                        // start cmd and start mstsc app with /wait key to wait till RDP session is closed.
                        process->start("cmd", QStringList() << "/c" << "start" << "/wait" << "mstsc" << "/v" << machine_address);
                        // returns true if process started successfully
                        process->waitForStarted(-1);
                        process->waitForReadyRead(-1);
                        qDebug() << "readAllStandardError:" << process->readAllStandardError();
                        qDebug() << "readAllStandardOutput:" << process->readAllStandardOutput();
                    }
                    
                    /* SLOTS */
                    
                    void MainWindow::rdp_process_started()
                    {
                        qDebug() << "started slot: Process started";
                    }
                    
                    void MainWindow::rdp_process_state_changed(QProcess::ProcessState newState)
                    {
                        qDebug() << "stateChanged slot: Process state changed. New state: " << newState;
                    }
                    
                    void MainWindow::rdp_process_finished(int exitCode, QProcess::ExitStatus exitStatus)
                    {
                        qDebug() << "finished slot: Exit code: " << exitCode << " Exit status: " << exitStatus;
                    }
                    
                    void MainWindow::rdp_process_error(QProcess::ProcessError error)
                    {
                        qDebug() << "error slot: Process error:  " << error;
                    }
                    

                    And got next messages from qDebug():

                    CMDKEY: Credential added successfully.
                    stateChanged slot: Process state changed. New state:  QProcess::Starting
                    stateChanged slot: Process state changed. New state:  QProcess::Running
                    started slot: Process started
                    stateChanged slot: Process state changed. New state:  QProcess::NotRunning
                    finished slot: Exit code:  0  Exit status:  QProcess::NormalExit
                    readAllStandardError: ""
                    readAllStandardOutput: ""
                    

                    So, it does not look mstsc want to say something to me...

                    1 Reply Last reply
                    0
                    • Christian EhrlicherC Offline
                      Christian EhrlicherC Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on last edited by Christian Ehrlicher
                      #9
                      int main(int argc, char* argv[])
                      {
                          QApplication a(argc, argv);
                      
                          QProcess* proc = new QProcess;
                          QObject::connect(proc, &QProcess::started,
                              []() { qDebug() << "started";  });
                          QObject::connect(proc, &QProcess::stateChanged,
                              [](QProcess::ProcessState s) { qDebug() << "stateChanged:" << s;  });
                          QObject::connect(proc, qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
                              [](int c, QProcess::ExitStatus s) { 
                              qDebug() << "finished:" << c << s;
                              QCoreApplication::quit(); 
                          });
                          proc->start("mstsc", { "/v:127.0.0.1" });
                          return a.exec();
                      }
                      
                      -->
                      stateChanged: QProcess::Running
                      started
                      // connect dialog is shown, I kill it
                      stateChanged: QProcess::NotRunning
                      finished: 0 QProcess::NormalExit
                      

                      Works perfectly fine for me. Still don't understand why everyone wants to use cmd /c to run a simple windows executable...

                      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                      Visit the Qt Academy at https://academy.qt.io/catalog

                      M 1 Reply Last reply
                      2
                      • Christian EhrlicherC Christian Ehrlicher
                        int main(int argc, char* argv[])
                        {
                            QApplication a(argc, argv);
                        
                            QProcess* proc = new QProcess;
                            QObject::connect(proc, &QProcess::started,
                                []() { qDebug() << "started";  });
                            QObject::connect(proc, &QProcess::stateChanged,
                                [](QProcess::ProcessState s) { qDebug() << "stateChanged:" << s;  });
                            QObject::connect(proc, qOverload<int,QProcess::ExitStatus>(&QProcess::finished),
                                [](int c, QProcess::ExitStatus s) { 
                                qDebug() << "finished:" << c << s;
                                QCoreApplication::quit(); 
                            });
                            proc->start("mstsc", { "/v:127.0.0.1" });
                            return a.exec();
                        }
                        
                        -->
                        stateChanged: QProcess::Running
                        started
                        // connect dialog is shown, I kill it
                        stateChanged: QProcess::NotRunning
                        finished: 0 QProcess::NormalExit
                        

                        Works perfectly fine for me. Still don't understand why everyone wants to use cmd /c to run a simple windows executable...

                        M Offline
                        M Offline
                        m4kas
                        wrote on last edited by m4kas
                        #10

                        @Christian-Ehrlicher
                        My log when using your code:

                        stateChanged: QProcess::Starting
                        stateChanged: QProcess::Running
                        started
                        stateChanged: QProcess::NotRunning
                        finished: 0 QProcess::NormalExit
                        // RDP session is still in progress
                        

                        Update: when using your code, but not with loopback, but with real remote machine IP . Using with loopback gives error about "could not connect to another console session".

                        1 Reply Last reply
                        0
                        • Christian EhrlicherC Offline
                          Christian EhrlicherC Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by
                          #11

                          I don't know what exactly mstsc is doing but maybe it's detaching the rdp connection internally so the mstsc process is not running when the rdp session is open. Take a look into your running taskmanager/processes when you have an open rdp connection if the mstsc process which you're using for connecting is still there. I would say it's not the case.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          M 1 Reply Last reply
                          2
                          • Christian EhrlicherC Christian Ehrlicher

                            I don't know what exactly mstsc is doing but maybe it's detaching the rdp connection internally so the mstsc process is not running when the rdp session is open. Take a look into your running taskmanager/processes when you have an open rdp connection if the mstsc process which you're using for connecting is still there. I would say it's not the case.

                            M Offline
                            M Offline
                            m4kas
                            wrote on last edited by
                            #12

                            @Christian-Ehrlicher
                            Yes, I can see mstsc.exe in active processes list after QT reported finished() for that process.

                            Christian EhrlicherC 1 Reply Last reply
                            0
                            • M m4kas

                              @Christian-Ehrlicher
                              Yes, I can see mstsc.exe in active processes list after QT reported finished() for that process.

                              Christian EhrlicherC Offline
                              Christian EhrlicherC Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by
                              #13

                              @m4kas said in QProcess start for mstsc (Remote Desktop) generates finished() signal immediately:

                              I can see mstsc.exe in active processes list after

                              And is it exactly this process which was started from Qt? Check the process id.

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              M 1 Reply Last reply
                              1
                              • Christian EhrlicherC Christian Ehrlicher

                                @m4kas said in QProcess start for mstsc (Remote Desktop) generates finished() signal immediately:

                                I can see mstsc.exe in active processes list after

                                And is it exactly this process which was started from Qt? Check the process id.

                                M Offline
                                M Offline
                                m4kas
                                wrote on last edited by
                                #14

                                @Christian-Ehrlicher
                                Good catch!
                                PIDs really differs. Now I will try to understand how track the process, that is being started by mstsc I am starting...

                                mrjjM 1 Reply Last reply
                                0
                                • M m4kas

                                  @Christian-Ehrlicher
                                  Good catch!
                                  PIDs really differs. Now I will try to understand how track the process, that is being started by mstsc I am starting...

                                  mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #15

                                  @m4kas
                                  Hi
                                  I think you are going to need to use the APIs
                                  https://docs.microsoft.com/en-us/windows/win32/termserv/terminal-services-administration

                                  1 Reply Last reply
                                  1
                                  • M Offline
                                    M Offline
                                    m4kas
                                    wrote on last edited by m4kas
                                    #16

                                    As mentioned on microsoft forum post, most likely when building 32-bit app (which I was doing), it makes mstsc call of 32-bit version mstsc, which calls the correct 64-bit version and closes original process that was called from QT app.
                                    Switched my QT project to build 64 bit application and it fixed my problem - now finished() signal is being emitted exactly after RDP session finished.
                                    @Christian-Ehrlicher @JonB @mrjj thanks for your inputs.
                                    Issue is solved.

                                    mrjjM 1 Reply Last reply
                                    4
                                    • M m4kas

                                      As mentioned on microsoft forum post, most likely when building 32-bit app (which I was doing), it makes mstsc call of 32-bit version mstsc, which calls the correct 64-bit version and closes original process that was called from QT app.
                                      Switched my QT project to build 64 bit application and it fixed my problem - now finished() signal is being emitted exactly after RDP session finished.
                                      @Christian-Ehrlicher @JonB @mrjj thanks for your inputs.
                                      Issue is solved.

                                      mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #17

                                      @m4kas
                                      Good digging!

                                      1 Reply Last reply
                                      1

                                      • Login

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