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
Forum Updated to NodeBB v4.3 + New Features

Executing batch file and getting finished signal

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 719 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 5 Dec 2022, 08:25 last edited by lukutis222 12 May 2022, 08:33
    #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.

    J 1 Reply Last reply 5 Dec 2022, 08:58
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on 5 Dec 2022, 08:54 last edited by ChrisW67 12 May 2022, 08:54
      #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
        5 Dec 2022, 08:25

        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.

        J Offline
        J Offline
        JonB
        wrote on 5 Dec 2022, 08:58 last edited by JonB 12 May 2022, 08:59
        #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 8 Dec 2022, 12:47 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?

          J 1 Reply Last reply 8 Dec 2022, 12:55
          0
          • L lukutis222
            8 Dec 2022, 12:47

            @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?

            J Offline
            J Offline
            JonB
            wrote on 8 Dec 2022, 12:55 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

            2/5

            5 Dec 2022, 08:54

            • Login

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