PDA

View Full Version : Problems launching a windows exe from Qt (using QProcess)



smacchia
11th January 2010, 22:36
I'm using the following code to launch a process. The program exists and I can run it on the command line. The code snippet from the slot/method trying to launch the program:


process = new QProcess; // process is a member of my class typed QProcess*
connect(
&process, SIGNAL (error(QProcess::ProcessError)),
this, SLOT(sdLaunchError (QProcess::ProcessError)));

QString path("C:\\Program Files\\My Compay\\MyCompanyMonitor");

QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
process->setWorkingDirectory(path);
QString fullPath = path + ";" + env.value("Path");
env.insert("PATH", fullPath);
process->setProcessEnvironment(env);

process->start("Monitor");

The error I get when I call errorString from sdLaunchError (the slot called when the QProcess::error signal is called) is "No such file or directory". The file is definitely there. I've tried changing the call to QProcess::setWorkingDirectory to the following (so that the path with spaces is enclosed in quotes):

process.setWorkingDirectory("\"" + path + "\"");
I tried adding QIODevice::NotOpen to QProcess::start call. I tried changing the call to ::start to include the extension:

process.start("Monitor.exe);
In a command prompt, I emulated this in the following way:

C:
cd \
set PATH=C:\Program Files\My Company\MyCompanyMonitor;%PATH%
Monitor

And the program runs. What am I doing wrong? (As an aside, I've launched programs several times on Linux with no problems on other projects).

I'm running with Qt 4.6.0 on Windows XP.

Thanks in advance!

wysota
11th January 2010, 22:45
QProcess doesn't understand the "PATH" variable as you think it would. You are passing PATH to environment of the application, meaning that it will be effective once the application is launched. It won't take part in searching for the application to be launched. You need to provide an absolute path to QProcess.

squidge
11th January 2010, 22:47
Whilst your OS may use '\' as a directory seperator, Qt uses '/'. You can convert between them for OS-specific function calls that require '\' by using QDir::toNativeSeperators()

smacchia
12th January 2010, 15:16
I didn't realize that setting the path wouldn't impact the process - thanks for that info. When I pass the full path including the executable to ::start, it doesn't get parsed correctly. I also tried the following, which resulted in the same problem:

String path("C:\\Program Files\\My Company\\MyCompanyMonitor");

QString fullPath = "\"" + path + "\\Monitor.exe\"";

bool ok = QProcess::startDetached(
fullPath,
QStringList(),
"\"" + path + "\"");

if (!ok)
{
QMessageBox::critical(
NULL, QString(), tr("Unable to run the Control Panel\n"));
}

Note that I'm passing the full path. It still won't start the program :(

I'll try switching to "/" and get back to (this always worked on Linux!).

Thanks

smacchia
12th January 2010, 15:32
Ok, I tried changing "\\" to "/". I tried adding "C:\\Program Files\\My Company\\MyCompanyMonitor" to the system path, restarted a command prompt and made sure the system path change worked (i.e., can I simply type "Monitor" and have it run) - and it worked.

But my application still can't launch the executable...this is REALLY frustrating and puzzling. I've debugged into QProcess code and can't seem to find why CreateProcess fails... I'm not a windows guru, but it seems to me that this should work...

Any help is greatly appreciated.

Thanks

squidge
12th January 2010, 16:18
Maybe the file can be found, but can't be run? It could be failing to find a dependancy. If your debugging into QProcess code, you should post the result from GetLastError() after the CreateProcess. Even better, you could go here -> http://msdn.microsoft.com/en-us/library/ms681382%28VS.85%29.aspx and look up the error code.

wysota
12th January 2010, 16:19
Please provide a minimal compilable example reproducing the problem.

smacchia
12th January 2010, 17:26
I managed to figure out the problem! I had to include the path to the program AND include quotes around it. And the working directory had to be correct in that it had to include "\" not "/" or create process returned invalid directory. So the working code looks like:

if (_mon)
return;

_mon = new QProcess(this);

QString path("C:\\Program Files\\My Company\\MyMonitor");

_mon->setWorkingDirectory(path);

QString program = "\"" + path + "/Monitor.exe" + "\"";
_mon->start(program);
...

sztomi
21st March 2012, 10:05
I have encountered the same problem. The solution smacchia described works, although it is a little messy (it produces ""C:\\Program Files\\My Company\\MyMonitor/Monitor.exe"" as a path, with the quotes). The way I found it to work and also look nicer is to set the working directory to the directory of the application to launch and then simply call start("myapplication.exe").



QProcess* process = new QProcess(this);
process->setWorkingDirectory(path_of_application);
process->start("application.exe");


I believe this shouldn't be necessary and it should run with the full path. This might be a bug, though I'm not sure about the exact circumstances yet. It may worth mentioning that the application I'm launching is a .NET application.