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 :eofSo 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.
-
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 :eofSo 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.
-
@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 worksGive 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 FolderGive 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. -
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 :eofSo 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.
@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. -
@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. -
@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. -
Apart from all the comments above - why do you need
cmd /cat all here? Why not simply start the executable. For the cmd it's needed but not for the exe. -
@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.@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. QtQString 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. -
Apart from all the comments above - why do you need
cmd /cat all here? Why not simply start the executable. For the cmd it's needed but not for the exe.@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.
-
@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.