Как программно запустить исполняемый файл с помощью Python

Раздел: ОС -> Работа с исполняемыми файлами

Основы запуска исполняемых файлов из Python

Запуск exe-файла из скрипта Python - частая задача при автоматизации, тестировании или интеграции сторонних утилит. Встроенные средства языка позволяют управлять процессом, передавать аргументы, обрабатывать вывод и ошибки. Ниже рассмотрены основные подходы, их преимущества и ограничения.

Какой модуль является наиболее надёжным и гибким для запуска exe-файлов?

Модуль subprocess - стандартное и рекомендуемое решение. Он предоставляет полный контроль над дочерним процессом: возможность дождаться завершения, получить stdout/stderr, задать тайм-аут и передать аргументы.


import subprocess

# Простейший запуск без ожидания
subprocess.Popen(['notepad.exe'])

# Запуск с ожиданием завершения
result = subprocess.run(['ping', '127.0.0.1'], capture_output=True, text=True)
print(result.stdout)

Open exe file python (открытие exe файла в python)

Функция run() (Python 3.5+) возвращает объект CompletedProcess. Для потокового вывода используйте Popen с коммуникацией.

Почему возникает ошибка FileNotFoundError при запуске?

Если exe-файл не находится в системной PATH или не указан полный путь, Python не найдёт его. Решение - передать абсолютный путь или использовать shutil.which() для поиска.


import shutil
path = shutil.which('myapp.exe')
if path:
    subprocess.run([path])
else:
    print('Файл не найден')

Как запустить exe-файл без возврата управления (асинхронно)?

Используйте subprocess.Popen без вызова wait() или communicate(). Процесс будет выполняться параллельно.


proc = subprocess.Popen(['calc.exe'])
# Скрипт продолжает работу, не дожидаясь закрытия калькулятора
print('Запущен калькулятор')

Как избежать зависания при запуске GUI-приложений из консоли?

Некоторые GUI-программы (например, блокнот) запускаются корректно, но другие могут ожидать завершения консольного родителя. Для Windows используйте CREATE_NO_WINDOW или флаг DETACHED_PROCESS.


import subprocess, os
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
proc = subprocess.Popen(['some_gui.exe'], startupinfo=startupinfo)

Как открыть exe-файл из Python средствами ОС (минимальный код)?

Функция os.system() запускает команду в командной оболочке. Подходит для простых одноразовых вызовов, но не даёт прямого доступа к stdout/stderr и может быть небезопасной при передаче аргументов от пользователя.


import os
exit_code = os.system('start notepad.exe')

На Windows os.startfile() открывает файл с помощью ассоциированного приложения, как двойной щелчок в проводнике.


import os
os.startfile('document.docx')  # откроется Word
os.startfile('script.exe')     # запустится исполняемый файл

Почему os.startfile() не работает с некоторыми exe-файлами?

Метод предназначен для открытия файлов по их расширению, а не для запуска произвольного приложения с аргументами. Для exe-файла он просто запускает его без возможности передачи параметров. Если нужно передать аргументы, используйте subprocess.

Как запустить exe-файл с использованием Windows API (низкоуровневый контроль)?

Модуль ctypes позволяет вызывать функции WinAPI, например CreateProcess. Это даёт максимальную гибкость, но требует больше кода и понимания внутренней механики.


import ctypes
from ctypes import wintypes

kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)

STARTF_USESHOWWINDOW = 0x00000001
SW_HIDE = 0

class STARTUPINFO(ctypes.Structure):
    _fields_ = [("cb", wintypes.DWORD),
                ("lpReserved", wintypes.LPWSTR),
                ("lpDesktop", wintypes.LPWSTR),
                ("lpTitle", wintypes.LPWSTR),
                ("dwX", wintypes.DWORD),
                ("dwY", wintypes.DWORD),
                ("dwXSize", wintypes.DWORD),
                ("dwYSize", wintypes.DWORD),
                ("dwXCountChars", wintypes.DWORD),
                ("dwYCountChars", wintypes.DWORD),
                ("dwFillAttribute", wintypes.DWORD),
                ("dwFlags", wintypes.DWORD),
                ("wShowWindow", wintypes.WORD),
                ("cbReserved2", wintypes.WORD),
                ("lpReserved2", ctypes.c_char_p),
                ("hStdInput", wintypes.HANDLE),
                ("hStdOutput", wintypes.HANDLE),
                ("hStdError", wintypes.HANDLE)]

class PROCESS_INFORMATION(ctypes.Structure):
    _fields_ = [("hProcess", wintypes.HANDLE),
                ("hThread", wintypes.HANDLE),
                ("dwProcessId", wintypes.DWORD),
                ("dwThreadId", wintypes.DWORD)]

si = STARTUPINFO()
si.cb = ctypes.sizeof(STARTUPINFO)
pi = PROCESS_INFORMATION()

