PowerShell Subprocess, запущенный через Debugpy, не наследует переменные среды (но cmd.exe делает)Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 PowerShell Subprocess, запущенный через Debugpy, не наследует переменные среды (но cmd.exe делает)

Сообщение Anonymous »

Проблема
Я сталкиваюсь с проблемой, в которой запуск PowerShell через подпроцесс Python.popen () работает, как и ожидалось во время обычного выполнения, но в режиме отладки (с использованием переменных среды Demaugpy/Cursor) (например, Programfiles и LocalAppdata ). Напротив, когда я запускаю команду CMD (например, Echo %Programfiles %), переменные среды правильно наследуют. /> < /ul>

Что я протестировал (v1) < /h3>
Я создал небольшую тестовую программу с тремя функциями: одна для PowerShell с опцией -noprofile < /code> (одна

Код: Выделить всё

print_psh
), один для PowerShell без этой опции (

Код: Выделить всё

print_psh_with_profile
) и один для CMD (

Код: Выделить всё

print_cmd
). Я также сделал вариант (

Код: Выделить всё

print_psh_with_profile_inject_env
) где я прохожу env = os.environ.copy () явно.

[*] Это версия до @mklement0, упомянутая о Shell . />

Код: Выделить всё

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>

 output (v1) < /h3>
 Нормальное выполнение (режим не-дебуг): < /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>
 режим отладки (используя 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>

 Что я протестировал (v2) < /h3>
Я изменил код более точным, тогда я получил новую ошибку и подсказку. < /p>

 Это версия перед @mklement. False 
во всех print_psh Семейство, потому что может быть уверено, что выражение PowerShell ' не рассматривается как команда cmd.exe.

Код: Выделить всё

...
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>
Добавьте этот код в начале кода v1.+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>

 output (v2) < /h3>
 Нормальное выполнение (режим не-дебуг): < /h4>
(Same as V1)
< /code>
 режим отладки (с помощью 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>

 Проверка в подсказке Miniconda PowerShell.
[list]
 Активируйте виртуальную среду. < /li>
 Запустите команду в подсказке. Подождите, чтобы прикрепить вручную. < /Li>
< /ol>
< /li>
< /ul>
python -m debugpy --listen 5678 --wait-for-client ./{source_file}.py.`
< /code>

 Создать задачу запуска (.vscode/launch.json
)
[/list]

Код: Выделить всё

...
{
"name": "Python: Attach",
"type": "python",
"request": "attach",
"connect": {
"host": "localhost",
"port": 5678
},
"pathMappings": [
{
"localRoot": "${workspaceFolder}",
"remoteRoot": "."
}
],
"justMyCode": true
}
...
< /code>

[*] Прикрепите pydebug из vscode. < /li>
< /ol>
 Режим отладки (с использованием вручную декажи(Same as Normal Execution)
Что я попробовал

(v1) Удаление -noprofile Не изменило результат в режиме отладки.
[*] (v1) Пропустить env = os.environ.copy () explicitly также не имел эффекта. CMD (через Echo %Programfiles %), переменные среды правильно унаследованы.
[*] Новое! (V2) Popen PowerShell с Shell = FALSE опция приведет к ошибке fiLenotFound, хотя и не с Shell = ture .
[*] Новое! (V2) Это может быть связано с любым влиянием на интегрированную комбинацию терминала и пидбуга VSCODE, и это может быть специфичным для моей среды. (@Grismar проверил его в той же средне, но не воспроизводил проблему) Подпроцессы CMD наследуют настройки среды. На запуске.json), чтобы убедиться, что полная среда передается в PowerShell даже в режиме отладки? Автоматически загружайте и запустите совместимую версию Chromedriver в сценарии, запущенном под Debugpy. Я заметил, что webdriver_manager не смог обнаружить установленную версию Chrome в моей системе. При более внимательном рассмотрении я обнаружил, что он внутренне пытается получить версию Chrome с использованием команд PowerShell (например, доступ к ключам реестра или путям файлов, которые полагаются на переменные среды, такие как Programfiles ).
, чтобы понять, почему это не удалось только в режиме отладки, я проследил сбором Call и нашел, что он в конечном итоге достигает подпрограммы. PowerShell. Это заставило меня проверить минимальные воспроизводимые примеры с использованием Popen непосредственно, когда я обнаружил, что в разделе Debugpy переменные среды, ожидаемые PowerShell, необъяснимым образом отсутствуют, в то время как один и тот же код ведет себя правильно вне режима отладки или при вызове CMD
sext in shablemels in shabrelse in shablis in shablemels debugels in shablemels
. Запущен в среде, в которой отсутствуют важные переменные, такие как ProgramFiles или localappdata .
Enviorment (редактор)

VSCode 1.96.2
[*] (последнее в 2025/16)

(последнее в 2025/16)

(последнее в 2025/16)

(последнее в 2025/16)
/> python @2025.4.0 < /li>
Python Debugger @2025.4.11 < /li>
pylance @2025.4.1 < /li>
< /ul>
< /li>
< /u>

Подробнее здесь: https://stackoverflow.com/questions/795 ... -variables
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • PowerShell Subprocess, запущенный через Debugpy, не наследует переменные среды (но cmd.exe делает)
    Anonymous » » в форуме Python
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • PowerShell Subprocess, запущенный через Debugpy, не наследует переменные среды (но cmd.exe делает)
    Anonymous » » в форуме Python
    0 Ответы
    9 Просмотры
    Последнее сообщение Anonymous
  • A.exe, запущенный из cmd, не видит входные файлы
    Anonymous » » в форуме C++
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • A.exe, запущенный из cmd, не видит входные файлы
    Anonymous » » в форуме C++
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • A.exe, запущенный из cmd, не видит входные файлы
    Anonymous » » в форуме C++
    0 Ответы
    11 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»