using System; using System.IO; using System.Net; using System.Threading; using System.Diagnostics; using Cognex.DataMan.SDK; using Cognex.DataMan.SDK.Discovery; class Program { static int Main(string[] args) { // ==================================================================== // MODO HIJO (VERIFICADOR PURIFICADO) // Este bloque no interactúa con LabVIEW, solo escanea la red. // ==================================================================== if (args.Length == 3 && args[0] == "VERIFICAR") { return EjecutarVerificacionLimpia(args[1], args[2]); } // Iniciar cronómetro para medir tiempo de ejecución Stopwatch timer = Stopwatch.StartNew(); // ==================================================================== // MODO PADRE (CONFIGURADOR E INTERFAZ CON LABVIEW) // ==================================================================== string exeDirectory = AppDomain.CurrentDomain.BaseDirectory; string configDirectory = "C:\\Jabil DM Config Station\\Files\\"; string configPath = Path.Combine(configDirectory, "ConfigIP.txt"); string labviewFolder = configDirectory; // Misma ruta para los archivos de resultado // Validaciones iniciales if (!File.Exists(configPath)) { Console.WriteLine($"No se encontró el archivo de configuración: {configPath}"); ActualizarEstadoLabVIEW(2, exeDirectory, labviewFolder); // Error Console.ReadKey(); return 0; } string[] configLines = File.ReadAllLines(configPath); if (configLines.Length < 2) { Console.WriteLine("El archivo ConfigIP.txt debe tener 2 líneas: MAC Address y Nueva IP."); ActualizarEstadoLabVIEW(2, exeDirectory, labviewFolder); // Error Console.ReadKey(); return 0; } string macAddressInput = configLines[0].Trim(); string macLimpia = macAddressInput.Replace("-", "").Replace(":", "").Replace(".", "").Replace(" ", "").ToUpper(); string macAddress = macAddressInput; if (macLimpia.Length == 12) { macAddress = $"{macLimpia.Substring(0, 2)}:{macLimpia.Substring(2, 2)}:{macLimpia.Substring(4, 2)}:{macLimpia.Substring(6, 2)}:{macLimpia.Substring(8, 2)}:{macLimpia.Substring(10, 2)}"; } else { Console.WriteLine($"\n[ADVERTENCIA] La MAC '{macAddressInput}' no tiene 12 caracteres."); ActualizarEstadoLabVIEW(2, exeDirectory, labviewFolder); // Error return 0; } string newIpString = configLines[1].Trim(); if (!IPAddress.TryParse(newIpString, out var newIp)) { Console.WriteLine($"Error: La IP '{newIpString}' no tiene un formato válido."); ActualizarEstadoLabVIEW(2, exeDirectory, labviewFolder); // Error Console.ReadKey(); return 0; } // Asignación inteligente de Submáscara IPAddress subnetMask; if (newIpString.StartsWith("169.254.")) { subnetMask = IPAddress.Parse("255.255.0.0"); // Máscara correcta para APIPA } else if (newIpString.StartsWith("10.")) { subnetMask = IPAddress.Parse("255.0.0.0"); // Máscara correcta para redes Clase A } else { subnetMask = IPAddress.Parse("255.255.255.0"); // Estándar para 192.168.x.x } IPAddress gateway = IPAddress.Parse("0.0.0.0"); Console.WriteLine("=========================================="); Console.WriteLine($"MAC Destino : {macAddress}"); Console.WriteLine($"Nueva IP : {newIp}"); Console.WriteLine("==========================================\n"); // --- MARCAMOS INICIO DE PROCESO PARA LABVIEW (0) --- ActualizarEstadoLabVIEW(0, exeDirectory, labviewFolder); try { // --- FASE 1: ENVÍO DE LA CONFIGURACIÓN --- bool macEncontrada = false; string macDetectadaEnRed = ""; using (EthSystemDiscoverer discoverer = new EthSystemDiscoverer()) { discoverer.SystemDiscovered += (systemInfo) => { string macTraducida = ConvertirMacSdk(systemInfo.MacAddress.ToString()); Console.WriteLine($"[RADAR SDK] Detectó Lector -> IP: {systemInfo.IPAddress} | MAC Real: {macTraducida}"); // Validación: comparar MAC del archivo con la MAC detectada if (macTraducida == macLimpia) { macEncontrada = true; macDetectadaEnRed = macTraducida; } }; Console.WriteLine("Despertando la red (3 segundos)..."); discoverer.Discover(); Thread.Sleep(3000); // Verificar si se encontró la MAC esperada if (!macEncontrada) { timer.Stop(); Console.WriteLine("\n[ERROR DE VALIDACIÓN] La MAC del lector no coincide con la configurada."); Console.WriteLine($"MAC Esperada: {macLimpia}"); Console.WriteLine($"MAC Detectada: {(macDetectadaEnRed != "" ? macDetectadaEnRed : "Ninguna o diferente")}"); Console.WriteLine($"Tiempo transcurrido: {timer.Elapsed.TotalSeconds:F2} segundos"); ActualizarEstadoLabVIEW(3, exeDirectory, labviewFolder); // Error 3 : MAC no encontrada timer.Start(); Thread.Sleep(5000); return 0; } Console.WriteLine($"\n[VALIDACIÓN OK] MAC confirmada: {macLimpia}"); Console.WriteLine("\nEnviando paquete de configuración a la red..."); try { discoverer.ForceNetworkSettings(macAddress, false, newIp, subnetMask, gateway, "admin", "", ""); } catch { string macRaw = macAddress.Replace(":", ""); discoverer.ForceNetworkSettings(macRaw, false, newIp, subnetMask, gateway, "admin", "", ""); } } Console.WriteLine("¡Comando de cambio de IP enviado!"); Console.WriteLine("El DataMan cortará su conexión y se reiniciará para aplicar los cambios."); Console.WriteLine("Esperando 30 segundos para que termine de arrancar..."); Thread.Sleep(30000); // --- FASE 2: VERIFICACIÓN CON EL CLON --- Console.WriteLine($"\nIniciando verificación en un entorno de memoria limpio..."); string exePath = Process.GetCurrentProcess().MainModule.FileName; ProcessStartInfo psi = new ProcessStartInfo(exePath, $"VERIFICAR {macLimpia} {newIp}"); psi.UseShellExecute = false; using (Process clonVerificador = Process.Start(psi)) { clonVerificador.WaitForExit(); if (clonVerificador.ExitCode == 1) { Console.WriteLine("\n-------------------------------------------------"); Console.WriteLine(" VERIFICACIÓN EXITOSA: ¡El lector reporta su nueva IP!"); Console.WriteLine("-------------------------------------------------"); // --- MARCAMOS ÉXITO PARA LABVIEW (1) --- ActualizarEstadoLabVIEW(1, exeDirectory, labviewFolder); } else { Console.WriteLine("\n[ERROR DE VERIFICACIÓN] El cambio de IP no pudo confirmarse."); // --- MARCAMOS ERROR PARA LABVIEW (2) --- ActualizarEstadoLabVIEW(2, exeDirectory, labviewFolder); } } } catch (Exception ex) { timer.Stop(); Console.WriteLine("\n[ERROR CRÍTICO] Ocurrió un problema general:"); Console.WriteLine(ex.Message); Console.WriteLine($"Tiempo transcurrido: {timer.Elapsed.TotalSeconds:F2} segundos"); ActualizarEstadoLabVIEW(2, exeDirectory, labviewFolder); // Error } timer.Stop(); TimeSpan tiempoTotal = timer.Elapsed; Console.WriteLine($"\n================================================"); Console.WriteLine($"Tiempo total de ejecución: {tiempoTotal.TotalSeconds:F2} segundos"); Console.WriteLine($"Desglose: {tiempoTotal.Hours}h {tiempoTotal.Minutes}m {tiempoTotal.Seconds}s {tiempoTotal.Milliseconds}ms"); Console.WriteLine($"================================================"); Console.WriteLine("\nLa aplicación padre se cerrará automáticamente en 5 segundos..."); Thread.Sleep(5000); return 0; } // ==================================================================== // FUNCIÓN DE VERIFICACIÓN DEL CLON // ==================================================================== static int EjecutarVerificacionLimpia(string macObjetivo, string ipEsperada) { bool ipConfirmada = false; using (EthSystemDiscoverer radarLimpio = new EthSystemDiscoverer()) { radarLimpio.SystemDiscovered += (systemInfo) => { string macDetectada = ConvertirMacSdk(systemInfo.MacAddress.ToString()); if (macDetectada == macObjetivo) { if (systemInfo.IPAddress.ToString() == ipEsperada) { ipConfirmada = true; } } }; radarLimpio.Discover(); Console.Write(" >> Clon escaneando la red"); for (int i = 0; i < 15; i++) { if (ipConfirmada) break; Thread.Sleep(1000); Console.Write("."); } Console.WriteLine(); } return ipConfirmada ? 1 : 0; } // ==================================================================== // FUNCIÓN TRADUCTORA DE LA MAC DEL SDK // ==================================================================== static string ConvertirMacSdk(string sdkMacRaw) { if (long.TryParse(sdkMacRaw, out long macNumerica)) { string hex = macNumerica.ToString("X12"); string macVolteada = hex.Substring(10, 2) + hex.Substring(8, 2) + hex.Substring(6, 2) + hex.Substring(4, 2) + hex.Substring(2, 2) + hex.Substring(0, 2); return macVolteada; } return sdkMacRaw.Replace(":", "").Replace("-", "").ToUpper(); } // ==================================================================== // FUNCIÓN DE INTERFAZ CON LABVIEW // ==================================================================== static void ActualizarEstadoLabVIEW(int estado, string directorioLocal, string carpetaDestino) { try { // 1. Escribir el estado en el archivo local de la aplicación string archivoLocal = Path.Combine(directorioLocal, "ReultIP.txt"); File.WriteAllText(archivoLocal, estado.ToString()); // Asegurarnos de que el directorio destino exista if (!Directory.Exists(carpetaDestino)) { Directory.CreateDirectory(carpetaDestino); } // 2. Ruta del archivo en la carpeta que monitorea LabVIEW string archivoDestino = Path.Combine(carpetaDestino, "ReultIP.txt"); // 3. Eliminar el archivo destino si existe (Obligatorio para que LabVIEW detecte el cambio) if (File.Exists(archivoDestino)) { File.Delete(archivoDestino); Thread.Sleep(100); // Pausa para que el sistema de archivos registre la eliminación } // 4. Copiar el archivo actualizado a la carpeta destino File.Copy(archivoLocal, archivoDestino); Console.WriteLine($"[SISTEMA] Bandera LabVIEW actualizada a: {estado}"); } catch (Exception ex) { Console.WriteLine($"\n[AVISO] Ocurrió un problema al intentar actualizar el archivo para LabVIEW: {ex.Message}"); } } }