Вопрос или проблема
Я собрал небольшую программу на Python, и у нее открыто это окно (консоль cmd), и я хотел бы сделать ее фоновым процессом или как-то скрыть от пользователя.
Да, я знаю, что могу скомпилировать свои файлы py с помощью –windowed, но это не рассматривается, так как это вызывает другие проблемы.
Я надеюсь на решение на PowerShell или Python. Любые советы или предложения будут полезны.
И нет, я не могу закрыть его (это закроет приложение, которое я хочу оставить открытым).
Ваши два самых простых варианта – это PowerShell и Windows Scripting Host.
Если вам нужна версия для скриптового хоста Windows, пожалуйста, уточните.
Powershell:
Вы используете командлет Start-Process
с флагом -WindowStyle hidden
.
Например:
Start-Process -WindowStyle hidden -FilePath python.exe -ArgumentList "c:\my_py_path\my_py_file.py"
Помните, что у вас не будет окна для закрытия. Чтобы завершить процесс, вам придется убить задачу.
Я ничего не знаю о Python и не могу разобрать изображения, которые вы привели, но PowerShell может скрыть любое окно, к которому вы можете получить дескриптор, если вы используете Add-Type
для вызова функции ShowWindow():
Add-Type @'
using System;
using System.Runtime.InteropServices;
public class API {
public enum SW : int {
Hide = 0,
Normal = 1,
ShowMinimized = 2,
Maximize = 3,
ShowNoActivate = 4,
Show = 5,
Minimize = 6,
ShowMinNoActive = 7,
ShowNA = 8,
Restore = 9,
Showdefault = 10,
Forceminimize = 11
}
[DllImport("user32.dll")]
public static extern int ShowWindow(IntPtr hwnd, SW nCmdShow);
}
'@
Скопируйте, вставьте и выполните приведенный выше код в окне PowerShell (или в скрипте), и окно сможет скрываться и показываться следующим образом:
$ThisWindow = [System.Diagnostics.Process]::GetCurrentProcess().MainwindowHandle
[API]::ShowWindow($ThisWindow,'Hide')
sleep -Seconds 5
[API]::ShowWindow($ThisWindow,'Show')
Дескрипторы других верхнего уровня окон можно получить с помощью Get-Process
или вызвав функции FindWindow()
.
Имейте в виду, что когда вы скрываете окно, процесс теряет его дескриптор (превращается в 0). Дескриптор окна по-прежнему является допустимым идентификатором, но команда Get-Process вернет 0 в свойстве MainWindowHandle.
Следовательно, вы не сможете показать его снова, если не сохранили дескриптор окна где-то (возможно, в реестре или в файле???).
В текущем скрипте дескриптор окна сохраняется внутри переменной $ThisWindow и по-прежнему доступен в области действия скрипта.
Но если вам нужно показать окно позже, вам потребуется немного больше программирования.
Макс
Ответ или решение
Когда возникает необходимость скрыть окно консоли Windows или отделить его от других окон, существует несколько подходов, которые мы можем использовать. Ваша задача — скрыть окно Python, которое при запуске открывает консоль, без использования параметра --windowed
, который приводит к другим проблемам. Рассмотрим возможные решения на основе PowerShell и Python.
Решение через PowerShell
Одним из самых прямых способов скрыть консольное окно является использование PowerShell, который предоставляет командлет Start-Process
. Однако данный метод просто скрывает окно при запуске нового процесса. Чтобы скрыть уже существующее окно, нам потребуется функция Windows API, а именно ShowWindow
, которую мы можем вызвать из PowerShell.
Шаги для реализации:
-
Добавление кода для работы с Windows API:
Сначала добавим тип, который позволит нам использовать функцию
ShowWindow
. В PowerShell выполните следующий код:Add-Type @" using System; using System.Runtime.InteropServices; public class API { public enum SW : int { Hide = 0, Show = 5 } [DllImport("user32.dll")] public static extern int ShowWindow(IntPtr hwnd, SW nCmdShow); } "@
-
Получение дескриптора окна:
Существует необходимость получить дескриптор основного окна вашего процесса. Вы можете сделать это с помощью следующего кода:
$ThisWindow = [System.Diagnostics.Process]::GetCurrentProcess().MainWindowHandle
-
Скрытие и отображение окна:
После получения дескриптора вы сможете скрыть и снова показать окно:
# Скрыть окно Start-Sleep -Seconds 5 # Подождите 5 секунд # Показать окно
Примечания:
-
Управление окнами: Когда вы скрываете окно, дескриптор процесса может поменяться, и вам нужно будет хранить его, если вы хотите снова показать окно. В примере выше мы сохраняем его в переменной
$ThisWindow
, которая остается доступной в рамках скрипта. -
Необходимость завершения процесса: Если вы используете вышеуказанный метод и необходимость в работе консольного окна исчезает, необходимо помнить, что закрытие процесса приведет к завершению всей программы. Чтобы завершить работу программы, не закрывая окно, вы можете использовать планировщик или другие подходы для управления задачами.
Альтернативное решение через Python
Если PowerShell по той или иной причине не подходит, вы можете дублировать логику в самом Python, используя модуль ctypes
, который позволит вам также вызвать функцию WinAPI ShowWindow
. Вот пример:
import ctypes
import time
import os
SW_HIDE = 0
SW_SHOW = 5
def hide_console():
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
ctypes.windll.user32.ShowWindow(hwnd, SW_HIDE)
def show_console():
hwnd = ctypes.windll.kernel32.GetConsoleWindow()
ctypes.windll.user32.ShowWindow(hwnd, SW_SHOW)
# Скрыть окно консоли
hide_console()
time.sleep(5) # Необходимо подождать 5 секунд
# Показать окно
show_console()
Заключение
Скрытие окна консоли не является тривиальной задачей, но можно использовать как PowerShell, так и Python для достижения этой цели. Подход, основанный на вызове WinAPI функций, позволит управлять видимостью окна достаточно гибко. Но имейте в виду необходимость хранения дескриптора окна, чтобы вы могли его восстановить, если это будет необходимо. Разработка подобного функционала требует точности, однако предоставляет пользователям более чистый интерфейс при работе с приложениями.