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

Problem passing a directory with whitespace in QProcess



  • Hello

    It's been a week that I'm developing an ESP32 binary burner with flash encryption. Basically it just wrapper for Python script that provided by espressif so I don`t need to manually call all the flash encryption function one by one. To avoid Python dependencies, I build .py files into .exe.

    Long story short, I have succesfully create QT program for ESP32 binary burner. The problem is, when I deploy the program into another PC, my program fail miserably. After further investigation, it was found that there is problem when I have a whitepsace on the python argument. So I`m looking for solution, and found this thread: https://forum.qt.io/topic/40197/problem-passing-a-directory-with-a-space-in-it-as-an-argument

    Basically the solution is making a batch script file (.cmd) to catch all the argument and paste them together. And it works...

    ...Until I realize that .cmd need to be on the folder with NO whitespace.

    Sure I can put my .cmd in C:/ and call it a day. But I want to make sure all the main program, QT dll, python script and .cmd (if needed) into one folder so when deploying to another PC, I just need to copy one folder and be done with it.

    Here is snipset on the QT Program. This is a simple hard coded program (the real program using QCoreApplication::applicationDirPath() for path), but will give you the idea how I want it to work:

    ESPTS::ESPTS(QWidget *parent) :
        QWidget(parent),
        ui(new Ui::ESPTS)
    {
        ui->setupUi(this);
    
        proc = new QProcess(this);
    	connect(proc, SIGNAL(readyReadStandardOutput()), this, SLOT(rightMessage()));
    	connect(proc, SIGNAL(readyReadStandardError()), this, SLOT(wrongMessage()));
    	connect(proc, SIGNAL(finished(int)), this, SLOT(finishedMessage()));
    
    	QString espefuse_path = "C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe"; //Whitespace on ESP Burner Folder
    	QString espcommand_path = "C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd"; //Whitespace on ESP Burner Folder
    	//QString espcommand_path = "C:/espcommand.cmd"; //No whitespace, it works
    
    	QString exec = "cmd.exe /C " + espcommand_path + " summary"
    						+ " \"" + espefuse_path + "\""
    						+ " \"" + "COM54" + "\""
    				;
    				
    	esp32_message.clear(); //To catch all data from QProcess
    				
    	ui->textEdit->append(exec);
    	ui->textEdit->append(""); //For debugging
    
    	proc->start(exec);
    }
    
    ESPTS::~ESPTS()
    {
        delete ui;
    }
    
    void ESPTS::rightMessage()
    {
        QByteArray strdata = proc->readAllStandardOutput();
        strdata = strdata.simplified();
        strdata = strdata.trimmed();
        esp32_message.append(strdata); //Append QProcess data
    }
    
    void ESPTS::wrongMessage()
    {
        QByteArray strdata = proc->readAllStandardError();
        esp32_message.append(strdata); //Append QProcess data
    }
    
    void ESPTS::finishedMessage()
    {
    	ui->textEdit->append(esp32_message); //Show the results
    }
    

    Here is the snipset on .cmd file:

    @echo off
    
    call :%1 %2 %3 %4 %5 %6 %7 %8 %9
    goto :eof
    
    :summary
    "%~1" --port %~2 summary
    goto :eof
    

    So when I run the program, ui->textEdit showing the result as following:

    cmd.exe /C C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd summary "C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe" "COM54"
    
    'C:/Users/Krisna/Desktop/ESP' is not recognized as an internal or external command,
    operable program or batch file.
    

    Any help will be greatly appreciated. Thank you for your time and guidance. Sorry for my bad english.


  • Lifetime Qt Champion

    @Papatonk You need to put such paths in "":

    QString espefuse_path = "\"C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe\"";
    


  • @jsulm Thank you for your reply. So using:

        QString espefuse_path = "\"C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe\""; //Whitespace on ESP Burner Folder
        QString espcommand_path = "C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd"; //Whitespace on ESP Burner Folder
        //QString espcommand_path = "C:/espcommand.cmd"; //No whitespace, it works
    

    Give the same result:

    cmd.exe /C C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd summary ""C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe"" "COM54"
    
    'C:/Users/Krisna/Desktop/ESP' is not recognized as an internal or external command,
    operable program or batch file.
    

    And if I add " to espcommand_path

        QString espefuse_path = "\"C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe\""; //Whitespace on ESP Burner Folder
        QString espcommand_path = "\"C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd\""; //Whitespace on ESP Burner Folder
    

    Give the same result too:

    cmd.exe /C "C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd" summary ""C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe"" "COM54"
    
    '"C:/Users/Krisna/Desktop/ESP"' is not recognized as an internal or external command,
    operable program or batch file.
    

  • Lifetime Qt Champion

    @Papatonk said in Problem passing a directory with whitespace in QProcess:

    QString exec = "cmd.exe /C " + espcommand_path + " summary"
    + " "" + espefuse_path + """
    + " "" + "COM54" + """

    This is completely wrong! Please read https://doc.qt.io/qt-5/qprocess.html
    Hint: the command to execute and its parameters are NOT one string! Parameters need to be put into a QStringList parameter.



  • @jsulm Ok, actually I have play with QProcess with QStringList before, AFAIK we dont need to put ", QProcess will do that when we pass QStringList, but CMIIW. So here is the code:

        QString espefuse_path = "C:/Users/Krisna/Desktop/ESP Burner/espefuse.exe"; //Whitespace on ESP Burner Folder
        QString espcommand_path = "C:/Users/Krisna/Desktop/ESP Burner/espcommand.cmd"; //Whitespace on ESP Burner Folder
    
        QStringList exec_list;
        exec_list << "/C" << espcommand_path << "summary" << espefuse_path << "COM54";
    
        proc->start("cmd.exe", exec_list);
    

    Still give the same result:

    'C:/Users/Krisna/Desktop/ESP' is not recognized as an internal or external command,
    operable program or batch file.
    


  • This post is deleted!

  • Lifetime Qt Champion

    Apart from all the comments above - why do you need cmd /c at all here? Why not simply start the executable. For the cmd it's needed but not for the exe.



  • @Papatonk
    I would not try passing a path with /s in it to Windows/cmd. To ensure it's treated correctly you should use \s. Qt QString QDir::toNativeSeparators(const QString &pathName) can do this for you.

    But mostly I would follow @Christian-Ehrlicher's suggestion. At the moment your command seems to have no need of being run via cmd /c (e.g. no redirection symbols used). So execute it directly and see how the quoting comes out.



  • @Christian-Ehrlicher Because I'm such a noob, the only QProcess I know is using only cmd.exe :D. Man it's embarassing, it's solved now. Sorry for bothering all of you, thank you for your guidance.


  • Lifetime Qt Champion

    @Papatonk
    No worries. we don't mind beginners as long as they post the actual code and write clear questions and not
    respond to all suggestions with "Don't work" :)
    So just consider yourself a little less beginner now :)


Log in to reply