PDA

View Full Version : QProcess issue with GPG under Windows



superpacko
5th September 2011, 14:59
Hey there, im having a few issues trying to use QProcess to create a sub-process that runs GPG on the background.

I had previously implemented the functionality with windows specific methods, but since we are porting everything to Linux and Mac i thought it would be nice to let QProcess handle everything.

The problem is that the arguments that QProcess is building are not compatible with the type or argument GPG expects (GPG is pretty sensitive).
My code look like this:



QList<GPGKey> GPGKeyManagement::getKeys(GPGParameter *param)
{
QList<GPGKey> list;

QStringList args;
args << "--homedir . --list-keys";
//args << "--homedir . ";
//args << " --list-keys ";

if (param)
{
// add the information specified in param to the args
}

QProcess gpg;
gpg.setProcessChannelMode(QProcess::MergedChannels );
gpg.start("gpg.exe", args);

if (!gpg.waitForFinished())
qDebug() << "Error: " << gpg.errorString();
else
{
QString response(gpg.readAll());
qDebug() << response;
list = parseKeysFromOutput(response);
}

return list;
}


i also tried this, with no luck:


gpg.start("gpg.exe --homedir . --list-keys", args); //args empty
or
args << "gpg.exe --homedir . --list-keys";
gpg.start("", args);


When Qt builds the command line it does 'gpg "--homedir . --list-keys" ' and so GPG complains about the double quotes added.
Was anyone able to call gpg from a QProcess in Windows?

high_flyer
6th September 2011, 12:56
What happens if you do:


args << "--homedir"<<"."<<"--list-keys";
gpg.start("gpg.exe", args);

superpacko
6th September 2011, 14:12
Thanks for the replay, im afraid it was no good either. I also tried



args << "--homedir . " << " --list-keys";


but it didnt work. I kinda imagine why qt is doing such thing, but maybe it would be nice to be able to customize the way we want to build the command line arguments to avoid this problems with super sensitive software like Gpg.
Im wondering if this issue will happen in linux and mac as well, because if it happens, then im gonna have to forget about QProcess and do it my self for each platform. What do u think?


Thanks!

high_flyer
6th September 2011, 15:05
Something is not right.
The arguments QPrcoess generates should not have quotes (" ") in them.
Argument in general don't need (" ") , unless it an argument value which is a string.
But I can't see what you are doing wrong in what you posted.

superpacko
7th September 2011, 15:41
i see, well i dont know what else to do. Im gonna try the test case on Mac to see what happens.

I'll let you know how it goes!

wysota
7th September 2011, 17:32
What Daniel suggests in post #2 should work fine. Please make sure you followed his advice accurately. Each argument should be its own string in the string list.

superpacko
7th September 2011, 20:19
I've tried that, and still not working. Here's what the command argument that QProcess builds, looks like in the debuger:

args "gpg.exe " --homedir " " . " " --list-keys""

If i build a single argument, the result is the same, it adds quotes to the single argument, and the variable in the debugger looks like:

args "gpg.exe "--homedir . --list-keys"""

So its clear that QProcess is adding surrounding quotes to the command line arguments. The same is happening on Mac.


Added after 6 minutes:

We have found a solution for this issue on windows, using setNativeArguments(). The code looks like this:


QProcess gpg;
gpg.setProcessChannelMode(QProcess::MergedChannels );
gpg.setNativeArguments("--homedir . --list-keys");
gpg.start("gpg");


This works perfectly fine. The problem is that this method is only avaliable on Windows, so the same problem is happening on Mac and i can use that solution.

-------------------------------------------------------------------------------------
We solved the issue, i looked at the qt_create_commandline() static function to find where or why the quotes were added. According to the algorithm, is the argument has a ' ' then it is wrapped in quotes. Since i was adding a space, every argument ended up wrapped.
The solution now looks like: (and it works both on windows and mac)


QStringList args;
args << "--homedir" << "." << "--list-keys"; //do not add any space on each argument!

QProcess gpg;
gpg.setProcessChannelMode(QProcess::MergedChannels );
gpg.start("gpg", args);


Thanks for your help!