Как CreateProcess находит исполняемый файл? - PullRequest
4 голосов
/ 25 апреля 2011

Согласно документации, CreateProcess может быть передано имя исполняемого файла в качестве первого аргумента или командная строка в качестве второго аргумента (из которого будет извлечено имя исполняемого файла).

Если вы передадите имя исполняемого файла, в документах будет указано, что PATH не будет найдено.

Если вы передадите вместо командной строки первый извлеченный токен, который будет использоваться в качестве имени исполняемого файла, а PATH будетдолжен быть найден.

В моем случае, однако, мой вызов CreateProcess --- только с командной строкой и с измененной средой - не находит искомый исполняемый файл.Это будет успешно выполнено только в том случае, если я предшествую командной строке cmd.exe /c (я понимаю, почему она работает таким образом).

Для полноты, на самом деле я не использую Windows API напрямую, а subprocess.Popen в Python,хотя я думаю, что я сузил проблему до вышеуказанных обстоятельств.С shell = True правильная среда подобрана;с shell = False (мой желаемый способ создания подпроцесса), вызов не может найти мой исполняемый файл.Исполняемый файл - это отдельный exe-файл, а не внутренняя команда cmd.exe.

Может кто-нибудь подсказать, что я здесь делаю неправильно или в чем мое недоразумение?

Пример кода:

from subprocess import Popen
import os, sys

exe = "wc.exe" # No other wc.exe on the PATH
env = os.environ.copy()
new_path = os.path.expandvars(r"%HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin;%PATH%")
env["PATH"] = os.path.expandvars(new_path).encode(sys.getfilesystemencoding())

Popen(
     args=[exe, "*.*"],
     env=env,
     # shell=True # Works if you uncomment this line.
)

Ответы [ 3 ]

3 голосов
/ 25 апреля 2011

Вам нужно изменить среду текущего процесса, если вы хотите, чтобы CreateProcess его увидел.В настоящее время подоболочка (включенная в командную строку или запрошенная через shell=True) видит вашу измененную среду, но прямой вызов CreateProcess - нет.

0 голосов
/ 25 апреля 2011

Если я правильно понял ваш вопрос, похоже, у вас есть приложение с именем wc.exe в папке, в которую %HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin отображается.Если это так, вам лучше установить exe на расширенную версию %HOMEDRIVE%%HOMEPATH%\SmallApps\GnuWin32\bin\wc.exe.Поскольку этот путь и имя исполняемого файла могут в конечном итоге содержать пробелы, не мешало бы также заключить его в кавычки.

Короче, не полагайтесь на поиск пути.Он не только подвержен ошибкам, но и является потенциальной дырой в безопасности.

0 голосов
/ 25 апреля 2011

Мысль о проверке MSDN? CreateProcess документация.

Процитирую одну его часть:

Каталог, из которого загружено приложение. Текущий каталог для родительского процесса. 32-разрядный системный каталог Windows. Используйте функцию GetSystemDirectory, чтобы получить путь к этому каталогу. 16-битный системный каталог Windows. Не существует функции, которая получает путь к этому каталогу, но она ищется. Название этого каталога - System. Каталог Windows. Используйте функцию GetWindowsDirectory, чтобы получить путь к этому каталогу. Каталоги, перечисленные в переменной среды PATH. Обратите внимание, что эта функция не выполняет поиск пути для приложения, указанного в разделе реестра «Путь к приложению». Чтобы включить этот путь для каждого приложения в последовательность поиска, используйте функцию ShellExecute.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...