204 lines
6.5 KiB
Python
204 lines
6.5 KiB
Python
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()
|