How can I add a path to the QProcess PATH environment variable? (PyQt5 on Python 3.7)












0















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:



enter image description here



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 :-(
 

 










share|improve this question




















  • 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













  • Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?

    – K.Mulier
    Nov 23 '18 at 10:29
















0















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:



enter image description here



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 :-(
 

 










share|improve this question




















  • 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













  • Hi @JonBrave, you have a point there. Could you perhaps illustrate with an example?

    – K.Mulier
    Nov 23 '18 at 10:29














0












0








0








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:



enter image description here



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 :-(
 

 










share|improve this question
















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:



enter image description here



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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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














  • 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













  • 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












2 Answers
2






active

oldest

votes


















1














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!






share|improve this answer
























  • 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











  • 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



















0














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)





share|improve this answer


























    Your Answer






    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    1














    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!






    share|improve this answer
























    • 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











    • 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
















    1














    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!






    share|improve this answer
























    • 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











    • 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














    1












    1








    1







    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!






    share|improve this answer













    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!







    share|improve this answer












    share|improve this answer



    share|improve this answer










    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 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











    • 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



















    • 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











    • 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

















    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













    0














    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)





    share|improve this answer






























      0














      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)





      share|improve this answer




























        0












        0








        0







        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)





        share|improve this answer















        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)






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 3 at 19:12

























        answered Jan 3 at 14:45









        ygramoelygramoel

        12110




        12110






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()