kernel32.CreateProcessW(
    None, "calc.exe", None, None, False, 0, None, None, ctypes.byref(si), ctypes.byref(pi))

Этот подход редко оправдан, так как subprocess внутри использует те же механизмы, но с более простым интерфейсом.

Как обработать ошибки запуска: файл заблокирован, недостаточно прав?

Ошибки бывают разные:

  • PermissionError - файл недоступен из-за антивируса или ограничений. Проверьте права на каталог.
  • FileNotFoundError - неверный путь. Используйте os.path.exists() перед запуском.
  • OSError - проблемы с архитектурой (попытка запустить 64-битный exe из 32-битного Python). Решение - использовать соответствующую версию интерпретатора.
  • Зависание процесса - добавьте тайм-аут в subprocess.run() с параметром timeout.

try:
    result = subprocess.run(['myapp.exe'], timeout=10, capture_output=True)
except subprocess.TimeoutExpired:
    print('Процесс превысил лимит времени')
except FileNotFoundError:
    print('Исполняемый файл не найден')

Для большинства сценариев достаточно subprocess.run() или Popen(). Остальные методы полезны в специфических ситуациях: os.system() - для быстрых однострочников, os.startfile() - для открытия любых файлов, включая exe, без управления аргументами.

Расширенные примеры запуска exe-файлов в Python

1. Запуск с передачей аргументов и получением вывода

Пример

import subprocess
# Команда: ping -n 3 127.0.0.1
proc = subprocess.run(['ping', '-n', '3', '127.0.0.1'],
                      capture_output=True,
                      encoding='cp866')  # кодировка для русского вывода
print('STDOUT:', proc.stdout)
print('STDERR:', proc.stderr)
print('Код возврата:', proc.returncode)
STDOUT: Обмен пакетами с 127.0.0.1 по 32 байт:
Ответ от 127.0.0.1: число байт=32 время<1мс TTL=128
...
STDERR: 
Код возврата: 0

2. Асинхронный запуск с постепенным чтением вывода (потоковый режим)

Пример

import subprocess
proc = subprocess.Popen(['ping', 'google.com'],
                        stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT,
                        text=True)
for line in proc.stdout:
    print(line, end='')
proc.wait()

3. Запуск exe с переменными окружения

Пример

import subprocess, os
my_env = os.environ.copy()
my_env['MY_VAR'] = 'value'
subprocess.run(['myapp.exe'], env=my_env)

4. Использование subprocess.check_call() для проверки успешности

Пример

try:
    subprocess.check_call(['myapp.exe'])
    print('Успешно завершился с кодом 0')
except subprocess.CalledProcessError as e:
    print(f'Ошибка, код возврата {e.returncode}')

5. Запуск скрытого окна (GUI без консоли)

Пример

import subprocess
si = subprocess.STARTUPINFO()
si.dwFlags |= subprocess.STARTF_USESHOWWINDOW
si.wShowWindow = subprocess.SW_HIDE
proc = subprocess.Popen(['headless_app.exe'],
                        startupinfo=si,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)
stdout, stderr = proc.communicate()

6. Запуск с повышением привилегий (UAC) на Windows через shell32

Пример

import subprocess, sys
if sys.platform == 'win32':
    subprocess.run(['powershell', '-Command',
                    'Start-Process', 'installer.exe', '-Verb', 'runAs'])

7. Асинхронный запуск с использованием asyncio (Python 3.7+)

Пример

import asyncio

async def run_exe():
    proc = await asyncio.create_subprocess_exec(
        'ffmpeg', '-i', 'input.mp4', 'output.avi',
        stdout=asyncio.subprocess.PIPE,
        stderr=asyncio.subprocess.PIPE
    )
    stdout, stderr = await proc.communicate()
    print(f'Done, exit code {proc.returncode}')

asyncio.run(run_exe())

8. Запуск exe из памяти (загрузка бинарного кода) - редко, но возможно с ctypes

Пример

import ctypes, os
# Загрузка библиотеки (например, DLL) напрямую без exe
lib = ctypes.CDLL('mylib.dll')
lib.my_function()

Запуск exe из памяти (без файла на диске) требует низкоуровневого манипулирования WinAPI, что выходит за рамки обычных задач и не рекомендуется.

9. Запуск нескольких exe параллельно с ожиданием всех

Пример

import subprocess
procs = []
for i in range(3):
    p = subprocess.Popen(['sleeper.exe', str(i)])
    procs.append(p)
for p in procs:
    p.wait()
print('Все процессы завершены')

10. Получение дерева процессов (родитель-потомок)

Пример

import subprocess, psutil
proc = subprocess.Popen(['child.exe'])
parent = psutil.Process(proc.pid)
children = parent.children(recursive=True)
print([c.name() for c in children])

Эти примеры покрывают большинство практических сценариев. Выбор конкретного подхода зависит от требований к синхронизации, управлению окружением и платформе.

Открытие exe файла в Python - comments

En
Open exe file python (python)