I am developing a Qt application that, among other things, converts an Excel spreadsheet in a text delimited with tab file. This is done by running a Windows Powershell script.
My problem is that the finished() signal from the QProcess is never emitted, although the conversion is done successfully. And yes, I receive stateChanged() signal.
Powershell script (ps_excel.ps1)
(adapted from this question)
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
Qt app header
(For testing, the minimal case is a QDialog without other widgets.)
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
#include <QProcess>
#include <QDebug>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
QProcess *proces;
private:
Ui::Dialog *ui;
private slots:
void procFinish(int estat);
void procState(QProcess::ProcessState estat);
};
#endif // DIALOG_H
Qt app C++
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QString program = "C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe";
QStringList params;
params << "-File" << "C:/Garsineu/ps_excel.ps1" << "-ent" << "C:/Garsineu/PROVAGALATEA.xls" << "-sal" << "C:/Garsineu/PROVAGALATEA.tab";
proces = new QProcess();
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.
Environment
Windows 7 Professional 64 bit
Powershell v1.0 x86
Qt 5.4.0 with minGW491_32
I appreciate your help. Thank you.
I found the solution. 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 ps_excel.ps1 script:
Get-Process Powershell | Stop-Process
instead of
exit 0
I Stop really Powershell and get finished signal, with QProcess::ExitStatus = 0.
Related
Please help!
I'm trying to open a USB connection to an existing device with a listed active interface.
For that I need to open a file using a device id (path).
But CreateFile() fails with ERROR_PATH_NOT_FOUND (error code 3).
I got the following device ids from the Windows 10 Device Manager on my computer ...
"USB\VID_046D&PID_C534&MI_00\6&168DEF1E&0&0000"
"USB\VID_046D&PID_C534&MI_01\6&168DEF1E&0&0001"
"USB\VID_04F2&PID_B5EE&MI_00\6&237200EE&0&0000"
... and ran the following trivial program using one of them as input to CreateFile():
#include "..\..\test_wconsole\test_wconsole\_wconsole_.h"
#include "conio.h"
int APIENTRY wWinMain(_In_ HINSTANCE hi, _In_opt_ HINSTANCE hpi, _In_ LPWSTR c, _In_ int cs)
{
const WCHAR* path = L"USB\\VID_046D&PID_C534&MI_01\\6&168DEF1E&0&0001";
wcprintf("\nopening file \"%ws\" ... ", path);
HANDLE h_usbdevice = CreateFile
(
path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED,
NULL
);
if (h_usbdevice != INVALID_HANDLE_VALUE) wcprintf("done\n"); else wcprintf("error %lu\n", GetLastError());
{ wcprintf("\n\tPress any key to proceed ... "); wcprintf("%i\n\n", _getch()); }
return NULL;
}
Here is a copy of the program’s console output:
opening file "USB\VID_046D&PID_C534&MI_01\6&168DEF1E&0&0001" ... error 3
Press any key to proceed ...
Running the program with Administrator privileges yields the same result. What am I doing wrong?
I am using 'https://github.com/microsoft/cpprestsdk' v2.8 and trying to handle interrupt signal but 'cpprest/http_listener.h' gives segmentation fault.
If I comment out line no 3( #include <cpprest/http_listener.h>) server gets stop without any segmentation fault.
My code snippet is as below
#include <iostream>
#include <cpprest/http_listener.h>
void signal_handler(int signal) {
std::wcout<<"Exiting the program... ::" << signal << std::endl;
exit(EXIT_SUCCESS);
}
int main(int argc, char** argv) {
//Registring a signal handler to prevent abrupt exits
std::signal(SIGINT, signal_handler);
try {
while (true);
}
catch (std::exception const & e) {
std::wcout << e.what() << std::endl;
}
return 0;
}
Versions used :
OS - Linux 16.04
CPP REST version - 2.8
G++ version - 7.5.0
Command to compile above code snippet - g++ test.cpp -o spike_op1 -lcpprest -lssl -lcrypto -lpthread
So there is issue in cpprest/http_listener.h file, does anyone have it's solution?
I am trying to change the Windows Console Mode for output (CONOUT$) using the Windows API and SetConsoleMode calls. So I modified a PowerShell script, based on ConinMode.ps1 (and which works for input), to do this. Reading works fine with both the ConoutMode.exe and my script, and returns:
# .\ConoutMode.exe
mode: 0x3
ENABLE_PROCESSED_OUTPUT 0x0001 ON
ENABLE_WRAP_AT_EOL_OUTPUT 0x0002 ON
ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 off <====
DISABLE_NEWLINE_AUTO_RETURN 0x0008 off
ENABLE_LVB_GRID_WORLDWIDE 0x0010 off
# .\ConoutMode.ps1
OK! GetConsoleWindow handle : 0x1F06D6
Console Input Mode (CONIN) : 0x21f
Console Output Mode (CONOUT) : 0x3
However, both my script and the exe fails in writing the mode. (Possibly because it thinks that my output handle is not pointing to a console?)
In PowerShell:
# .\ConoutMode.exe set 0x000f
error: SetConsoleMode failed (is stdout a console?)
# .\ConoutMode.ps1 -Mode 7
OK! GetConsoleWindow handle : 0x1F06D6
old (out) mode: 0x3
SetConsoleMode (out) failed (is stdout a console?)
At C:\cygwin64\home\emix\win_esc_test\ConoutMode.ps1:112 char:9
+ throw "SetConsoleMode (out) failed (is stdout a console?)"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (SetConsoleMode ...out a console?):String) [], RuntimeException
+ FullyQualifiedErrorId : SetConsoleMode (out) failed (is stdout a console?)
Here is my ConoutMode.ps1 script in it's entirety:
param (
[int] $Mode
)
$signature = #'
[DllImport("kernel32.dll", SetLastError=true)]
public static extern IntPtr GetConsoleWindow();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern uint SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
public const int STD_INPUT_HANDLE = -10;
public const int STD_OUTPUT_HANDLE = -11;
public const int ENABLE_PROCESSED_OUTPUT = 0x0001;
public const int ENABLE_WRAP_AT_EOL_OUTPUT = 0x0002;
public const int ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
public const int DISABLE_NEWLINE_AUTO_RETURN = 0x0008;
public const int ENABLE_LVB_GRID_WORLDWIDE = 0x0010;
'#
#----------------------------------------------------------
$WinAPI = Add-Type -MemberDefinition $signature -Name WinAPI -Namespace ConoutMode -PassThru
#$WinAPI = Add-Type -MemberDefinition $signature -Name WinAPI -Namespace IdentifyConsoleWindow -PassThru
$hwnd = $WinAPI::GetConsoleWindow()
if ($hwnd -eq 0) {
throw "Error: GetConsoleWindow returned NULL."
}
echo "OK! GetConsoleWindow handle : 0x$($hwnd.ToString("X"))"
function GetConIn {
$ret = $WinAPI::GetStdHandle($WinAPI::STD_INPUT_HANDLE)
if ($ret -eq -1) {
throw "Error: cannot get stdin handle"
}
return $ret
}
function GetConOut {
$ret = $WinAPI::GetStdHandle($WinAPI::STD_OUTPUT_HANDLE)
if ($ret -eq -1) {
throw "Error: cannot get stdout handle"
}
return $ret
}
function GetConInMode { #GetCOnsoleMode
$conin = GetConIn
$mode = 0
$ret = $WinAPI::GetConsoleMode($conin, [ref]$mode)
if ($ret -eq 0) {
throw "GetConsoleMode (in) failed (is stdin a console?)"
}
return $mode
}
function GetConOutMode {
$conout = GetConOut
$mode = 0
$ret = $WinAPI::GetConsoleMode($conout, [ref]$mode)
if ($ret -eq 0) {
throw "GetConsoleMode (out) failed (is stdout a console?)"
}
return $mode
}
function SetConInMode($mode) {
$conin = GetConIn
$ret = $WinAPI::SetConsoleMode($conin, $mode)
if ($ret -eq 0) {
throw "SetConsoleMode (in) failed (is stdin a console?)"
}
}
function SetConOutMode($mode) {
#$conout = GetConOut
# Different tack:
$conout = $hwnd
$ret = $WinAPI::SetConsoleMode($conout, $mode)
if ($ret -eq 0) {
throw "SetConsoleMode (out) failed (is stdout a console?)"
}
}
#----------------------------------------------------------
# MAIN
#----------------------------------------------------------
$oldInMode = GetConInMode
$oldOutMode = GetConOutMode
$newMode = $oldOutMode
$doit = $false
if ($PSBoundParameters.ContainsKey("Mode")) {
$newMode = $Mode
$doit = $true
}
if ($doit) {
echo "old (out) mode: 0x$($oldOutMode.ToString("x"))"
SetConOutMode $newMode
$newMode = GetConOutMode
echo "new (out) mode: 0x$($newMode.ToString("x"))"
} else {
echo "Console Input Mode (CONIN) : 0x$($oldInMode.ToString("x"))"
echo "Console Output Mode (CONOUT) : 0x$($oldOutMode.ToString("x"))"
}
So at the end of the day, I want to enable ENABLE_VIRTUAL_TERMINAL_PROCESSING for the Console.
The system I am using for this is:
---------------------------------------------------------
PowerShell Version : 6.1.1
OS Name : Microsoft Windows 8.1 (64-bit)
OS Version : 6.3.9600 [2018-11-16 00:50:01]
OS BuildLabEx : 9600.19179
OS HAL : 6.3.9600.18969
OS Kernel : 6.3.9600.18217
OS UBR : 19182
-------------------------------------------------------
with Privilege : Administrator
-------------------------------------------------------
ExecutionPolicy :
MachinePolicy : Undefined
UserPolicy : Undefined
Process : Undefined
CurrentUser : Undefined
LocalMachine : Bypass
Console Settings:
Type : ConsoleHost
OutputEncoding : Unicode (UTF-8)
Color Capability : 23
Registry VT Level : 1
CodePage (input) : 437
CodePage (output) : 437
I have also enabled the registry item: HKCU:\Console\VirtualTerminalLevel, as instructed elsewhere.
Q: How can I enable this bit/flag using PowerShell?
Some things I can think of that may be wrong:
I surely have the wrong understanding of how this works...
I might have the wrong permissions to write to console? (How to set?)
I might not write to the correct output buffer? (How to find?)
Note that setting the output mode of one screen buffer does not affect the output mode of other screen buffers.
When executing a script, perhaps a new output buffer is created? (What to do?)
I might have to create a new buffer?
I might have to create a new Console?
Related Questions and Links:
ENABLE_VIRTUAL_TERMINAL_PROCESSING and DISABLE_NEWLINE_AUTO_RETURN failing
MSDN: Inside the Windows Console
MSDN: Introducing the Windows Pseudo Console - ConPty
The code is using "GetStdHandle" to get stdin or stdout. And those might be console handles - but it's dependent on how the process is created. If you're launched from a console, and the stdin/stdout aren't redirected, then you'd probably get a console handle. But it's not guaranteed.
Rather than asking for stdin/stdout, just open the console handles directly - you can "CreateFile" for CONIN$ and CONOUT$. The documentation for CreateFile has a whole section on Consoles.
Update: I made a Gist to demonstrate how to use CreateFile to open CONIN$ and CONOUT$ from PowerShell.
I have been experimenting with this myself for a few days and have come to realize a few things. Apparently PowerShell enables Virtual Terminal Processing when it starts up. It disables it again, however, when it launches an executable and then reenables it when the executable exits. This means that whatever executable needs Virtual Terminal Processing must enable it itself or be called through a wrapper program that enables it and then pipes stdin/stdout/stderr through to the terminal. As for how would even go about writing such a program, I don't know.
I have been working through creating a unit test. I need to learn this to test our gui objects. So far this site has answered many questions (most were asked and answered previously). However, I am now at a point where I am getting an error and I cannot find a link to help me resolve it. I get "No rule to make target 'TestGui.cpp', needed by 'TestGui.o'. Stop". Can anyone tell me how to fix this and get my test compiled? This is my first attempt at testing...
This is my test file-
#include <QString>
#include <QObject>
#include <QtTest>
#include <QLineEdit>
#include <QWidget>
#include <QApplication>
class SampleTest : public QObject
{
Q_OBJECT
public:
SampleTest();
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void TestGui();
void TestQstring();
};
SampleTest::SampleTest()
{
}
void SampleTest::initTestCase()
{
}
void SampleTest::cleanupTestCase()
{
}
void SampleTest::TestGui()
{
QLineEdit line_edit;
QTest::keyClicks(&line_edit, "hello world");
QCOMPARE(line_edit.text(), QString("hello world"));
}
void SampleTest::TestQstring()
{
QString str = "hello world";
QCOMPARE(str.toUpper(), QString("HELLO wORLD"));
}
QTEST_MAIN(SampleTest)
#include "SampleTest.moc"
My test.pro file is here -
#-------------------------------------------------
#
# Project created by QtCreator 2015-09-03T09:46:40
#
#-------------------------------------------------
QT += core widgets gui testlib
TARGET = SampleTest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += ../sample_project/TestGui.cpp \
SampleTest.cpp
HEADERS += ../sample_project/TestGui.h
FORMS += ../sample_project/TestGui.ui
DEFINES += SRCDIR=\\\"$$PWD/\\\"
INCLUDEPATH += $$PWD/../sample_project
include(../sample_project/sample_project.pri)
This is my project .pro file -
#-------------------------------------------------
#
# Project created by QtCreator 2015-09-03T09:29:42
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = sample_project
TEMPLATE = app
SOURCES += main.cpp\
TestGui.cpp \
TestBox.cpp
HEADERS += TestGui.h \
TestBox.h
FORMS += TestGui.ui \
TestBox.ui
My project .pri file hs the source and header for my project -
SOURCES += TestGui.cpp
HEADRES += TestGui.h
Try to rename the class name accordingly to the filename. In your case, SampleTest => TestGui
QtCreator tries to find appropriate class definition. If not, it ignores to create target ".moc:" in projects Makefile.
I've written simple program.
Here a code:
#include <iostream>
#include <stdio.h>
#include <D:\Program Files\PostgreSQL\8.4\include\libpq-fe.h>
#include <string>
using namespace std;
int main()
{
PGconn *conn;
PGresult *res;
int rec_count;
int row;
int col;
cout << "ble ble: " << 8 << endl;
conn = PQconnectdb("dbname=db_pm host=localhost user=postgres password=postgres");
if (PQstatus(conn) == CONNECTION_BAD) {
puts("We were unable to connect to the database");
exit(0);
}
}
I'm trying to connect with PostgreSQL.
I compile this code with following command:
gcc -I/"d:\Program Files\PostgreSQL\" -L/"d:\Program Files\PostgreSQL\8.4\lib\" -lpq -o firstcpp.o firstcpp.cpp
This command is from following site:
http://www.mkyong.com/database/how-to-building-postgresql-libpq-programs/
And when I compile it I get following error:
/cygnus/cygwin-b20/H-i586-cygwin32/i586-cygwin32/bin/ld: cannot open -lpq: No such file or directory
collect2: ld returned 1 exit status
Does anyone help me?
Difek
You can try using forward slashes instead of backward slashes. And I have no idea about the first forward slash. Isn't it meant to be inside the quotes ? Eg -I"/d:/Program Files/PostgreSQL/"
Anyway, if you are using the gcc from cygwin, you could also try
-I"/cygdrive/d/Program Files/PostgreSQL"
And I'd do the same with that include (libpq-fe) - though apparently that is working, the error is in the linker.