Discussion:
Executing PowerShell command with quotes using QProcess
(too old to reply)
Jason Kretzer
2014-04-02 19:18:59 UTC
Permalink
Good Day Everyone,

I would like to be able to run a few certain powershell commands using QProcess. I can then read the result. Here is an example of one that works:

QProcess powershell;
powershell.setReadChannel(QProcess::StandardOutput);
powershell.start("PowerShell -Command \"& {(Get-WmiObject Win32_Videocontroller).Name}\"");
powershell.waitForReadyRead(30000);
QString allData(powershell.readAll());
powershell.close();

At the end of this, the allData has content and life is good.

However, if I try to run the exact same code but with a powershell command that has quotes in it, for example code to just get the size of the C:
QProcess powershellHDD;
powershellHDD.setReadChannel(QProcess::StandardOutput);
powershellHDD.start("PowerShell -Command \"&{(Get-WmiObject Win32_LogicalDisk -Filter \\\"DeviceID='C:’\\\").Size}\"");
powershellHDD.waitForReadyRead(30000);
QString dataHDDsize = powershellHDD.readAll();
powershellHDD.close();

This does not work as I expect it to. The dataHDDsize is an empty string “”. If I pull the command out and run it directly from a command prompt (removing the escaping backslashes) it runs exactly as I expect it to returning a number. I thought maybe the number is the problem and I have similar commands that return proper letters and the same thing occurs.

Style and suggestions for third party libs aside, does any one have any pointers?

Thanks!

-Jason

//--------------------------------//
Jason R. Kretzer
Application Developer
***@gocodigo.com
606.792.0079
//--------------------------------//
Thiago Macieira
2014-04-02 22:23:59 UTC
Permalink
Post by Jason Kretzer
powershellHDD.start("PowerShell -Command \"&{(Get-WmiObject
Win32_LogicalDisk -Filter \\\"DeviceID='C:’\\\").Size}\"");
This does not work as I expect it to. The dataHDDsize is an empty string
“”. If I pull the command out and run it directly from a command prompt
(removing the escaping backslashes) it runs exactly as I expect it to
returning a number. I thought maybe the number is the problem and I have
similar commands that return proper letters and the same thing occurs.
Style and suggestions for third party libs aside, does any one have any pointers?
There's a comment in qprocess.cpp that reads:

// handle quoting. tokens can be surrounded by double quotes
// "hello world". three consecutive double quotes represent
// the quote character itself.

I don't know whose idea it was to use three quotes successively to indicate a
quote character. It doesn't work on a regular Unix shell:

$ echo """hello"""
hello

Nor on Windows's prompt:
C:\>echo """hello"""
"""hello"""

That commit has been there since the Qt public history started. It's even
documented as such (I had to look it up, I didn't know):
http://qt-project.org/doc/qt-5/qprocess.html#start-3

But I don't know why it was done like that. It's highly surprising. If it
weren't documented, I'd be tempted to just change behaviour and go for
standard backslashing.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Jason Kretzer
2014-04-02 23:13:54 UTC
Permalink
Thank you, sir. I never would have found that tidbit...

-----Original Message-----
From: interest-bounces+jason=***@qt-project.org [mailto:interest-bounces+jason=***@qt-project.org] On Behalf Of Thiago Macieira
Sent: Wednesday, April 02, 2014 6:24 PM
To: ***@qt-project.org
Subject: Re: [Interest] Executing PowerShell command with quotes using QProcess
Post by Jason Kretzer
powershellHDD.start("PowerShell -Command \"&{(Get-WmiObject
Win32_LogicalDisk -Filter \\\"DeviceID='C:’\\\").Size}\"");
This does not work as I expect it to. The dataHDDsize is an empty
string “”. If I pull the command out and run it directly from a
command prompt (removing the escaping backslashes) it runs exactly as I expect it to
returning a number. I thought maybe the number is the problem and I have
similar commands that return proper letters and the same thing occurs.
Style and suggestions for third party libs aside, does any one have any pointers?
There's a comment in qprocess.cpp that reads:

// handle quoting. tokens can be surrounded by double quotes
// "hello world". three consecutive double quotes represent
// the quote character itself.

I don't know whose idea it was to use three quotes successively to indicate a quote character. It doesn't work on a regular Unix shell:

$ echo """hello"""
hello

Nor on Windows's prompt:
C:\>echo """hello"""
"""hello"""

That commit has been there since the Qt public history started. It's even documented as such (I had to look it up, I didn't know):
http://qt-project.org/doc/qt-5/qprocess.html#start-3

