i have a application (X)Medcon, i want to run command line (convert file) with QProcess. I tried but it is not success. This is my code
convertDicomProcess = new QProcess(this);
QString program = "C:\\Program Files\\XMedCon\\bin\\xmedcon.exe";
QStringList arguments;
arguments << "medcon"<< "-f" << "F:/33.nii" << "-c" << "dicom" << "-o" << "F:/33.dcm";
convertDicomProcess->start(program, arguments);
convertDicomProcess->waitForFinished();
QByteArray output = convertDicomProcess->readAll();
convertDicomProcess->close();
When i run command line with
medcon -f E:\55.nii -c dicom -o
E:\55.dcm
it is convert success
Try:
QStringList arguments;
arguments << "/c" << program << "-f" << "F:/33.nii" << "-c" << "dicom" << "-o" << "F:/33.dcm";
convertDicomProcess->start("cmd.exe", arguments);
Test if you really need "medcon" as an argument again, I do not know since I do not know the "medcon" program. If yes change it to:
arguments << "/c" << program << "medcon" << "-f" << "F:/33.nii" << "-c" << "dicom" << "-o" << "F:/33.dcm";
This code tries to run the medcon program in a shell.
If you path exists, I think you need to use quotes (\") in the string for the one:
QString program = "\"C:\\Program Files\\XMedCon\\bin\\xmedcon.exe\"";
...
Related
The aim of this c++ program is about the understanding the cocurrent process mechanism in operating system. And the following code is for the child functions of one process. And the child process have theirs numbers, NO.5 and NO.6.
I'm trying to exectute an a.out file in the NO.6 process. I'm trying to do it this way.
void ChildFunction_For_ProcessNO.4(int i){
switch(i){
case(5):
cout << "This is process five, and the ID for this process is " << getpid() << '\n'
<< "and the ID for the parent process is " << getppid() << '\n';
CreateThreads_Five();
cout << "Process five has ended.\n" << '\n';
break;
case(6):
cout << "This is process six, and the ID for this process is " << getpid() << '\n'
<< "and the ID for the parent process is " << getppid() << '\n';
execl("./a.out", "a.out", NULL);
//and I also tried this way
execl("Home/CLionProjects/Project_1/a.out", "a.out", NULL);
char buf[100];
cout << "getcwd: " << getcwd(buf, sizeof(buf))) << endl;
cout << "Process six has ended.\n";
break;
}
and the getcwd's output goes like this
getcwd: /home/chengxuyuan/CLionProjects/Project_1/cmake-build-debug
The a.out file has already been put in the folder together with the c++ program.
the screenshot of the working directory
and the compile went well, but there is just no output which ought to be Hello world from the a.out file. How can I solve this problem. Thanks a lot!
The getcwd output shows that you have to put your file a.out into
/home/chengxuyuan/CLionProjects/Project_1/cmake-build-debug
Your attempt
execl("Home/CLionProjects/Project_1/a.out", "a.out", NULL);
is wrong this is not the full path. You would have to use
execl("/home/chengxuyuan/CLionProjects/Project_1/a.out", "a.out", NULL);
BTW: You should specify the same value as argument 0 as you use for the program to be run, i.e.
execl("/home/chengxuyuan/CLionProjects/Project_1/a.out", "/home/chengxuyuan/CLionProjects/Project_1/a.out", NULL);
or
execl("./a.out", "./a.out", NULL);
This is what the shell would do and what most programs expect.
noted: this is a use-specific question, but I hope others can benefit from this too
To get a basic sense of what I want to do:
QProcess runs a command by:
QProcess::start("sh -c \"cd /tmp/tempdir ; ./my_script --option file.txt ; echo $?\" ")
The script expects input from the user (a password), QProcess::readAll() confirms the script's input request. The input is given by QProcess::write().
Here I get lost! -> No output is received. from readAll() and readAllStandardOutput(), both are empty.
I need the output: particularly the echo $? for later processing, but don't get anything since readAll() and readAllStandardOutput() returns empty strings
To me there are several possible issues to cause this, maybe more than one:
The script does not receive this input
The script receives the input, but expects a "return key press"
The script receives the input, QProcess::write automatically does a "return key press", the script continues and finishes but QProcess does not read this output
The Code:
// please ignore the messiness of the code, a placed a number of debugs just to see the code response.
cmd = "cd /tmp/tempdir ; ./my_script --option file.txt ; echo $?" (without quotes)
input => required input for script
QString gen_serv::runCommand(QString cmd, QString input){
Process *p = new QProcess(parent);
p->setProcessChannelMode(QProcess::MergedChannels);
// p->start("sh ", QStringList() << " -c " << cmd);
QString c = QString("sh -c \"" + cmd + "\" ");
p->start(c); <---- ACTUAL COMMAND : sh -c "cd /tmp/tempdir ; ./my_script --option file.txt ; echo $?"
if (p->waitForStarted()) {
if (!p->waitForReadyRead()) {
qDebug(log_lib_gen_serv) << "waitForReadyRead() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
if (!p->waitForFinished(1000)) {
qDebug() << p->readAll();
qDebug() << p->readAllStandardOutput();
//p->write(input.toLatin1());
p->write(QString(input + QString("\n")).toLatin1()); <--- added this "\n" incase the process/console was waiting for a return press, thus the /n should satisfy the return requirement
qDebug() << p->readAll();
qDebug() << p->readAllStandardOutput();
if (!p->waitForFinished()) {
qDebug() << p->readAll();
qDebug() << p->readAllStandardOutput();
qDebug(log_lib_gen_serv) << "waitForFinished() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
qDebug() << p->readAll();
qDebug() << p->readAllStandardOutput();
}
QString s = QString(p->readAll() + p->readAllStandardOutput());
return s;
}
else{
qDebug(log_lib_gen_serv) << "waitForStarted() [false] : CODE: " << QVariant(p->error()).toString() << " | ERROR STRING: " << p->errorString();
}
p->waitForFinished();
p->kill();
return QString();
}
Please note:
The script is long and complicated, however it returns a message "done" if successfully executed and an exit code for each case.
Thus the echo $? should capture and return this for processing i.e. return s
I hope this makes sense, any suggestions how I can attempt to solve this issue?
I developed a code which create a .cpp file from a .isc file. This .isc file contains tons of lines with logic circuit information. My code read every line of this .isc file and write a code in a .cpp file that will simulate the logic of each .isc line, and this .cpp is saved in the same folder of the code which creates it. What I want to do is compile and run the executable of this .cpp file I created with a command line straight from my main code. I've been doing some researches and I found that a makefile could do that for me. About makefile I found some information here:
Can I compile all .cpp files in src/ to .o's in obj/, then link to binary in ./?
C++ makefile on Linux with Multiple *.cpp files
Based on that, After creating and writing the converted code in the .cpp file, I created a makefile (with dynamically name), here is it:
ofstream make_file("Makefile", ios::out | ios::trunc); //read and open the file
if (make_file == NULL ){ cout << "Error creating makefile!"; return 1; }
make_file << "# Makefile" << endl;
make_file << "# This makefile will run the new cpp file created\n" << endl;
make_file << "CC = g++\n" << endl;
make_file << "# FLAGS:" << endl;
make_file << "CFLAGS = -g -B -Wall\n" << endl;
make_file << "Executable target:" << endl;
make_file << "TARGET = " << netlist << "\n" << endl;
make_file << "all: $(TARGET)\n" << endl;
make_file << "$(TARGET): $(TARGET).c" << endl;
make_file << "\t$(CC) $(CFLAGS) -o $(TARGET) $(TARGET).cpp\n" << endl;
make_file << "clean:" << endl;
make_file << "\t$(RM) $(TARGET)" << endl;
make_file.close();
So, my objective is to make this makefile compile the .cpp file and run its executable, assuming this is possible. If it is and I created the makefile in a correct way, how do I execute, or "make" it?
Edit: I'm using codeblocks
I am writing a small application on linux using qt creator.
When i start my application i want it to execute a shell command. I`m using QProcess for it like this:
int main(int argc, char *argv[])
{
MyApplication a(argc, argv);
QProcess mapProc(&a);
QString command;
QStringList args;
command = "java";
args << "-jar" << "/home/$USER/MapServer/map.jar" << "localhost" << "9797" << "12123";
mapProc.start(command, args);
bool flag = mapProc.waitForStarted();
QProcess::ProcessState state = mapProc.state();
qDebug() << mapProc.errorString();
qDebug() << mapProc.pid();
/*/////////////////
some code
/////////////////*/
return a.exec();
}
but when my application started, process "mapProc" becomes a zombie. Why? what am i doing wrong?
$USER will not really work like that with QProcess. You will need to invoke the command through /bin/sh -c "mycmd" or even better if you just do it the proper Qt way as indicated below.
Try using QStandardPaths, so write this:
QString homeLocation =
QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
args << "-jar" << QString(homeLocation.first() + "/MapServer/map.jar")
<< "localhost" << "9797" << "12123";
instead of this:
args << "-jar" << "/home/$USER/MapServer/map.jar"
<< "localhost" << "9797" << "12123";
I have a C++ program that reads a config file and gets the directories.
What I want to do now is to execute an .exe program using the directory settings from the config file.
Here is a piece of my code:
int main(){
ConfigFile cfg("htbaseconfig.properties");
bool exists = cfg.keyExists("backuplocation");
exists = cfg.keyExists("logdir");
exists = cfg.keyExists("execdir");
exists = cfg.keyExists("fulldir");
exists = cfg.keyExists("incdir");
exists = cfg.keyExists("appdir");
std::string bkploc = cfg.getValueOfKey<std::string>("backuplocation");
std::cout << "Backup Location: " << bkploc << "\n";
std::string bkplogdir = cfg.getValueOfKey<std::string>("logdir");
std::cout << "Log Location: " << bkplogdir << "\n";
std::string bkpexec = cfg.getValueOfKey<std::string>("execdir");
std::cout << "Exec Directory: " << bkpexec << "\n";
std::string bkpfulldir = cfg.getValueOfKey<std::string>("fulldir");
std::cout << "Full Directory: " << bkpfulldir << "\n";
std::string bkpappdir = cfg.getValueOfKey<std::string>("appdir");
std::cout << "Real app Directory: " << bkpappdir << "\n\n\n";
for( ; ; ) {
Sleep(6000);
ShellExecute(NULL, L"open", , L"C:\\teste.htm", NULL,SW_SHOWNORMAL);
}
std::cin.get();
return (0);}
Inside the ShellExecute, I wanted to execute the following line parsing the config options:
$execdir/program.exe $logdir/log.txt $bkpappdir $bkploc
How do I do this? I want to execute my program with the variables I get on std::cout.
You must pass to ShellExecute, instead of the second NULL, a string (c string, a char[]) that contains all parameters, like if you are passing them to the command line.
So Will be something like
ShellExecute(NULL, L"open", , L"C:\\teste.htm", "option=param option2=param2",SW_SHOWNORMAL);
Depends on how you parse them (or how they are parsed) from the other exe file