QProcess: finished() signal not emitted running Powershell script
In my application, I convert an Excel spreadsheet into a tab-delimited file. This is done by running a Windows Powershell script into a QProcess.
My problem is that the finished() signal is never emitted, although the conversion is done successfully. And yes, I receive stateChanged() signal.
Powershell script
param ([string]$ent = $null, [string]$sal = $null)
$xlCSV = -4158 #value for tab delimited file
$Excel = New-Object -Com Excel.Application
$Excel.visible = $False
$Excel.displayalerts=$False
$b = $Excel.Workbooks.Open($ent)
$b.SaveAs($sal,$xlCSV)
$Excel.quit()
exit 0 #tested without exit, with exit and with exit 0
Header:
Code:
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QProcess>
#include <QDebug>
namespace Ui {
class Dialog;
}
{
Q_OBJECT
public:
explicit Dialog
(QWidget *parent
= 0);
~Dialog();
private:
Ui::Dialog *ui;
private slots:
void procFinish(int estat);
void procState
(QProcess::ProcessState estat
);
};
#endif // DIALOG_H
Source:
Code:
#include "dialog.h"
#include "ui_dialog.h"
ui(new Ui::Dialog)
{
ui->setupUi(this);
QString program
= "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe";
params << "-File" << "C:/Garsineu/ps_excel.ps1" << "-ent" << "C:/Garsineu/PROVAGALATEA.xls" << "-sal" << "C:/Garsineu/PROVAGALATEA.tab";
connect(proces, SIGNAL(finished(int)), this, SLOT(procFinish(int)));
connect(proces,
SIGNAL(stateChanged
(QProcess::ProcessState)),
this,
SLOT(procState
(QProcess::ProcessState)));
proces->start(program, params);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::procFinish(int estat)
{
qDebug() << "Finished";
}
void Dialog
::procState(QProcess::ProcessState estat
) {
qDebug() << estat;
}
Although the conversion is successful and the states 1 (Started) and 2 (Running) are shown, the message "Finished" is never displayed.
I also tried to do it synchronously, by waitForFinished () method, which is always timed out.
The application needs to know when the process is complete, to carry out further actions on the converted file.
I appreciate your help. Thank you.
Re: QProcess: finished() signal not emitted running Powershell script
Does the script end/exit if you run it manually in a console window?
Cheers,
_
Re: QProcess: finished() signal not emitted running Powershell script
Take a look at the console output from your program at run time and/or the return value from connect(). It is likely that you are receiving warning that QProcess does not have a signal matching "finished(int)" and that connect() returns false (Qt4) or a QMetaObject::Connection that evaluates as false (Qt5). The signal is QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus)
Re: QProcess: finished() signal not emitted running Powershell script
Quote:
Does the script end/exit if you run it manually in a console window?
Yes, running the script in Powershell console performs conversion and closes the console. I have also tried replacing the last line of script by:
Get-Host.SetShouldExit(0)
Which is supposed provides an exit code.
Quote:
Originally Posted by
ChrisW67
Take a look at the console output from your program at run time and/or the return value from connect(). It is likely that you are receiving warning that QProcess does not have a signal matching "finished(int)" and that connect() returns false (Qt4) or a QMetaObject::Connection that evaluates as false (Qt5). The signal is
QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus)
I changed the connection and slot accordingly:
Code:
connect(proces,
SIGNAL(finished
(int,
QProcess::ExitStatus)),
SLOT(procFinish
(int,
QProcess::ExitStatus)));
void Dialog
::procFinish(int exitC,
QProcess::ExitStatus exitS
) { qDebug() << exitC << exitS;
}
The result of connect evaluates to TRUE. With the same (no) result.
Re: QProcess: finished() signal not emitted running Powershell script
Have you tried connecting to the QProcess' error(QProcess::ProcessError) signal to see if any error occurs?
By the way, your code leaks the QProcess instance (but this does not cause the problem being discussed).
Re: QProcess: finished() signal not emitted running Powershell script
Quote:
Originally Posted by
yeye_olive
Have you tried connecting to the QProcess' error(QProcess::ProcessError) signal to see if any error occurs?
By the way, your code leaks the QProcess instance (but this does not cause the problem being discussed).
I have added the connect and slot to capture the possible error; no errors reported.
Code:
connect(proces,
SIGNAL(error
(QProcess::ProcessError)),
this,
SLOT(procError
(QProcess::ProcessError)));
void Dialog
::procError(QProcess::ProcessError error
) { qDebug() << error;
}
Re: QProcess: finished() signal not emitted running Powershell script
What if you exchange your external process call with a different one, e.g. running notepad or something like that? Do you get the finished signal when you exit that external program?
Re: QProcess: finished() signal not emitted running Powershell script
Quote:
Originally Posted by
wysota
What if you exchange your external process call with a different one, e.g. running notepad or something like that? Do you get the finished signal when you exit that external program?
I have another application that calls mysqldump to backup and restore the database, and I get finished signal.
Although I don't like, I found a workaround: at the last line of script I write something (e.g. "End") to stdout. Then I test the "end" as follows:
Code:
connect(proces, SIGNAL(readyReadStandardOutput()), this, SLOT(test()));
void Dialog::test() {
qDebug() << proces->readAllStandardOutput(); // "End"
}
I reviewed all documentation I found about Powershell, including my Holy Bible -I mean Windows 7 Resource Kit (paperback) Perhaps that's one of the Microsoft's undocumented quirks... :confused:
Edit: (3 min. later)
I found the solution (no Qt problem). Apparently powershell does not run in the same way from the console or when is called from another program (noninteractive). If I add at end of script:
Get-Process Powershell | Stop-Process
I Stop * really * powershell and get finished signal, with QProcess::ExitStatus = 0.
The slot:
Code:
void Dialog
::procState(QProcess::ProcessState estat
) { qDebug() << estat;
}
now shows the states: 1 (starting), 2 (running) and 0 (not running).
Thanks to all of you for making me think a little longer.
Re: QProcess: finished() signal not emitted running Powershell script
You might also try the "-NonInteractive" argument to the Powershell.exe and see if that allows the exit.