How can I add a path to the QProcess PATH environment variable? (PyQt5 on Python 3.7)
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
2. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# NEW: initialize the environment variables for self.__myProcess:
env = QProcessEnvironment.systemEnvironment()
self.__myProcess.setProcessEnvironment(env)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
add a comment |
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
2. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# NEW: initialize the environment variables for self.__myProcess:
env = QProcessEnvironment.systemEnvironment()
self.__myProcess.setProcessEnvironment(env)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
2
I think you're misunderstanding. You are trying to affect thePATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.
– JonBrave
Nov 23 '18 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 '18 at 10:29
add a comment |
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
2. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# NEW: initialize the environment variables for self.__myProcess:
env = QProcessEnvironment.systemEnvironment()
self.__myProcess.setProcessEnvironment(env)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
1. The problem explained
I instantiate a QProcess()
-object just before the application shows its main window. The QProcess()
-instance is stored in the self.__myProcess
variable, and stays alive as long as you can see the main window.
The main window looks like this:
When you click on the button, the following code executes:
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
The last two lines are quite clear: the command openocd.exe
is passed to self.__myProcess
and executes. What this executable actually does is not important here. In fact, I could use any random executable. The point is: if the executable is in my Windows PATH
environment variable, it gets found and executed.
Imagine the executable is NOT in the PATH
environment variable. Then the function self.__add_openocd_to_env()
should fix that issue:
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
However, I've noticed it has no effect at all. I have tried a lot of different things in this function, but it just won't have any effect.
You can find the full code here:
If you have Python 3 installed with PyQt5, you can simply copy-paste the code into a .py module and run it. You should see the little window with the pushbutton. Of course you should change the path "C:UsersKristof.." to something valid on your computer. You can choose any executable you like for this test.
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
env = self.__myProcess.processEnvironment()
env.insert("PATH", "C:\Users\Kristof\programs\openocd_0.10.0\bin;" + env.value("PATH"))
self.__myProcess.setProcessEnvironment(env)
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
2. My question
I know I could simply add "C:UsersKristofprogramsopenocd_0.10.0bin" to my Windows PATH
environment variable before instantiating the QProcess()
. But that's not the point. I want to know how to add it to the PATH
environment variable for that one specific QProcess()
-instance. If possible, it should not affect any other QProcess()
-instances around in my software, nor should it affect any future QProcess()
-instances I create later on.
3. System settings
I use the PyQt5 framework in Python 3.7 on Windows 10.
NOTE:
I've just tried to improve the QProcess()
setup in the following way:
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# NEW: initialize the environment variables for self.__myProcess:
env = QProcessEnvironment.systemEnvironment()
self.__myProcess.setProcessEnvironment(env)
I was hopefull ... but it still won't work :-(
python python-3.x process environment-variables qprocess
python python-3.x process environment-variables qprocess
edited Nov 22 '18 at 21:37
K.Mulier
asked Nov 22 '18 at 21:15
K.MulierK.Mulier
2,42512759
2,42512759
2
I think you're misunderstanding. You are trying to affect thePATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.
– JonBrave
Nov 23 '18 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 '18 at 10:29
add a comment |
2
I think you're misunderstanding. You are trying to affect thePATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.
– JonBrave
Nov 23 '18 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 '18 at 10:29
2
2
I think you're misunderstanding. You are trying to affect the
PATH
environment which gets passed to the sub-process. What you want to do is simply alter the PATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent's PATH
back after the sub-process has been spawned.– JonBrave
Nov 23 '18 at 9:12
I think you're misunderstanding. You are trying to affect the
PATH
environment which gets passed to the sub-process. What you want to do is simply alter the PATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent's PATH
back after the sub-process has been spawned.– JonBrave
Nov 23 '18 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 '18 at 10:29
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 '18 at 10:29
add a comment |
2 Answers
2
active
oldest
votes
Based on the comment of Mr. @JonBrave, I have written the following workaround:
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 '18 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 '18 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 '18 at 15:54
add a comment |
There is a solution using python subprocess.run() instead of QProcess.
In subprocess.run(), you can specify a set of environment variables (actually a dictionary) using the env
parameter. The idea is to take a copy of your original environment, modify the PATH variable, and pass the modified environment to subprocess.run, as follows:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env)
This still doesn't work: the remaining problem is that the environment (including the modified PATH variable) will be available in the subprocess but is not used to search for the openocd command. But that is easy to fix: subprocess.run also has a boolean shell
parameter (default False) that tells it to run the command in a shell. Since the shell will run in the subprocess, it will use the modified PATH to search for openocd. So working code is:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env, shell=True)
An alternative for shell=True is to use shutil.which (available in Python >= 3.3) to resolve the command. This will also work reliably when the command is given as a list of strings instead of a single string.
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
command = shutil.which("openocd", path = self.env.get('PATH', None))
subprocess.run([ command ], env=env)
add a comment |
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438065%2fhow-can-i-add-a-path-to-the-qprocess-path-environment-variable-pyqt5-on-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Based on the comment of Mr. @JonBrave, I have written the following workaround:
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 '18 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 '18 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 '18 at 15:54
add a comment |
Based on the comment of Mr. @JonBrave, I have written the following workaround:
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 '18 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 '18 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 '18 at 15:54
add a comment |
Based on the comment of Mr. @JonBrave, I have written the following workaround:
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
Based on the comment of Mr. @JonBrave, I have written the following workaround:
import sys
import os
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class CustomMainWindow(QMainWindow):
def __init__(self):
super(CustomMainWindow, self).__init__()
# -------------------------------- #
# QProcess() setup #
# -------------------------------- #
self.__myProcess = QProcess()
self.__myProcess.setProcessChannelMode(QProcess.MergedChannels)
self.__myProcess.readyRead.connect(self.__on_output)
self.__myProcess.errorOccurred.connect(self.__on_error)
self.__myProcess.finished.connect(self.__on_exit)
# -------------------------------- #
# Window setup #
# -------------------------------- #
self.setGeometry(100, 100, 800, 200)
self.setWindowTitle("QProcess test")
self.__frm = QFrame(self)
self.__frm.setStyleSheet("QWidget { background-color: #ffffff }")
self.__lyt = QVBoxLayout()
self.__lyt.setAlignment(Qt.AlignTop)
self.__frm.setLayout(self.__lyt)
self.setCentralWidget(self.__frm)
self.__myBtn = QPushButton("START QPROCESS()")
self.__myBtn.clicked.connect(self.__btn_clicked)
self.__myBtn.setFixedHeight(70)
self.__myBtn.setFixedWidth(200)
self.__lyt.addWidget(self.__myBtn)
self.show()
def __add_openocd_to_env(self):
self.__oldEnv = os.environ["PATH"]
os.environ["PATH"] = "C:\Users\Kristof\Dropbox (Personal)\EMBEDOFFICE\embedoffice\resources\programs\openocd_0.10.0_dev00459\bin;" + self.__oldEnv
def __remove_openocd_from_env(self):
os.environ["PATH"] = self.__oldEnv
def __btn_clicked(self):
self.__add_openocd_to_env()
command = "openocd.exe" + 'rn'
self.__myProcess.start(command)
self.__myProcess.waitForStarted(-1)
self.__remove_openocd_from_env()
def __on_output(self):
data = bytes(self.__myProcess.readAll()).decode().replace('rn', 'n')
print(data)
def __on_error(self, error):
print("")
print("Process error: {0}".format(str(error)))
print("")
def __on_exit(self, exitCode, exitStatus):
print("")
print("ExitCode = {0}".format(str(exitCode)))
print("ExitStatus = {0}".format(str(exitStatus)))
print("")
if __name__ == '__main__':
app = QApplication(sys.argv)
QApplication.setStyle(QStyleFactory.create('Fusion'))
myGUI = CustomMainWindow()
sys.exit(app.exec_())
Basically I'm doing the following: just before ordering the QProcess()
-instance to start a command, I add the executable path to the PATH
environment variable that belongs to the whole Python session. Once the command has started, I can remove it again so it won't have an effect on other QProcess()
-instances created in the future.
It works, but it will certainly require a lot of "bookkeeping" if I'm going to apply that approach in my software (many QProcess()
-instances live in my software). If you find a better approach, please don't hesitate to share!
answered Nov 23 '18 at 11:02
K.MulierK.Mulier
2,42512759
2,42512759
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 '18 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 '18 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 '18 at 15:54
add a comment |
Looks good. Sorry, I don't have time to type an answer! You could probably call__remove_openocd_from_env()
straight afterstart()
, beforewaitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class fromQProcess
to use just for this case to avoid changing the others. Finally, you could do this from a.bat
file on yourPATH
/in your current directory which changes PATH before invokingopenocd.exe
, then it's in one place (and you can change the path) and you don't have to alterQProcess
... :)
– JonBrave
Nov 23 '18 at 11:45
Just noticed your code's:command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.
– JonBrave
Nov 23 '18 at 15:51
And finally, from the example you give, if you know that theexe
is located in the directory you're adding toPATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.
– JonBrave
Nov 23 '18 at 15:54
Looks good. Sorry, I don't have time to type an answer! You could probably call
__remove_openocd_from_env()
straight after start()
, before waitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class from QProcess
to use just for this case to avoid changing the others. Finally, you could do this from a .bat
file on your PATH
/in your current directory which changes PATH before invoking openocd.exe
, then it's in one place (and you can change the path) and you don't have to alter QProcess
... :)– JonBrave
Nov 23 '18 at 11:45
Looks good. Sorry, I don't have time to type an answer! You could probably call
__remove_openocd_from_env()
straight after start()
, before waitForStarted()
(which you then wouldn't need) to reduce changed-environment-exposure time (try it?). You could derive your own class from QProcess
to use just for this case to avoid changing the others. Finally, you could do this from a .bat
file on your PATH
/in your current directory which changes PATH before invoking openocd.exe
, then it's in one place (and you can change the path) and you don't have to alter QProcess
... :)– JonBrave
Nov 23 '18 at 11:45
Just noticed your code's:
command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.– JonBrave
Nov 23 '18 at 15:51
Just noticed your code's:
command = "openocd.exe" + 'rn'
. Take out that CRLF stuff, it's got no place in issuing an OS command.– JonBrave
Nov 23 '18 at 15:51
And finally, from the example you give, if you know that the
exe
is located in the directory you're adding to PATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.– JonBrave
Nov 23 '18 at 15:54
And finally, from the example you give, if you know that the
exe
is located in the directory you're adding to PATH
, and the exe itself does not need the PATH to be changed for its own purposes, just make the full path to the exe yourself and invoke it that way, much simpler.– JonBrave
Nov 23 '18 at 15:54
add a comment |
There is a solution using python subprocess.run() instead of QProcess.
In subprocess.run(), you can specify a set of environment variables (actually a dictionary) using the env
parameter. The idea is to take a copy of your original environment, modify the PATH variable, and pass the modified environment to subprocess.run, as follows:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env)
This still doesn't work: the remaining problem is that the environment (including the modified PATH variable) will be available in the subprocess but is not used to search for the openocd command. But that is easy to fix: subprocess.run also has a boolean shell
parameter (default False) that tells it to run the command in a shell. Since the shell will run in the subprocess, it will use the modified PATH to search for openocd. So working code is:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env, shell=True)
An alternative for shell=True is to use shutil.which (available in Python >= 3.3) to resolve the command. This will also work reliably when the command is given as a list of strings instead of a single string.
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
command = shutil.which("openocd", path = self.env.get('PATH', None))
subprocess.run([ command ], env=env)
add a comment |
There is a solution using python subprocess.run() instead of QProcess.
In subprocess.run(), you can specify a set of environment variables (actually a dictionary) using the env
parameter. The idea is to take a copy of your original environment, modify the PATH variable, and pass the modified environment to subprocess.run, as follows:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env)
This still doesn't work: the remaining problem is that the environment (including the modified PATH variable) will be available in the subprocess but is not used to search for the openocd command. But that is easy to fix: subprocess.run also has a boolean shell
parameter (default False) that tells it to run the command in a shell. Since the shell will run in the subprocess, it will use the modified PATH to search for openocd. So working code is:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env, shell=True)
An alternative for shell=True is to use shutil.which (available in Python >= 3.3) to resolve the command. This will also work reliably when the command is given as a list of strings instead of a single string.
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
command = shutil.which("openocd", path = self.env.get('PATH', None))
subprocess.run([ command ], env=env)
add a comment |
There is a solution using python subprocess.run() instead of QProcess.
In subprocess.run(), you can specify a set of environment variables (actually a dictionary) using the env
parameter. The idea is to take a copy of your original environment, modify the PATH variable, and pass the modified environment to subprocess.run, as follows:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env)
This still doesn't work: the remaining problem is that the environment (including the modified PATH variable) will be available in the subprocess but is not used to search for the openocd command. But that is easy to fix: subprocess.run also has a boolean shell
parameter (default False) that tells it to run the command in a shell. Since the shell will run in the subprocess, it will use the modified PATH to search for openocd. So working code is:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env, shell=True)
An alternative for shell=True is to use shutil.which (available in Python >= 3.3) to resolve the command. This will also work reliably when the command is given as a list of strings instead of a single string.
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
command = shutil.which("openocd", path = self.env.get('PATH', None))
subprocess.run([ command ], env=env)
There is a solution using python subprocess.run() instead of QProcess.
In subprocess.run(), you can specify a set of environment variables (actually a dictionary) using the env
parameter. The idea is to take a copy of your original environment, modify the PATH variable, and pass the modified environment to subprocess.run, as follows:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env)
This still doesn't work: the remaining problem is that the environment (including the modified PATH variable) will be available in the subprocess but is not used to search for the openocd command. But that is easy to fix: subprocess.run also has a boolean shell
parameter (default False) that tells it to run the command in a shell. Since the shell will run in the subprocess, it will use the modified PATH to search for openocd. So working code is:
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
subprocess.run("openocd", env=env, shell=True)
An alternative for shell=True is to use shutil.which (available in Python >= 3.3) to resolve the command. This will also work reliably when the command is given as a list of strings instead of a single string.
env = os.environ.copy()
env['PATH'] = "C:\Users\Kristof\programs\openocd_0.10.0\bin"
+ os.pathsep + env['PATH']
command = shutil.which("openocd", path = self.env.get('PATH', None))
subprocess.run([ command ], env=env)
edited Jan 3 at 19:12
answered Jan 3 at 14:45
ygramoelygramoel
12110
12110
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53438065%2fhow-can-i-add-a-path-to-the-qprocess-path-environment-variable-pyqt5-on-python%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
2
I think you're misunderstanding. You are trying to affect the
PATH
environment which gets passed to the sub-process. What you want to do is simply alter thePATH
environment in the parent, it is that which needs to find your executable before the sub-process can get spawned. And if you want to, then change your parent'sPATH
back after the sub-process has been spawned.– JonBrave
Nov 23 '18 at 9:12
Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?
– K.Mulier
Nov 23 '18 at 10:29