elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: ¿Eres nuevo? ¿Tienes dudas acerca del funcionamiento de la comunidad? Lee las Reglas Generales


+  Foro de elhacker.net
|-+  Programación
| |-+  Scripting
| | |-+  Ctrl+C en windows me lo detecta pero no sale del script | Python3
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ctrl+C en windows me lo detecta pero no sale del script | Python3  (Leído 2,890 veces)
Drakaris

Desconectado Desconectado

Mensajes: 278


Todo lo que puedas imaginar, lo puedes crear.


Ver Perfil
Ctrl+C en windows me lo detecta pero no sale del script | Python3
« en: 9 Enero 2022, 18:45 pm »

Buenas,
Feliz año  ;D

Estoy con un socket servidor que al estar corriendo quiero que si el usuario hace Ctrl+C en el CMD este sale limpiamente (con un SIGINT).

main.py
Código
  1. from sources.handlerSignals import HandlerSignals
  2. class SocketServer:
  3.    def __init__(self,**kwargs):
  4.        try:
  5.            HandlerSignals()
  6.            # [...]
  7.  
  8.        # When the service shutdown successfully
  9.        except (KeyboardInterrupt, SystemExit,GeneratorExit) as err:
  10.            print("KeyboardInterrupt")
  11.            None
  12.  
  13.        finally:
  14.            try:
  15.                self.sock.close()
  16.            except:
  17.                None
  18.            print("Turnning off ClassAdminS")
  19.            sys.exit(0)
  20.  
  21.    # continue code
  22. if __name__=="__main__":
  23.    SocketServer(args=sys.argv)
  24.  

El HandlerSignals() esta en una carpeta 'sources' en el archivo handlerSignals
  -main.py
  |
  - sources/
      \-- handlerSignals.py


handlerSignals.py
Código
  1. import signal, sys, platform
  2. class HandlerSignals:
  3.    def __init__(self):
  4.        signal.signal(signal.SIGTERM,self.shutdown)
  5.  
  6.        # shutdown signal in Windows
  7.        if platform.system().upper()=="WINDOWS":
  8.            import win32api
  9.            win32api.SetConsoleCtrlHandler(self.shutdownWin, True)
  10.  
  11.    def shutdownWin(self,a):
  12.        print("Ctrl+c")
  13.        raise SystemExit
  14.  
  15.    def shutdown(self,code,msg):
  16.        raise SystemExit
  17.  


Como se puede ver si el sistema es Windows, se ejecuta
Citar
win32api.SetConsoleCtrlHandler(self.shutdownWin, True)
Que esta en escucha de Ctrl+C en windows CMD. Así que al ser presionado se llama a la funcion shutdownWin que este imprime "Ctrl+C" y lanza una excepcion SystemExit.

Que esta excepcion teoricamente es recogida por main.py que y sale de la terminal.

Pero no ocurre eso. Al lanzarse el SystemExit no imprime "KeyboardInterrupt". Y no se porque pasa....


https://imgur.com/gallery/x5jxQhM

Parece como si la excepcion no se pueda pasar al main.py

Como lo puedo solucionar...? Gracias por vuestra atencion.


En línea

Lo increible, no es lo que ves, sino como es
Drakaris

Desconectado Desconectado

Mensajes: 278


Todo lo que puedas imaginar, lo puedes crear.


Ver Perfil
Re: Ctrl+C en windows me lo detecta pero no sale del script | Python3
« Respuesta #1 en: 10 Enero 2022, 10:25 am »

Buenos dias!
Solución
Ya esta resuelto. Puede que no sea la mejor opcion, ni la más adecuada, pero me veo obligado ha hacerlo así pues Windows tiende a matar los procesos.

Así como lo queria hacer tendría que funcionar para mis ojos, pero la realidad es que no, y no se porque (en Linux funcionaria....).

Lo que hice es añadir el HandlerSignals() justo despues de crear el socket (dentro del __createSocket, despues del listen)