But I don't know why it was done like that. It's highly surprising. If it weren't documented, I'd be tempted to just change behaviour and go for standard backslashing.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center

_______________________________________________
Interest mailing list
***@qt-project.org
http://lists.qt-project.org
Sze Howe Koh
2014-04-03 00:34:20 UTC
Permalink
Post by Thiago Macieira
Post by Jason Kretzer
powershellHDD.start("PowerShell -Command \"&{(Get-WmiObject
Win32_LogicalDisk -Filter \\\"DeviceID='C:'\\\").Size}\"");
This does not work as I expect it to. The dataHDDsize is an empty string
"". If I pull the command out and run it directly from a command prompt
(removing the escaping backslashes) it runs exactly as I expect it to
returning a number. I thought maybe the number is the problem and I have
similar commands that return proper letters and the same thing occurs.
Style and suggestions for third party libs aside, does any one have any pointers?
// handle quoting. tokens can be surrounded by double quotes
// "hello world". three consecutive double quotes represent
// the quote character itself.
I don't know whose idea it was to use three quotes successively to indicate a
$ echo """hello"""
hello
C:\>echo """hello"""
"""hello"""
That commit has been there since the Qt public history started. It's even
http://qt-project.org/doc/qt-5/qprocess.html#start-3
But I don't know why it was done like that. It's highly surprising. If it
weren't documented, I'd be tempted to just change behaviour and go for
standard backslashing.
That's highly unintuitive. The fact that it's Windows-only suggests
that it was put in to work around some issue (which may not be present
in modern versions of Windows). Candidate for change in Qt 6?


Regards,
Sze-Howe
Damian Ivanov
2014-04-03 06:58:37 UTC
Permalink
I'm sorry if this may not help but I wanted to share as it's somewhat
related. On Windows systems one can from QProccess access any Windows
cmd command.
The process should be defined as "cmd /c $mycommand" /k maybe also useful.
Post by Sze Howe Koh
Post by Thiago Macieira
Post by Jason Kretzer
powershellHDD.start("PowerShell -Command \"&{(Get-WmiObject
Win32_LogicalDisk -Filter \\\"DeviceID='C:'\\\").Size}\"");
This does not work as I expect it to. The dataHDDsize is an empty string
"". If I pull the command out and run it directly from a command prompt
(removing the escaping backslashes) it runs exactly as I expect it to
returning a number. I thought maybe the number is the problem and I have
similar commands that return proper letters and the same thing occurs.
Style and suggestions for third party libs aside, does any one have any pointers?
// handle quoting. tokens can be surrounded by double quotes
// "hello world". three consecutive double quotes represent
// the quote character itself.
I don't know whose idea it was to use three quotes successively to indicate a
$ echo """hello"""
hello
C:\>echo """hello"""
"""hello"""
That commit has been there since the Qt public history started. It's even
http://qt-project.org/doc/qt-5/qprocess.html#start-3
But I don't know why it was done like that. It's highly surprising. If it
weren't documented, I'd be tempted to just change behaviour and go for
standard backslashing.
That's highly unintuitive. The fact that it's Windows-only suggests
that it was put in to work around some issue (which may not be present
in modern versions of Windows). Candidate for change in Qt 6?
Regards,
Sze-Howe
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Oswald Buddenhagen
2014-04-03 08:12:27 UTC
Permalink
Post by Sze Howe Koh
Post by Thiago Macieira
C:\>echo """hello"""
"""hello"""
That commit has been there since the Qt public history started. It's even
http://qt-project.org/doc/qt-5/qprocess.html#start-3
But I don't know why it was done like that. It's highly surprising. If it
weren't documented, I'd be tempted to just change behaviour and go for
standard backslashing.
That's highly unintuitive. The fact that it's Windows-only suggests
that it was put in to work around some issue (which may not be present
in modern versions of Windows). Candidate for change in Qt 6?
it's not windows-only.
the quoting mechanism is inspired by how *some* windows applications
interpret quoting. but it is generally speaking just stupid.
when i finally get to it, i want to deprecate this custom single-string
mode in favor of accepting native shell command lines, as qt creator's
QtcProcess does.
Koehne Kai
2014-04-03 08:38:33 UTC
Permalink
Post by Jason Kretzer
-----Original Message-----
[...]
it's not windows-only.
the quoting mechanism is inspired by how *some* windows applications
interpret quoting. but it is generally speaking just stupid.
when i finally get to it, i want to deprecate this custom single-string mode in
favor of accepting native shell command lines, as qt creator's QtcProcess
does.
Just stumbled over

