Уведомления

Группа в Telegram: @pythonsu

#1 Май 2, 2013 13:10:12

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

Приветствую всех.

Суть: Необходимо сделать запуск программы не привязанным к консоли. На linux ( и других UNIX подобных) это легко решается с помощью т.н. magic double fork.

Вопрос: как сделать по простому в Windows?

Гугление в основном приводит к использованию win32 библиотеки и оформлению кода как Windows Service, что несколько нежелательно (именно привязыватсья к сторонней библиотеки, причем относительно тяжелой).
Подумав и поразмывлив я пришел к некоторому решению, онснованное на особенностях Win32API в частности на флаги функции CreateProcess. Идея в том что при старте код проверяет некое условие и если оно удовлетворительно перезапускает себя же но уже с необходимым флагом. Ниже условный тестовый пример.

# -*- coding: utf-8 -*-
import sys, os , optparse, subprocess, time, traceback
from win32process import CREATE_NO_WINDOW
# выведим текущий номер процесса
print 'Process ID = {}\n'.format(os.getpid())
# Проверка аргументов на ключ указывающий на перезапуск скрипта с оторванной консолью
if len(sys.argv)>1 and  'hide' in sys.argv:
    subprocess.Popen([__file__], shell=True, creationflags=CREATE_NO_WINDOW)
    sys.exit()
# основное тело кода
with open('test_{}.log'.format(os.getpid()), 'w') as log:
    while True:
        try:
            log.write('Process ID = {}{}'.format(os.getpid(), os.linesep))
            log.flush()
            time.sleep(1)
        except BaseException:
            break

Если вызввать его следующем образом:
C:\ser>python test.py hide
Process ID = 1580
, то получится что стартует основной процесс с PID 1580, который порождает процесс с PID 680 и завершает работу, в то время как дочерний процесс продолжает выполнение.

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



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#2 Май 2, 2013 13:24:34

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

>pythonw test.py
Или test.py -> test.pyw и запускать даблкликом.

Оно?

Офлайн

#3 Май 2, 2013 14:22:27

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

reclosedev
как альтернативный метод возможный вариант. Но не совсем то, поясню:
хочется создать кроссплатформенную программу, которая бы вызывалась как обычно, и где то внутри себя отрывалась от консоли, или не отрывалась в зависимости от опций командной строки. Структурно она выглядела бы так:

class A():
def __init__():
parser()
if option:
if linux:
magic_double_fork()
elif Windows:
some_code_to_detach_console()

def main():
main_code()



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#4 Май 2, 2013 20:52:47

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

Офлайн

#5 Май 3, 2013 05:51:24

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

s0rg
Вот как бы уже близко к истине, только что то не получается. Дело в том что если просто вызвать

 from ctypes import windll
 windll.kernel32.FreeConsole()
То произойдет именно то что написано в документации - так как никакой более процесс не привязан к консоли изначального процесса, то консоль закроется, а вместе с ней и завершится процесс.
Если вызывать AllocConsole() то откроектся новая консоль, в которой будет происходить выполнение кода процесса и изначальная консоль будет в ожидании завершения дочерней.
Если поразмыслить,то представяется что я должен создать новую консоль, переключиться на изначальную, освободиться от нее, переключиться на новую консоль, которая к тому же как то скрыта должна быть. Однако подобных функций в доках в разделе про консоли не нашел.
Пока что еще думаю в этом направлении



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#6 Май 3, 2013 15:21:07

s0rg
От:
Зарегистрирован: 2011-06-05
Сообщения: 777
Репутация: +  25  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

JOHN_16
Однако подобных функций в доках в разделе про консоли не нашел.
А это?

Офлайн

#7 Май 4, 2013 07:07:21

sanodin
От:
Зарегистрирован: 2011-06-16
Сообщения: 515
Репутация: +  31  -
Профиль   Отправить e-mail  

Запуск скрипта оторванным от консоли Windows

Всегда для скрытия ком.строки пользовал vbs скрипт

Dim oShell
Set oShell = WScript.CreateObject ("WSCript.shell")
oShell.run "1.py", 0
Set oShell = Nothing
или .exe не важно

и вот средствами python…
тема очень пригодилась

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version