How to use Windows QT to call WSL cmd?
-
wrote on 29 Aug 2022, 04:23 last edited by
I'm new to QT and tried to integrate some linux packages with another guy in Windows QT. I found that WSL may be a convenient way to run my original code and it went well after I installed WSL2 Ubuntu.
Then I installed QT5.15.2 with MinGW and try to run my Python code after click a button. I tested in QT Creator and found this line works: QProcess::execute("cmd /c mkdir C:\Test"); that creates a folder in C. However, this line won't work: QProcess::execute("cmd /c wsl ls >> res.txt"); It can't recognize what wsl is. But I also test the QT MinGW terminal and it recognized wsl. Why it can't recognize in exe? Do I need to select different compiler or debugger? Or any other suggestion such as Docker for this kind of integration? Thank you~
-
I'm new to QT and tried to integrate some linux packages with another guy in Windows QT. I found that WSL may be a convenient way to run my original code and it went well after I installed WSL2 Ubuntu.
Then I installed QT5.15.2 with MinGW and try to run my Python code after click a button. I tested in QT Creator and found this line works: QProcess::execute("cmd /c mkdir C:\Test"); that creates a folder in C. However, this line won't work: QProcess::execute("cmd /c wsl ls >> res.txt"); It can't recognize what wsl is. But I also test the QT MinGW terminal and it recognized wsl. Why it can't recognize in exe? Do I need to select different compiler or debugger? Or any other suggestion such as Docker for this kind of integration? Thank you~
@NTU_WTY Use full path to wsl.exe.
Also, the way you're using QProcess is wrong, please read its documentation (hint: parameters for the executable needs to be passed as a QStringList). -
@NTU_WTY Use full path to wsl.exe.
Also, the way you're using QProcess is wrong, please read its documentation (hint: parameters for the executable needs to be passed as a QStringList).wrote on 29 Aug 2022, 06:20 last edited by@jsulm Thank you, I tried as follows:
QProcess sh; sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls >> res.txt"); sh.waitForFinished(); QByteArray output = sh.readAll(); sh.close();
The
res.txt
is still empty. I also tried to replacecmd
toC:\\Windows\\System32\\wsl.exe
and it took a while to complete without creating the res.txt. Can you give me more hints? Thank you~ -
@jsulm Thank you, I tried as follows:
QProcess sh; sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls >> res.txt"); sh.waitForFinished(); QByteArray output = sh.readAll(); sh.close();
The
res.txt
is still empty. I also tried to replacecmd
toC:\\Windows\\System32\\wsl.exe
and it took a while to complete without creating the res.txt. Can you give me more hints? Thank you~@NTU_WTY said in How to use Windows QT to call WSL cmd?:
"C:\Windows\System32\wsl.exe ls >> res.txt"
Try to split this into 4 parameters instead of one
-
@jsulm Thank you, I tried as follows:
QProcess sh; sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls >> res.txt"); sh.waitForFinished(); QByteArray output = sh.readAll(); sh.close();
The
res.txt
is still empty. I also tried to replacecmd
toC:\\Windows\\System32\\wsl.exe
and it took a while to complete without creating the res.txt. Can you give me more hints? Thank you~wrote on 29 Aug 2022, 07:02 last edited by JonB@NTU_WTY
So far as I can see (not being a Windows WSL user) your command should work (I assume you tested it in a Command Prompt first).Why not start with
sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls");
Avoids dealing with the redirection. Does
output
variable now get filled with the output? You might check for errors. -
@NTU_WTY
So far as I can see (not being a Windows WSL user) your command should work (I assume you tested it in a Command Prompt first).Why not start with
sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls");
Avoids dealing with the redirection. Does
output
variable now get filled with the output? You might check for errors.wrote on 29 Aug 2022, 07:37 last edited by NTU_WTY@JonB Thank you. Yes, I've tested in Command Prompt and it recognized
wsl
and listed files and folders in the default directory. As I remove the redirection part and set a breakpoint in debug mode, theoutput
variable is empty aftersh.readAll()
. No error shows after writing in QStringList, not as it would show:"wsl is not recognized as an internal or external command"
when writing in my originalQProcess::execute
way.` -
@JonB Thank you. Yes, I've tested in Command Prompt and it recognized
wsl
and listed files and folders in the default directory. As I remove the redirection part and set a breakpoint in debug mode, theoutput
variable is empty aftersh.readAll()
. No error shows after writing in QStringList, not as it would show:"wsl is not recognized as an internal or external command"
when writing in my originalQProcess::execute
way.` -
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
"C:\Windows\System32\wsl.exe ls >> res.txt"
Try to split this into 4 parameters instead of one
wrote on 29 Aug 2022, 08:13 last edited by@jsulm Thank you. The res.txt is still empty after I separate the command into
sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe" << "ls" << ">>" << "res.txt");
.@JonB said in How to use Windows QT to call WSL cmd?:
waitForFinished
-
@JonB Thank you. Yes, I've tested in Command Prompt and it recognized
wsl
and listed files and folders in the default directory. As I remove the redirection part and set a breakpoint in debug mode, theoutput
variable is empty aftersh.readAll()
. No error shows after writing in QStringList, not as it would show:"wsl is not recognized as an internal or external command"
when writing in my originalQProcess::execute
way.`wrote on 29 Aug 2022, 08:24 last edited by JonB@NTU_WTY said in How to use Windows QT to call WSL cmd?:
No error shows after writing in QStringList, not as it would show: "wsl is not recognized as an internal or external command" when writing in my original QProcess::execute way.`
What do you mean by this? If you are saying you originally used
QProcess::execute("C:\\Windows\\System32\\wsl.exe", ...)
or"wsl"
or"cmd /c ..."
or whatever and got"wsl is not recognized as an internal or external command"
then please show what exact command you did that way.Your latest reply does not say what returned from
waitForFinished
(cut off)?I trust you really tried
cmd /c C:\Windows\System32\wsl.exe
verbatim in a Command Prompt?If you cannot resolve this, stop using
waitForFinished
, hook up all the signals fromQProcess
and see what is happening. Like I wrote earlier, start by diagnosing/getting it working without the file redirection. -
@NTU_WTY
I would still put in fuller error checking (look at the docs forQProcess
). For a start, what is the return result fromsh.waitForFinished();
?wrote on 29 Aug 2022, 08:26 last edited by@JonB It's
true
. I also check readAllStandardError() but I'm not sure I wrote it correctly:qDebug() << sh.readAllStandardError();
, and it prints:"'C:\\Windows\\System32\\wsl.exe' \xA4\xA3\xACO\xA4\xBA\xB3\xA1\xA9\xCE\xA5~\xB3\xA1\xA9R\xA5O\xA1""B\xA5i\xB0\xF5\xA6\xE6\xAA\xBA\xB5{\xA6\xA1\xA9\xCE\xA7\xE5\xA6\xB8\xC0\xC9\xA1""C\r\n
-
@JonB It's
true
. I also check readAllStandardError() but I'm not sure I wrote it correctly:qDebug() << sh.readAllStandardError();
, and it prints:"'C:\\Windows\\System32\\wsl.exe' \xA4\xA3\xACO\xA4\xBA\xB3\xA1\xA9\xCE\xA5~\xB3\xA1\xA9R\xA5O\xA1""B\xA5i\xB0\xF5\xA6\xE6\xAA\xBA\xB5{\xA6\xA1\xA9\xCE\xA7\xE5\xA6\xB8\xC0\xC9\xA1""C\r\n
wrote on 29 Aug 2022, 08:35 last edited by JonB@NTU_WTY
That looks worrying to me! Whatever it's supposed to be, the fact that something is even echoing back'C:\\Windows\\System32\\wsl.exe' ...
looks like some kind of error to me....I have asked several times what exactly you tested in Command Prompt....
Oh, and a huge "BTW" when you do use the redirection and say
res.txt is still empty
: where are you looking, what do you think the current working directory of your Qt app is? Have you checked with specifying an absolute path?Please stop trying the redirection for a while, it only complicates. Try one of these:
sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls");
sh.start("C:\\Windows\\System32\\wsl.exe", QStringList() << "ls");
Especially the second one. I would not use
waitFor...
, at least while I diagnosed, I would use the signals/slots including for errors, as I wrote earlier. -
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
No error shows after writing in QStringList, not as it would show: "wsl is not recognized as an internal or external command" when writing in my original QProcess::execute way.`
What do you mean by this? If you are saying you originally used
QProcess::execute("C:\\Windows\\System32\\wsl.exe", ...)
or"wsl"
or"cmd /c ..."
or whatever and got"wsl is not recognized as an internal or external command"
then please show what exact command you did that way.Your latest reply does not say what returned from
waitForFinished
(cut off)?I trust you really tried
cmd /c C:\Windows\System32\wsl.exe
verbatim in a Command Prompt?If you cannot resolve this, stop using
waitForFinished
, hook up all the signals fromQProcess
and see what is happening. Like I wrote earlier, start by diagnosing/getting it working without the file redirection.wrote on 29 Aug 2022, 09:13 last edited byNo error shows after writing in QStringList, not as it would show: "wsl is not recognized as an internal or external command" when writing in my original QProcess::execute way.`
What do you mean by this? If you are saying you originally used
QProcess::execute("C:\\Windows\\System32\\wsl.exe", ...)
or"wsl"
or"cmd /c ..."
or whatever and got"wsl is not recognized as an internal or external command"
then please show what exact command you did that way.QProcess::execute("cmd /c wsl ls")
QProcess::execute("cmd /c C:/Windows/System32/wsl.exe ls");
I wrote in above ways that both not recognizedwsl
. But if I open the cmd prompt, power shell, or MinGW terminal, they all recognizewsl
.About the following two lines:
sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls");
sh.start("C:\\Windows\\System32\\wsl.exe", QStringList() << "ls");
They will get
false
returned fromwaitForFinished
immediately. But thereadAllStandardError()
shows empty. (Previoustrue
also immediately. Not sure what does that mean...)
Sorry I don't know how to "hook up all signals fromQProcess
". Can you give me more hint when you have time? Thank you very much. -
No error shows after writing in QStringList, not as it would show: "wsl is not recognized as an internal or external command" when writing in my original QProcess::execute way.`
What do you mean by this? If you are saying you originally used
QProcess::execute("C:\\Windows\\System32\\wsl.exe", ...)
or"wsl"
or"cmd /c ..."
or whatever and got"wsl is not recognized as an internal or external command"
then please show what exact command you did that way.QProcess::execute("cmd /c wsl ls")
QProcess::execute("cmd /c C:/Windows/System32/wsl.exe ls");
I wrote in above ways that both not recognizedwsl
. But if I open the cmd prompt, power shell, or MinGW terminal, they all recognizewsl
.About the following two lines:
sh.start("cmd", QStringList() << "/c" << "C:\\Windows\\System32\\wsl.exe ls");
sh.start("C:\\Windows\\System32\\wsl.exe", QStringList() << "ls");
They will get
false
returned fromwaitForFinished
immediately. But thereadAllStandardError()
shows empty. (Previoustrue
also immediately. Not sure what does that mean...)
Sorry I don't know how to "hook up all signals fromQProcess
". Can you give me more hint when you have time? Thank you very much.wrote on 29 Aug 2022, 09:27 last edited by@NTU_WTY said in How to use Windows QT to call WSL cmd?:
I wrote in above ways that both not recognized wsl. But if I open the cmd prompt, power shell, or MinGW terminal, they all recognize wsl.
Then you have a problem. This is my final time of asking: copy and paste, or show me a screenshot, of precisely what you are trying in a Command Prompt. Do not tell me "they work", show me what you are trying, character for character.
Sorry I don't know how to "hook up all signals from QProcess"
At minimum connect a slot to void QProcess::errorOccurred(QProcess::ProcessError error):
- Make your
QProcess sh;
a class member variable, at least temporarily, so it stays in scope. - Start with:
connect(&sh, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) { qDebug() << error; })
, we'll see whether we need any further ones depending on that.
-
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
I wrote in above ways that both not recognized wsl. But if I open the cmd prompt, power shell, or MinGW terminal, they all recognize wsl.
Then you have a problem. This is my final time of asking: copy and paste, or show me a screenshot, of precisely what you are trying in a Command Prompt. Do not tell me "they work", show me what you are trying, character for character.
Sorry I don't know how to "hook up all signals from QProcess"
At minimum connect a slot to void QProcess::errorOccurred(QProcess::ProcessError error):
- Make your
QProcess sh;
a class member variable, at least temporarily, so it stays in scope. - Start with:
connect(&sh, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) { qDebug() << error; })
, we'll see whether we need any further ones depending on that.
wrote on 29 Aug 2022, 09:44 last edited by@JonB said in How to use Windows QT to call WSL cmd?:
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
I wrote in above ways that both not recognized wsl. But if I open the cmd prompt, power shell, or MinGW terminal, they all recognize wsl.
Then you have a problem. This is my final time of asking: copy and paste, or show me a screenshot, of precisely what you are trying in a Command Prompt. Do not tell me "they work", show me what you are trying, character for character.
- Make your
-
@JonB said in How to use Windows QT to call WSL cmd?:
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
I wrote in above ways that both not recognized wsl. But if I open the cmd prompt, power shell, or MinGW terminal, they all recognize wsl.
Then you have a problem. This is my final time of asking: copy and paste, or show me a screenshot, of precisely what you are trying in a Command Prompt. Do not tell me "they work", show me what you are trying, character for character.
wrote on 29 Aug 2022, 09:51 last edited by@NTU_WTY
So all you have proved is thatwsl ls
works from that Command Prompt. Which is not the same as the command you are trying to issue from your Qt program, is it? Maybe it'swsl.exe
, maybe it's not. Maybe it's inC:\Windows\System32
, maybe it's not.Will you please try:
cmd /c "C:\Windows\System32\wsl.exe ls"
in a Command Prompt.
After that, try the error code I showed earlier.
-
@NTU_WTY
So all you have proved is thatwsl ls
works from that Command Prompt. Which is not the same as the command you are trying to issue from your Qt program, is it? Maybe it'swsl.exe
, maybe it's not. Maybe it's inC:\Windows\System32
, maybe it's not.Will you please try:
cmd /c "C:\Windows\System32\wsl.exe ls"
in a Command Prompt.
After that, try the error code I showed earlier.
wrote on 29 Aug 2022, 10:34 last edited by@JonB
Sorry that I choose the wrong terminal. The following is my "C:\Windows\System32\wsl.exe" result:
If I directly type:
cmd /c "C:\Windows\System32\wsl.exe ls"
in the search input, the terminal will flash out (successfully show and close). So I modified to:cmd /k "C:\Windows\System32\wsl.exe ls"
, it opens the terminal and lists all the files inside.
I also tried:cmd /k "C:\Windows\System32\wsl.exe pwd"
, and it returns,
where/mnt/c
is the correct representation of the pathC:\
inwsl
.About the slot, I think I need more time to digest, thank you~
-
@JonB
Sorry that I choose the wrong terminal. The following is my "C:\Windows\System32\wsl.exe" result:
If I directly type:
cmd /c "C:\Windows\System32\wsl.exe ls"
in the search input, the terminal will flash out (successfully show and close). So I modified to:cmd /k "C:\Windows\System32\wsl.exe ls"
, it opens the terminal and lists all the files inside.
I also tried:cmd /k "C:\Windows\System32\wsl.exe pwd"
, and it returns,
where/mnt/c
is the correct representation of the pathC:\
inwsl
.About the slot, I think I need more time to digest, thank you~
wrote on 29 Aug 2022, 10:52 last edited by@NTU_WTY said in How to use Windows QT to call WSL cmd?:
If I directly type: cmd /c "C:\Windows\System32\wsl.exe ls" in the search input
In what "search input"? The Windows desktop Start button area, or similar? I asked you to type into a Command Prompt...! Never mind, I get the gist, it looks like the full path does work, that in itself is not the issue.
Yes you should try the code with signal/slot I showed earlier.
You might also try e.g.
sh.start("cmd", QStringList() << "/c" << "echo Hello >> C:\\Temp\\tempfile.txt");
Please be sensible about the path, whatever works for you. Does this work?
-
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
If I directly type: cmd /c "C:\Windows\System32\wsl.exe ls" in the search input
In what "search input"? The Windows desktop Start button area, or similar? I asked you to type into a Command Prompt...! Never mind, I get the gist, it looks like the full path does work, that in itself is not the issue.
Yes you should try the code with signal/slot I showed earlier.
You might also try e.g.
sh.start("cmd", QStringList() << "/c" << "echo Hello >> C:\\Temp\\tempfile.txt");
Please be sensible about the path, whatever works for you. Does this work?
wrote on 29 Aug 2022, 13:36 last edited by@JonB said in How to use Windows QT to call WSL cmd?:
You might also try e.g.
sh.start("cmd", QStringList() << "/c" << "echo Hello >> C:\Temp\tempfile.txt");Please be sensible about the path, whatever works for you. Does this work?
Yes! It generates
tempfile
and alsoHello
inside this file. It only fails when related towsl
.I try to rewrite the code by mimicking from the doc:
QObject *parent; QString program = "cmd"; QStringList arguments; arguments << "/c" << "C:\\Windows\\System32\\wsl.exe" << "ls"; QProcess *sh = new QProcess(parent); sh->start(program, arguments); connect(sh, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) { qDebug() << error; });
It outputs this when the object is created:
21:17:42: C:/Users/USER/Documents/Code/Qt/build-testQT-Desktop_Qt_5_15_2_MinGW_32_bit-Debug/debug/testQT.exe crashed.
I'm not sure if I wrote it right. Thank you for your patience~ Please correct me and give me more hints! -
@JonB said in How to use Windows QT to call WSL cmd?:
You might also try e.g.
sh.start("cmd", QStringList() << "/c" << "echo Hello >> C:\Temp\tempfile.txt");Please be sensible about the path, whatever works for you. Does this work?
Yes! It generates
tempfile
and alsoHello
inside this file. It only fails when related towsl
.I try to rewrite the code by mimicking from the doc:
QObject *parent; QString program = "cmd"; QStringList arguments; arguments << "/c" << "C:\\Windows\\System32\\wsl.exe" << "ls"; QProcess *sh = new QProcess(parent); sh->start(program, arguments); connect(sh, &QProcess::errorOccurred, this, [](QProcess::ProcessError error) { qDebug() << error; });
It outputs this when the object is created:
21:17:42: C:/Users/USER/Documents/Code/Qt/build-testQT-Desktop_Qt_5_15_2_MinGW_32_bit-Debug/debug/testQT.exe crashed.
I'm not sure if I wrote it right. Thank you for your patience~ Please correct me and give me more hints!@NTU_WTY said in How to use Windows QT to call WSL cmd?:
QObject *parent;
This is dangling pointer!
If you do not need a parent then pass nullptr instead!QProcess *sh = new QProcess();
If you really want a proper parent then pass a pointer to an existing (allocated) object.
-
@NTU_WTY said in How to use Windows QT to call WSL cmd?:
QObject *parent;
This is dangling pointer!
If you do not need a parent then pass nullptr instead!QProcess *sh = new QProcess();
If you really want a proper parent then pass a pointer to an existing (allocated) object.
wrote on 29 Aug 2022, 14:19 last edited by@jsulm said in How to use Windows QT to call WSL cmd?:
This is dangling pointer!
If you do not need a parent then pass nullptr instead!
QProcess *sh = new QProcess();If you really want a proper parent then pass a pointer to an existing (allocated) object.
Thank you~ The code executed successfully without any messages after null ptr correction. So... what shall I do next to get some info from the process?
1/37