http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx?Redirected=true

I guess it's at least a source of good test cases :)

Regards

Kai
Thiago Macieira
2014-04-03 16:04:40 UTC
Permalink
Post by Oswald Buddenhagen
the quoting mechanism is inspired by how *some* windows applications
interpret quoting. but it is generally speaking just stupid.
when i finally get to it, i want to deprecate this custom single-string
mode in favor of accepting native shell command lines, as qt creator's
QtcProcess does.
Single-string mode is useful on Windows where the command-line is passed to
the OS in a single string as well.

Of course, we break it up and re-create the string in QProcess, instead of
just passing it along.
--
Thiago Macieira - thiago.macieira (AT) intel.com
Software Architect - Intel Open Source Technology Center
Joerg Bornemann
2014-04-03 09:36:38 UTC
Permalink
Post by Thiago Macieira
C:\>echo """hello"""
"""hello"""
Checking arguments with the echo shell built-in on Windows is not a good
idea. It behaves (not even) slightly different from real executables.

Create an executable that prints its arguments and you will find that
triple double-quotes (sextquotes? ;)) will print:

C:\>printAllArgs """hello"""
"hello"


Cheers,

Joerg
Damian Ivanov
2014-04-03 10:28:02 UTC
Permalink
one could use "cmd /c echo hello" at least I do so, or this somehow bad?
Post by Joerg Bornemann
Post by Thiago Macieira
C:\>echo """hello"""
"""hello"""
Checking arguments with the echo shell built-in on Windows is not a good
idea. It behaves (not even) slightly different from real executables.
Create an executable that prints its arguments and you will find that
C:\>printAllArgs """hello"""
"hello"
Cheers,
Joerg
_______________________________________________
Interest mailing list
http://lists.qt-project.org/mailman/listinfo/interest
Joerg Bornemann
2014-04-03 10:44:50 UTC
Permalink
Post by Damian Ivanov
one could use "cmd /c echo hello" at least I do so, or this somehow bad?
You can use that if you're completely sure that echo prints its
arguments verbatim. I for one wouldn't be surprised if there's some
weird edge case where it transforms the passed string somehow, because
of some ancient compatibility requirement. But that's just my very
personal paranioa.


Cheers,

Joerg
Oswald Buddenhagen
2014-04-03 11:12:23 UTC
Permalink
Post by Damian Ivanov
one could use "cmd /c echo hello" at least I do so, or this somehow bad?
it's a double-fail, because in addition to the weird echo behavior, you
also have the even more weird cmd behavior (which can be modified
further with the /s flag).
Loading...