import ctypes import subprocess import sys import re import os import json import time from win10toast import ToastNotifier import threading # Definir una constante para la ruta del directorio DIR = "D:\\Proyectos\\Scripts\\IPChanger" IP_HISTORY_FILE = os.path.join(DIR, "ip_history.json") def is_admin(): """Verifica si el script se está ejecutando con privilegios de administrador.""" try: return ctypes.windll.shell32.IsUserAnAdmin() except: return False def run_as_admin(argv=None, debug=False): """Ejecuta el script como administrador.""" shell32 = ctypes.windll.shell32 if argv is None and shell32.IsUserAnAdmin(): # Ya estamos ejecutando como administrador, no es necesario hacer nada return True if argv is None: argv = sys.argv if hasattr(sys, "_MEIPASS"): # Soporte para PyInstaller arguments = map(str, argv[1:]) else: arguments = map(str, argv) argument_line = " ".join(arguments) executable = str(sys.executable) if debug: print(f"Command line: {executable} {argument_line}") ret = shell32.ShellExecuteW(None, "runas", executable, argument_line, None, 1) if int(ret) <= 32: return False return None def set_static_ip(ip_address, gateway): """Establece una dirección IP estática para el adaptador Ethernet.""" try: subprocess.run( f'netsh interface ip set address "Ethernet" static {ip_address} 255.255.255.0 {gateway}', shell=True, ) return f"Dirección IP establecida en {ip_address}" except Exception as e: return f"Error al establecer la dirección IP: {e}" def set_dhcp(): """Configura el adaptador Ethernet para obtener la dirección IP automáticamente a través de DHCP.""" try: subprocess.run('netsh interface ip set address "Ethernet" dhcp', shell=True) return "Adaptador Ethernet configurado para DHCP" except Exception as e: return f"Error al configurar DHCP: {e}" def save_current_ip(ip_history): """Guarda la dirección IP actual del adaptador Ethernet en un archivo y detecta si es de DHCP.""" try: ip_config_output = subprocess.check_output("ipconfig /all", shell=True).decode( "cp850" ) # Buscar la sección del adaptador de Ethernet y DHCP ethernet_config = re.search( "Adaptador de Ethernet Ethernet:[\s\S]*?(DHCP habilitado[\s\S]*?)\r\n\r\n", ip_config_output, ) current_ip = re.search( "Dirección IPv4. . . . . . . . . . . . . . : (\d+\.\d+\.\d+\.\d+)", ethernet_config.group(1) if ethernet_config else "", ) dhcp_enabled = re.search( "DHCP habilitado . . . . . . . . . . . . . : sí", ethernet_config.group(1) if ethernet_config else "", ) if current_ip and not dhcp_enabled: ip_history.insert(0, current_ip.group(1)) ip_history = ip_history[:10] return f"Dirección IP actual guardada: {current_ip.group(1)}" elif dhcp_enabled: return "La dirección IP actual es obtenida por DHCP." else: return "No se encontró la dirección IP actual." except Exception as e: return f"Error al obtener la configuración IP: {e}" def restore_last_ip(ip_history): """Restaura la última dirección IP guardada para el adaptador Ethernet.""" if ip_history: last_ip = ip_history[0] # Obtener la última IP del historial gateway = last_ip.rsplit(".", 1)[0] + ".1" return set_static_ip(last_ip, gateway) else: return "No hay direcciones IP guardadas en el historial." def get_input_parameter(): """Solicita al usuario un parámetro por línea de comandos.""" return input( "Ingrese la dirección IP, 0-9 para los ultimas IP, 'a' o 'auto' para DHCP, o 'l' o 'last' para la última IP: " ) def display_ip_history(ip_history): """Muestra el historial de las últimas 10 IPs en orden inverso (de la más antigua a la más reciente) y permite al usuario seleccionar una.""" if ip_history: for i, ip in enumerate(reversed(ip_history)): print(f"{len(ip_history) - 1 - i}: {ip}") return None def remove_duplicates_preserve_order(ip_history): """Elimina duplicados de la lista manteniendo el orden.""" seen = set() new_history = [] for item in ip_history: if item not in seen: seen.add(item) new_history.append(item) return new_history def show_notification(message, duration): toaster = ToastNotifier() toaster.show_toast("Cambio de IP", message, duration=duration) def main(): if not is_admin(): # Si no se está ejecutando como administrador, solicitar elevación result = run_as_admin() if result is True: print("Ejecutando como administrador.") elif result is False: print("No se pudo obtener privilegios de administrador.") return else: # El script se reinició con privilegios de administrador return if os.path.exists(IP_HISTORY_FILE): with open(IP_HISTORY_FILE, "r") as file: ip_history = json.load(file) ip_history = remove_duplicates_preserve_order(ip_history) else: ip_history = [] argument = sys.argv[1] if len(sys.argv) > 1 else None if not argument: chosen_ip = display_ip_history(ip_history) argument = get_input_parameter() if len(argument) == 0: return if ip_history: if len(argument) == 1: if argument.isdigit() and 0 <= int(argument) < len(ip_history): argument = ip_history[int(argument)] # Guardar la dirección IP actual solo si no es 'auto' message = save_current_ip(ip_history) print(message) if argument == "auto" or argument == "a": message = set_dhcp() elif argument == "last" or argument == "l": if ip_history: message = restore_last_ip(ip_history) print(message) else: ip_parts = argument.split(".") if len(ip_parts) == 3: argument += ".249" gateway = ".".join(ip_parts[:3]) + ".1" message = set_static_ip(argument, gateway) print(message) with open(IP_HISTORY_FILE, "w") as file: json.dump(ip_history, file) notification_thread = threading.Thread(target=show_notification, args=(message, 3)) notification_thread.start() if __name__ == "__main__": main()