Ich begegne ein Problem, bei dem das Starten von PowerShell über Pythons Subprozess.Popen () wie erwartet während der normalen Ausführung erwartet, aber im Debug -Modus (mit Debugpy/Cursor) die Schlüsselvariablen (z. Wenn ich im Gegensatz dazu einen CMD -Befehl ausführe (z. B. echo %Programmfiles %), werden die Umgebungsvariablen korrekt vererbt. /> < /ul>
Was ich getestet habe (v1) < /h3>
Ich habe ein kleines Testprogramm mit drei Funktionen erstellt: eine für PowerShell mit der Option -noprofile < /code> (Option (code>
Code: Select all
print_psh
Code: Select all
print_psh_with_profile
Code: Select all
print_cmd
Code: Select all
print_psh_with_profile_inject_env
Code: Select all
import subprocess
import os
def print_psh(cmd):
with subprocess.Popen(
"powershell -NoProfile " + '"' +
f"$ErrorActionPreference='silentlycontinue'; $tmp = ({cmd}); if ($tmp){{echo $tmp; Exit;}}" + '"',
stdout=subprocess.PIPE,
stdin=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
shell=True, # Is the "powershell" expression recognized as a CMD.exe command? This returns nothing, but it works without error.(see the description about *V2* code)
) as stream:
cmm = stream.communicate()
stdout = cmm[0].decode()
print(f"NoProfile: {cmd} = {stdout}")
def print_psh_with_profile(cmd):
with subprocess.Popen(
"powershell " + '"' +
f"$ErrorActionPreference='silentlycontinue'; $tmp = ({cmd}); if ($tmp){{echo $tmp; Exit;}}" + '"',
stdout=subprocess.PIPE,
stdin=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
shell=True, # Is the "powershell" expression recognized as a CMD.exe command? This returns nothing, but it works without error.(see the description about *V2* code)
) as stream:
cmm = stream.communicate()
stdout = cmm[0].decode()
print(f"WithProfile: {cmd} = {stdout}")
def print_psh_with_profile_inject_env(cmd):
with subprocess.Popen(
"powershell " + '"' +
f"$ErrorActionPreference='silentlycontinue'; $tmp = ({cmd}); if ($tmp){{echo $tmp; Exit;}}" + '"',
stdout=subprocess.PIPE,
stdin=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
shell=True, # Is the "powershell" expression recognized as a CMD.exe command? This returns nothing, but it works without error.(see the description about *V2* code)
env=os.environ.copy(),
) as stream:
cmm = stream.communicate()
stdout = cmm[0].decode()
print(f"WithProfile(inject env): {cmd} = {stdout}")
def print_cmd(cmd):
with subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stdin=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
shell=True, # use commandline commands.
) as stream:
cmm = stream.communicate()
stdout = cmm[0].decode()
print(f"CMD.EXE: {cmd} = {stdout}")
print_psh("$env:PROGRAMFILES")
print_psh("$env:LOCALAPPDATA")
print_cmd("echo %PROGRAMFILES%")
print_cmd("echo %LOCALAPPDATA%")
print_psh_with_profile("$env:PROGRAMFILES")
print_psh_with_profile("$env:LOCALAPPDATA")
print_psh_with_profile_inject_env("$env:PROGRAMFILES")
print_psh_with_profile_inject_env("$env:LOCALAPPDATA")
< /code>
Ausgabe (v1) < /h3>
Normale Ausführung (Nicht-Debug-Modus): < /h4>
NoProfile: $env:PROGRAMFILES = C:\Program Files
NoProfile: $env:LOCALAPPDATA = C:\Users\(USERNAME)\AppData\Local
CMD.EXE: echo %PROGRAMFILES% = C:\Program Files
CMD.EXE: echo %LOCALAPPDATA% = C:\Users\(USERNAME)\AppData\Local
WithProfile: $env:PROGRAMFILES = [profile script output] ... C:\Program Files
WithProfile: $env:LOCALAPPDATA = [profile script output] ... C:\Users\(USERNAME)\AppData\Local
WithProfile(inject env): $env:PROGRAMFILES = C:\Program Files
WithProfile(inject env): $env:LOCALAPPDATA = C:\Users\(USERNAME)\AppData\Local
< /code>
Debug-Modus (mit Debugpy): < /h4>
NoProfile: $env:PROGRAMFILES =
NoProfile: $env:LOCALAPPDATA =
CMD.EXE: echo %PROGRAMFILES% = C:\Program Files
CMD.EXE: echo %LOCALAPPDATA% = C:\Users\(USERNAME)\AppData\Local
WithProfile: $env:PROGRAMFILES =
WithProfile: $env:LOCALAPPDATA =
WithProfile(inject env): $env:PROGRAMFILES =
WithProfile(inject env): $env:LOCALAPPDATA =
< /code>
Was ich getestet habe (v2) < /h3>
Ich habe den Code genauer geändert, dann habe ich einen neuen Fehler und Hinweis erhalten. False
Code: Select all
...
def print_psh...(cmd):
with subprocess.Popen(
"powershell -NoProfile " + '"' +
...
stderr=subprocess.DEVNULL,
- shell=True, # Is the "powershell" expression recognized as a CMD.exe command? This returns nothing, but it works without error.(see the description about *V2* code)
+ shell=False, # PowerShell commands are indirectlly called from a new process.
) as stream:
...
< /code>
Fügen Sie diesen Code zu Beginn des Code V1 hinzu.+def print_psh_test():
+ cmd = "powershell"
+ with subprocess.Popen(
+ cmd,
+ stdout=subprocess.PIPE,
+ stdin=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ shell=False, # PowerShell commands are indirectlly called from +a new process.
+ ) as stream:
+ cmm = stream.communicate()
+ print("test to run powershell.")
...
+print_psh_test()
print_psh("$env:PROGRAMFILES")
print_psh("$env:LOCALAPPDATA")
...
< /code>
Ausgabe (v2) < /h3>
Normale Ausführung (Nicht-Debug-Modus): < /h4>
(Same as V1)
< /code>
Debug-Modus (mit Debugpy): < /h4>
Exception has occurred: FileNotFoundError
[WinError 2] The system cannot find the file specified.
File "C:\...\{source_file}.py", line 6, in print_psh_test
with subprocess.Popen(
File "C:\...\{source_file}.py", line 71, in
print_psh_test()
FileNotFoundError: [WinError 2] The system cannot find the file specified.
< /code>
[*] Test in der Miniconda PowerShell -Eingabeaufforderung. Warten Sie, um manuell anzuhängen.python -m debugpy --listen 5678 --wait-for-client ./{source_file}.py.`
< /code>
[list]
Erstellen Sie die Startaufgabe (.vscode/launch.json
[/list]
Code: Select all
...
{
"name": "Python: Attach",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
],
"justMyCode": true
}
...
< /code>
[*] Fügen Sie den Pydebug aus VSCODE bei.(Same as Normal Execution)
(v1) Entfernen -noprofile änderte das Ergebnis in Debug -Modus nicht. CMD (über eCho %Programfiles %) werden die Umgebungsvariablen korrekt vererbt.
[*] Neu! (V2) Popen PowerShell mit Shell = False verursacht den fileNotFound -Fehler, obwohl nicht mit Shell = Ture .
Neu! (V2) Dies könnte auf jegliche Auswirkungen auf die integrierte Abschluss- und Pydebug -Kombination von VSCODE zurückzuführen sein und für meine Umgebung spezifisch sein. (@Grismar hat es in derselben Umgebung getestet, aber das Problem nicht reproduziert) < /li>
< /ul>
Meine Frage < /H3>
scheint, dass beim Laufen unter Debugpy, die in der erwarteten Debug -Umgebung, in der erwarteten Variablen, mit einer Umgebung, in der erwarteten Variablen, mit einer Umgebung, in der Debug -Debug, (The Leuldel Subs, The Lefting Subs), mit einer Umgebung mit einer Umwelt, die mit einer Umgebung gestartet wurde, mit einer Umwelt (oder dem Mangeln "(The Lefting Subs, The Lefting Subs", erscheint. CMD -Subprozesse erben die Umgebung normal. (z. B. im Start.json) Um sicherzustellen, dass die vollständige Umgebung auch im Debug -Modus an PowerShell übergeben wird? Webdriver_Manager , um eine kompatible Version von Chromedriver automatisch in einem unter Debugpy gestarteten Skript herunterzuladen und zu starten. Mir ist aufgefallen, dass WebDriver_Manager die installierte Chrome -Version in meinem System nicht erkannt hat. Bei näherer Betrachtung stellte ich fest, dass es intern versucht, die Chromversion unter Verwendung von PowerShell -Befehlen abzurufen (z. B. Zugriff auf Registrierungsschlüssel oder Dateipfade, die sich auf Umgebungsvariablen wie ProgramFiles ). Powershell. Dies führte mich dazu, minimal reproduzierbare Beispiele unter Verwendung von Popen direkt zu testen, wobei ich feststellte, dass von PowerShell unter Debugpy -Umgebungsvariablen unerklärlicherweise fehlen - während derselbe Code außerhalb des Debug -Modus korrekt verhält, wenn der Debug -Modus aufgerufen wird. startete in einer Umgebung, in der wesentliche Variablen wie Programmfiles < /code> oder localAppdata < /code>. /> Pylance < /li>
Python < /li>
Python -Debugger < /li>
< /ul>
< /li>
< /u>