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 batch file and getting finished signal

Executing batch file and getting finished signal

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 696 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.
  • L Offline
    L Offline
    lukutis222
    wrote on last edited by lukutis222
    #1

    Hello. I have batch file that is used for flashing external micrcocontrollers (ESP32). The batch file contents:

    tools\esptool.exe -p COM33 -b 921600 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 bins\flash_image.bin
    

    As you can see from above, it is using esptool.exe that I have in the tools folder.

    I need to execute this command batch file via QT and receive finished signal. I try 3 different methods:

    METHOD 1:

    void MainWindow::on_flash_button_clicked()
    {
        QStringList arguments;
        QProcess process;
        connect(&process, &QProcess::errorOccurred, this, &MainWindow::processError);
        connect(&process, &QProcess::finished, this, &MainWindow::flash_finished);
    
    
        arguments << "/C"<<"start"<<"bats\\esp32_flash2.bat";
        process.setArguments(arguments);
        process.setProgram("cmd.exe");
        qDebug() << process.program() << " " << process.arguments();
        process.start();
      
    }
    

    When I click button to start my script, nothing happens and I get the following error:

    "cmd.exe"   QList("/C", "start", "bats\\esp32_flash2.bat")
    QProcess: Destroyed while process ("cmd.exe") is still running.
    error enum val =  QProcess::Crashed 
    flash finished 
    

    METHOD 2: (identical to method 1 except using startDetached() instead of start()

    
    //works but not getting flash finished signal
    void MainWindow::on_flash2_button_clicked()
    {
        QStringList arguments;
        QProcess process;
    
        connect(&process, &QProcess::errorOccurred, this, &MainWindow::processError);
        connect(&process, &QProcess::finished, this, &MainWindow::flash_finished);
    
        arguments << "/C"<<"start"<<"bats\\esp32_flash2.bat";
        process.setArguments(arguments);
        process.setProgram("cmd.exe");
        qDebug() << process.program() << " " << process.arguments();
        process.startDetached();
        
    }
    

    The above method opens a cmd instance and starts flashing the device. This works but I have 2 issues with this method:

    1. It starts a cmd instance and I do not want user to see this. I want everything to happen "behind the curtains".
    2. It does not generate a finished signal when the flashing is complete.

    METHOD 3 (removed "start" from QProcess arguments)

    void MainWindow::on_flash3_button_clicked()
    {
        QStringList arguments;
        QProcess process;
    
        connect(&process, &QProcess::errorOccurred, this, &MainWindow::processError);
        connect(&process, &QProcess::finished, this, &MainWindow::flash_finished);
    
        arguments <<"/C"<<"bats\\esp32_flash2.bat";
        process.setArguments(arguments);
        process.setProgram("cmd.exe");
        qDebug() << process.program() << " " << process.arguments();
        process.startDetached();
    
    }
    

    This method works better than the method 2 because it does not start external cmd instance.
    I have 1 issue with above method:

    1. It does not generate QProcess::finished signal when the flashing is complete

    Could someone help me understand how to call batch scripts from QT properly and how to make sure the QProcess::finished gets triggered at the end of batch file execution? I believe I need to use process.start() rather than startDetached() but I cannot get it to work using start(), I always get QProcess::Crashed error. Thanks in advance.

    JonBJ 1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on last edited by ChrisW67
      #2

      Your QProcess instance needs to exist longer than the process it is managing.

      By default, Windows start does not wait for its child process to complete.

      In Method 1 QProcess:start() runs start, which returns ('finishes') quickly, and then the QProcess is destroyed while the command shell(s) involved are still running. This generates the overt warning.

      Method 2 suffers the same problem except you moved the quick return into the Qt side.

      Method 3 after the batch file process is launched detached the QProcess instance is destroyed and thus does not exist to send a finished() signal.

      Make the a QProcess instance or a QProcess* used to track a heap-allocated QProcess a member variable.

      1 Reply Last reply
      1
      • L lukutis222

        Hello. I have batch file that is used for flashing external micrcocontrollers (ESP32). The batch file contents:

        tools\esptool.exe -p COM33 -b 921600 --before default_reset --after hard_reset --chip esp32  write_flash --flash_mode dio --flash_size detect --flash_freq 80m 0x0 bins\flash_image.bin
        

        As you can see from above, it is using esptool.exe that I have in the tools folder.

        I need to execute this command batch file via QT and receive finished signal. I try 3 different methods:

        METHOD 1:

        void MainWindow::on_flash_button_clicked()
        {
            QStringList arguments;
            QProcess process;
            connect(&process, &QProcess::errorOccurred, this, &MainWindow::processError);
            connect(&process, &QProcess::finished, this, &MainWindow::flash_finished);
        
        
            arguments << "/C"<<"start"<<"bats\\esp32_flash2.bat";
            process.setArguments(arguments);
            process.setProgram("cmd.exe");
            qDebug() << process.program() << " " << process.arguments();
            process.start();
          
        }
        

        When I click button to start my script, nothing happens and I get the following error:

        "cmd.exe"   QList("/C", "start", "bats\\esp32_flash2.bat")
        QProcess: Destroyed while process ("cmd.exe") is still running.
        error enum val =  QProcess::Crashed 
        flash finished 
        

        METHOD 2: (identical to method 1 except using startDetached() instead of start()

        
        //works but not getting flash finished signal
        void MainWindow::on_flash2_button_clicked()
        {
            QStringList arguments;
            QProcess process;
        
            connect(&process, &QProcess::errorOccurred, this, &MainWindow::processError);
            connect(&process, &QProcess::finished, this, &MainWindow::flash_finished);
        
            arguments << "/C"<<"start"<<"bats\\esp32_flash2.bat";
            process.setArguments(arguments);
            process.setProgram("cmd.exe");
            qDebug() << process.program() << " " << process.arguments();
            process.startDetached();
            
        }
        

        The above method opens a cmd instance and starts flashing the device. This works but I have 2 issues with this method:

        1. It starts a cmd instance and I do not want user to see this. I want everything to happen "behind the curtains".
        2. It does not generate a finished signal when the flashing is complete.

        METHOD 3 (removed "start" from QProcess arguments)

        void MainWindow::on_flash3_button_clicked()
        {
            QStringList arguments;
            QProcess process;
        
            connect(&process, &QProcess::errorOccurred, this, &MainWindow::processError);
            connect(&process, &QProcess::finished, this, &MainWindow::flash_finished);
        
            arguments <<"/C"<<"bats\\esp32_flash2.bat";
            process.setArguments(arguments);
            process.setProgram("cmd.exe");
            qDebug() << process.program() << " " << process.arguments();
            process.startDetached();
        
        }
        

        This method works better than the method 2 because it does not start external cmd instance.
        I have 1 issue with above method:

        1. It does not generate QProcess::finished signal when the flashing is complete

        Could someone help me understand how to call batch scripts from QT properly and how to make sure the QProcess::finished gets triggered at the end of batch file execution? I believe I need to use process.start() rather than startDetached() but I cannot get it to work using start(), I always get QProcess::Crashed error. Thanks in advance.

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

        @lukutis222
        As @ChrisW67 has written. Note that to wait for finished you will want to use QProcess::start() and not startDetached(). Also do not try to run the Windows start command, that will prevent waiting for finished on the program it runs.

        1 Reply Last reply
        1
        • L Offline
          L Offline
          lukutis222
          wrote on last edited by
          #4

          @ChrisW67
          @JonB

          Thanks both for responses. I managed to get it working by creating process on the heap as you have suggested.

          void MainWindow::on_flash3_button_clicked()
          {
              QStringList arguments;
              //QProcess* process;
              QProcess * process = new QProcess();
              connect(process, &QProcess::errorOccurred, this, &MainWindow::processError);
              connect(process, &QProcess::finished, this, &MainWindow::flash_finished);
          
              arguments <<"/C"<<"bats\\esp32_flash2.bat";
              process->setArguments(arguments);
              process->setProgram("cmd.exe");
              qDebug() << process->program() << " " << process->arguments();
              process->start();
          
          }
          

          Since I have a habit of never using heap (I always allocate everything on stack), I would like to know if there is anything else I need to be aware of when using this method. Do I need to manually free the memory once I receive the finished signal?

          JonBJ 1 Reply Last reply
          0
          • L lukutis222

            @ChrisW67
            @JonB

            Thanks both for responses. I managed to get it working by creating process on the heap as you have suggested.

            void MainWindow::on_flash3_button_clicked()
            {
                QStringList arguments;
                //QProcess* process;
                QProcess * process = new QProcess();
                connect(process, &QProcess::errorOccurred, this, &MainWindow::processError);
                connect(process, &QProcess::finished, this, &MainWindow::flash_finished);
            
                arguments <<"/C"<<"bats\\esp32_flash2.bat";
                process->setArguments(arguments);
                process->setProgram("cmd.exe");
                qDebug() << process->program() << " " << process->arguments();
                process->start();
            
            }
            

            Since I have a habit of never using heap (I always allocate everything on stack), I would like to know if there is anything else I need to be aware of when using this method. Do I need to manually free the memory once I receive the finished signal?

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

            @lukutis222 said in Executing batch file and getting finished signal:

            Do I need to manually free the memory once I receive the finished signal?

            Yes!

            If you don't like heap-allocating the QProcess you could make it a member variable of e.g. MainWindow? Then you wouldn't have to think about deleting it.

            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