Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QProcess startDetached() run ps1 script



  • Hi all!
    I have one problem while using QT Process. I need to start the PowerShell script from my QT widget application. All my scripts are located in appfolder/Scripts. So in my qt program, I create a function to run the script. Its look like that:

    void MainWindow::runCommand(QString command)
    {
        QProcess process;
        process.setWorkingDirectory(QDir::currentPath()+"/Scripts/");
        QString cmd = "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe";
        QStringList arguments{command};
    
        process.start(cmd, arguments);
        while(process.waitForFinished()==true) delay_MSec(100);
        delay_MSec(1000);
    }
    

    As "command" i use QString with script name (reboot.ps1)
    My delay function looks like that:

    void MainWindow::delay_MSec(unsigned int msec)
    {
        QTime _Timer = QTime::currentTime().addMSecs(msec);
        while( QTime::currentTime() < _Timer )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
    

    Everything working ok but if I using only process.start() app GUI freezing. So I read somewhere on the internet to use function startDetached(). But now I have a problem, when I using this function my app not freezing (that's so good!) but the app doesn't wait for finished. It runs the first script and waits 1000ms. Past this one second app run the next script. I need to app wait for the finish first script.

    Ps1 script looks like that:

    If ( Test-path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" ) 
    { 
        $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
        New-Item $ScriptDir\state.txt
        Set-Content $ScriptDir\state.txt '1';
    } 
    else 
    { 
        $ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
        New-Item $ScriptDir\state.txt
        Set-Content $ScriptDir\state.txt '0';
    }
    

    Thank you in advance for your help!


  • Lifetime Qt Champion

    Hi,

    @Piotrek102 said in QProcess startDetached() run ps1 script:

    while(process.waitForFinished()==true) delay_MSec(100);

    You are blocking the event loop and thus freeze your application.

    You should take advantage of the asynchronous nature of QProcess in order to run your script without blocking your GUI. You'll be able to chain your script properly as well.



  • @SGaist
    Thank you for your response.
    So can you tell me the correct way to run a PowerShell script using e.g. startDetached () in conjunction with waitforfinished ()? When I use startDetached () my program does not wait for the end of the process. This is why I used the start () function.
    thank you very much!



  • @Piotrek102 set 1000ms delay at the top of your second script.


  • Lifetime Qt Champion

    You can't. The suggestion is that you use the finished signal to trigger the next command.



  • @JoeCFD
    The program will then wait a total of 2 seconds, run the script, wait one second in the RunCommand () function, and then wait another second. My point is to make the program wait for the script to finish. Sometimes I use scripts that require up to 10 minutes of work. Therefore, the program has to wait for the script to do its job.

    @SGaist
    I will try your method but I think I will need time to understand it thoroughly. Thanks for the idea!


  • Lifetime Qt Champion

    Make a list of the commands your want to execute and then each time finished is triggered, get the next command to execute and so on until the list is empty.



  • @SGaist
    Great idea! I change the code and everything should work. I close the topic and if I encounter any other problems I will create a new one.
    @SGaist , @JoeCFD Thank you for your help!