main.py:
Código
  1. #!/usr/bin/python3
  2. import sys,socket,urllib3,time,multiprocessing, threading
  3. from sources.ClientListener import ClientListener
  4. from sources.handlerSignals import HandlerSignals
  5. from sources.utils import logFile, Hosts, getIpAddress, Notify
  6. from sources.Server import Server
  7. from sources.Requests import Requests
  8.  
  9. class SocketServer:
  10.    def __init__(self,**kwargs):
  11.        try:
  12.            # [...]
  13.            self.__createSocket()
  14.  
  15.        # When the service shutdown successfully
  16.        except (KeyboardInterrupt, SystemExit,GeneratorExit) as err:
  17.                None
  18.  
  19.        finally:
  20.            try:
  21.                self.sock.close()
  22.            except:
  23.                None
  24.            Notify("Turnning off ClassAdminS",logFile().message("Good Bye. What you have a good day :)", True, "INFO"))
  25.  
  26.    def __createSocket(self):
  27.        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  28.        self.sock.bind(("",self.PORT))
  29.        self.sock.listen(self.CLIENTS)
  30.        HandlerSignals(self.sock)
  31.        Notify("Start ClassAdminS",logFile().message(f"Good days :D. I am listenning {self.CLIENTS} clients by port {self.PORT}.",True,"INFO"))
  32.        self.__handlerClients()
  33.  
  34. if __name__=="__main__":
  35.    SocketServer(args=sys.argv)
  36.  

La diferencia es que la funcion HnadlerSignals(sock) coge como parametro la variable que contiene el objecto socket.

handlerSignals.py
Código
  1. import signal, platform
  2. class HandlerSignals:
  3.    def __init__(self,sock):
  4.        self.sock = sock
  5.        signal.signal(signal.SIGTERM,self.shutdown)
  6.        # shutdown signal in Windows
  7.        if platform.system().upper()=="WINDOWS":
  8.            import win32api
  9.            win32api.SetConsoleCtrlHandler(self.shutdownWin, True)
  10.  
  11.    def shutdownWin(self,a):
  12.        self.sock.close()
  13.  
  14.    def shutdown(self,code,msg):
  15.        raise SystemExit
  16.  
La gran diferencia de handlerSignals.py con el anterior es que, al hacer Ctrl+C y llamar a la funcion shutdownWin(), este cierra el socket y me muestra el Notify de el try/except/finally del main.py.

Así me funciona correctamente, aunque no se si es muy buena practica,pero me funciona.

Hay que tener en cuenta que el HandlerSignals() debe estar justo después de la declaración de la variable self.sock. Yo lo pongo despues del self.sock.listen().

https://imgur.com/gallery/B2VR7Lp

¿Porque tan pesado con el Ctrl+C en CMD?
Por dos cosas:
  • Pues para salir limpiamente y correctamente
  • Pues este script lo ejecuto como servicio con NSSM

NSSM al parar un servicio, implicitamente hace un Ctrl+C y espera una reaccion. Si no hay reaccion este se cierra forzosamente y muestra el siguiente mensaje.
https://imgur.com/gallery/n5UO4sL

Ahora si el script detecta el Ctrl+C en CMD....
https://imgur.com/gallery/qLnBGOi

En el NSSM este es configurado así
https://imgur.com/gallery/ZEwvmOq

Gracias por vuestra atencion! ;-)


« Última modificación: 10 Enero 2022, 10:29 am por Drakaris » En línea

Lo increible, no es lo que ves, sino como es
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Desactivar Ctrl+C y Ctrl+V en Windows XP.
Windows
gelop 2 6,321 Último mensaje 16 Junio 2010, 00:21 am
por simorg
Bios detecta Disco Duro, pero Windows no, ayuda « 1 2 »
Hardware
NIGHTBIRD 11 17,738 Último mensaje 21 Marzo 2015, 04:25 am
por jomamb
Tengo un proyecto de script me coneta y todo pero me sale los packet escriptados
Hacking
peke-2011 0 1,403 Último mensaje 25 Julio 2015, 16:57 pm
por peke-2011
Saber si el script se ejecuto como administrador [Windows] | Python3
Scripting
Drakaris 2 1,968 Último mensaje 22 Septiembre 2020, 00:48 am
por Drakaris
Al hacer un screenshot con python3 en windows, la imagen me sale en negro.
Scripting
Drakaris 0 174 Último mensaje 16 Abril 2022, 12:30 pm
por Drakaris
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines