Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

deprecation of QProcess::start and execute without argument list...



  • Hi,
    I'm upgrading my code to Qt v5.15.0 and I've noticed that both QProcess::start and the static QProcess::execute with only one QString containing both the command and the arguments are deprecated.

    That's quite problematic...
    You may read full command lines from a configuration file.
    It can be really tricky to cut it back in Command and arguments as there might be spaces to indicate a paths, also placeholders that are replaced using QString::arg...

    Is there a way to discuss/challenge the deprecation and prevent a removal for Qt v6.0?


  • Lifetime Qt Champion

    @mbruel said in deprecation of QProcess::start and execute without argument list...:

    It can be really tricky to cut it back in Command and arguments as there might be spaces to indicate a paths

    That's exactly the reason why it was deprecated - the arguments must be passed separately to the underlying OS call. This does not work out in a lot of cases due to strange escaping of e.g. spaces. Therefore you have to pass the arguments separately since Qt can't do it for you in a reliable way.



  • @Christian-Ehrlicher
    Sorry, I'm not with you on this, I'm more with @mbruel .

    As he says, there are cases where, for whatever reason, you have a complete string to execute. Having something from a configuration file is indeed an example. Attempting to split it up into separate arguments, de-quote it, and then asking Qt to re-quote it, is madness. Madness, I say! And will probably be required for legacy stuff, if nothing else.

    The thing is, the docs always used to say of the start(QString) one: "There are times when the rules of Qt quoting are not good enough/suitable, and there are cases where you will want to use this to get it right on a particular OS".

    Yes, the single string is dangerous, if you don't know what you're doing. But very useful if you do.

    @mbruel

    Is there a way to discuss/challenge the deprecation and prevent a removal for Qt v6.0?

    Probably not, in the sense that the decision is probably made. Only IMHO.



  • @Christian-Ehrlicher Yeah we all know executing a single string could fail due to escaping not done properly, but if you're careful with it, sometimes it's just practical.
    If there is an issue, you can test and adapt your string....

    I've several apps with command lines loaded from config files, as @JonB said, it would be madness to cut it back in command and attributes....

    Probably not, in the sense that the decision is probably made. Only IMHO.

    well how Qt team makes their decisions about deprecating APIs? Is there a place where users could request not to do it and explain why? This would sound like opensource philosophy to me. If many people react and ask to keep a functionality they could consider to let it no?

    Is it only the bug platform?

    Edit: and also a place where we could request some piece of functionalities that we would like. See if others are interested... This would be great for the whole community no?


  • Lifetime Qt Champion

    If many people react and ask to keep a functionality they could consider to let it no?

    This feature will for sure not come in again, trust me.

    You know much better where the single arguments are than Qt. So you have to take care for it. There were a lot of problems due to the heuristic to split the string into a list of arguments so it will be removed in Qt6.
    I don't see why you can't pass the parameters as QStringList though. You should rewrite your code so you're also aware what a single argument is.

    For reference: https://bugreports.qt.io/browse/QTBUG-80640



  • @mbruel
    I can see there are pro & con arguments for who/where should be responsible for command argument strings/items. You & I are not going to win, if @Christian-Ehrlicher says

    This feature will for sure not come in again, trust me.

    then we should trust him ;-)

    I just wanted to say: assuming you are on a decent OS like Linux, or even a dodgy one like Windows, we can (may be able to) use the shell to execute single-string command-lines.

    For Linux:

    start("/bin/sh", QStringList() << "-c" << commandLineString);
    

    For Windows, I'm a bit worried because it does not really take a single argument, Qt's quoting might mess it up, but:

    start("cmd", QStringList() << "/c" << commandLineString);
    

    Unfortunately, these approaches may have their own quoting issues, but it's a thought...?



  • @Christian-Ehrlicher said in deprecation of QProcess::start and execute without argument list...:

    This feature will for sure not come in again, trust me.

    You know much better where the single arguments are than Qt. So you have to take care for it. There were a lot of problems due to the heuristic to split the string into a list of arguments so it will be removed in Qt6.

    For reference: https://bugreports.qt.io/browse/QTBUG-80640

    Well, I've checked the QTBUG and the code of QProcess. As explained there by some people, it's bothering for the "customers" or "users" to loose something they were relying on: that static parseCombinedArgString() method.
    You have it in the code, why don't you at least let it accessible... you could either put it in QProcess or in QCommandLineParser namespace...

    I don't see why you can't pass the parameters as QStringList though. You should rewrite your code so you're also aware what a single argument is.

    As explained, I don't think I'm the only one using that, I'm getting commands from configuration files.
    On a simple app, sth like post treatment commands.

    Before checking Qt's code, I'd have just use a split(QRegularExpression("\\s+")) ignoring the quotes but it would be more practical to use parseCombinedArgString.
    It's a bit boring to have to copy that function in our code... I guess we can do it!..
    But it was handy to have the QProcess methods without argument list doing it for us...

    @JonB Well I guess I'm just going to copy Qt parseCombinedArgString method. It is working fine enough for me. If needed I'll rethink the algorithm but really it is doing the job already!



  • @mbruel said in deprecation of QProcess::start and execute without argument list...:

    @JonB Well I guess I'm just going to copy Qt parseCombinedArgString method. It is working fine enough for me. If needed I'll rethink the algorithm but really it is doing the job already!

    Thinking it through: because Qt insists on issuing OS commands through an argument vector method and never a complete string --- despite the fact that under Windows the underlying OS executable spawner works from complete string not separate arguments, see CreateProcess(), unless that has changed these days --- that means Qt has to have code to parse a string argument to break it into separate arguments, i.e. parseCombinedArgString().

    Now, they probably felt that this was "dodgy", certainly cross-platform, I don't know if it always gets it "right", for its target OS. So I think they are alleviating themselves from such a responsibility. Since the code is probably not reliable, it's now your job to provide whatever user-level code you consider appropriate for your code/needs. So if it's wrong, it's now your fault!

    Given which, I guess it's reasonable that if you decide the code in their old, deprecated parseCombinedArgString() is what you want to use, you now have to provide that yourself....



  • @mbruel
    Further to our discussion as to what to do for a string command once 5.15 comes out with the QProcess string versions deprecated....

    I just came across a new method at 5.15: QStringList QProcess::splitCommand(QStringView command)

    Splits the string command into a list of tokens, and returns the list.

    Tokens with spaces can be surrounded by double quotes; three consecutive double quotes represent the quote character itself.

    This function was introduced in Qt 5.15.

    So... for right or for wrong, this presumably encapsulates the logic Qt used to use if it split your string into separate tokens before passing to OS. Which means that hopefully you haven't lost the functionality from Qt code, it's just in its own method now, which you can use on your string before handing it to a QProcess method requiring a QStringList!



  • @JonB oh cool, I didn't see your reply.
    Indeed, they've reintroduced parseCombinedArgString but renamed in splitCommand \o/

    It's just boring that it was gone just for few versions... as we need to define it for versions prior to 5.15...
    It is still needed to compile on 5.8 for old systems using a old glibc version... (servers on Debian 8 for example)
    more #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)...

    But anyway, it's a good news ;)


Log in to reply