/* * Copyright (c) 2026 RAVAPI Soluções. Todos os direitos reservados. * www.ravapi.com */ using System; using System.Collections.Generic; using System.Diagnostics; using System.Management; using System.Net.NetworkInformation; using System.Security.Principal; using Microsoft.Win32; namespace TechDeskAgent { /// /// Coleta todos os dados do terminal Windows via WMI, Registro e APIs do sistema. /// public class DataCollector { // ── Identidade do terminal ──────────────────────────────────────────── public IdentidadeInfo ColetarIdentidade() { try { string hostname = Environment.MachineName; string dominio = Environment.UserDomainName; string usuario = Environment.UserName; string os = ObterValorWmi("Win32_OperatingSystem", "Caption"); string build = ObterValorWmi("Win32_OperatingSystem", "BuildNumber"); string arquit = Environment.Is64BitOperatingSystem ? "x64" : "x86"; string serial = ObterValorWmi("Win32_BIOS", "SerialNumber"); string mac = ObterMacPrimario(); string ip = ObterIpPrimario(); return new IdentidadeInfo { Hostname = hostname, Dominio = dominio, Usuario = usuario, SistemaOp = os?.Trim(), BuildOS = build, Arquitetura = arquit, Serial = serial?.Trim(), MacAddress = mac, IpAddress = ip }; } catch (Exception ex) { Logger.Error($"ColetarIdentidade: {ex.Message}"); return new IdentidadeInfo { Hostname = Environment.MachineName }; } } // ── Hardware ────────────────────────────────────────────────────────── public HardwareInfo ColetarHardware() { try { // CPU string cpuNome = ObterValorWmi("Win32_Processor", "Name")?.Trim(); int cpuNucleos = int.TryParse(ObterValorWmi("Win32_Processor", "NumberOfCores"), out var n) ? n : 0; double cpuUso = ObterUsoCpu(); // RAM ulong ramTotal = 0, ramLivre = 0; using (var q = new ManagementObjectSearcher("SELECT TotalVisibleMemorySize, FreePhysicalMemory FROM Win32_OperatingSystem")) foreach (ManagementObject o in q.Get()) { ramTotal = Convert.ToUInt64(o["TotalVisibleMemorySize"]) * 1024; ramLivre = Convert.ToUInt64(o["FreePhysicalMemory"]) * 1024; } // Discos var discos = new List(); using (var q = new ManagementObjectSearcher("SELECT DeviceID, Size, FreeSpace, FileSystem FROM Win32_LogicalDisk WHERE DriveType=3")) foreach (ManagementObject o in q.Get()) discos.Add(new DiscoInfo { Letra = o["DeviceID"]?.ToString(), TamanhoB = Convert.ToInt64(o["Size"] ?? 0), LivreB = Convert.ToInt64(o["FreeSpace"] ?? 0), SistArquiv = o["FileSystem"]?.ToString() }); // Placas de rede var adaptadores = new List(); foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) { if (ni.OperationalStatus != OperationalStatus.Up) continue; if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue; var ip4 = ""; foreach (var ua in ni.GetIPProperties().UnicastAddresses) if (ua.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { ip4 = ua.Address.ToString(); break; } adaptadores.Add(new AdaptadorInfo { Nome = ni.Name, Descricao = ni.Description, Mac = ni.GetPhysicalAddress().ToString(), Ip = ip4, VelocidadeB = ni.Speed, Tipo = ni.NetworkInterfaceType.ToString() }); } return new HardwareInfo { CpuNome = cpuNome, CpuNucleos = cpuNucleos, CpuUsoPct = Math.Round(cpuUso, 1), RamTotalB = (long)ramTotal, RamUsadoB = (long)(ramTotal - ramLivre), Discos = discos, Adaptadores = adaptadores }; } catch (Exception ex) { Logger.Error($"ColetarHardware: {ex.Message}"); return new HardwareInfo(); } } // ── Softwares instalados ────────────────────────────────────────────── public List ColetarSoftwares() { var lista = new List(); string[] chaves = { @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall", @"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" }; foreach (string chave in chaves) { try { using (var reg = Registry.LocalMachine.OpenSubKey(chave)) { if (reg == null) continue; foreach (string sub in reg.GetSubKeyNames()) { using (var k = reg.OpenSubKey(sub)) { if (k == null) continue; string nome = k.GetValue("DisplayName")?.ToString(); if (string.IsNullOrWhiteSpace(nome)) continue; lista.Add(new SoftwareInfo { Nome = nome, Versao = k.GetValue("DisplayVersion")?.ToString(), Editora = k.GetValue("Publisher")?.ToString(), Instalado = k.GetValue("InstallDate")?.ToString() }); } } } } catch (Exception ex) { Logger.Warn($"Registro {chave}: {ex.Message}"); } } return lista; } // ── Processos rodando ────────────────────────────────────────────────── public List ColetarProcessos() { var lista = new List(); try { foreach (var p in Process.GetProcesses()) { try { lista.Add(new ProcessoInfo { Nome = p.ProcessName, Pid = p.Id, MemoriaB = p.WorkingSet64, Inicio = TentarObterStartTime(p) }); } catch { /* acesso negado a alguns processos do sistema */ } } } catch (Exception ex) { Logger.Error($"ColetarProcessos: {ex.Message}"); } return lista; } // ── Eventos do Windows ──────────────────────────────────────────────── public List ColetarEventos() { var lista = new List(); // Erros e Avisos dos logs Sistema e Aplicação (últimas 4h) var logs = new[] { "System", "Application" }; var desde = DateTime.Now.AddHours(-4); foreach (var logNome in logs) { try { using (var log = new EventLog(logNome)) { for (int i = log.Entries.Count - 1; i >= 0 && lista.Count < 100; i--) { var entry = log.Entries[i]; if (entry.TimeGenerated < desde) break; if (entry.EntryType != EventLogEntryType.Error && entry.EntryType != EventLogEntryType.Warning) continue; lista.Add(new EventoInfo { Log = logNome, Tipo = entry.EntryType.ToString(), Fonte = entry.Source, EventId = entry.EventID, Mensagem = entry.Message?.Length > 500 ? entry.Message.Substring(0, 500) + "..." : entry.Message, Timestamp = entry.TimeGenerated }); } } } catch (Exception ex) { Logger.Warn($"EventLog {logNome}: {ex.Message}"); } } // Eventos de Login/Logout do log de Segurança (requer privilégio) try { using (var log = new EventLog("Security")) { for (int i = log.Entries.Count - 1; i >= 0; i--) { var entry = log.Entries[i]; if (entry.TimeGenerated < desde) break; // 4624=Logon, 4634=Logoff, 4647=Logoff iniciado pelo usuário if (entry.EventID != 4624 && entry.EventID != 4634 && entry.EventID != 4647) continue; lista.Add(new EventoInfo { Log = "Security", Tipo = entry.EventID == 4624 ? "Logon" : "Logoff", Fonte = entry.Source, EventId = entry.EventID, Mensagem = entry.Message?.Length > 300 ? entry.Message.Substring(0, 300) + "..." : entry.Message, Timestamp = entry.TimeGenerated }); } } } catch { /* Segurança pode exigir privilégio de administrador */ } return lista; } // ── Mapeamento de rede (ARP) ────────────────────────────────────────── public List ColetarRedeArp() { var lista = new List(); try { // Executa arp -a e captura saída var psi = new ProcessStartInfo("arp", "-a") { RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var proc = Process.Start(psi)) { string output = proc.StandardOutput.ReadToEnd(); proc.WaitForExit(); foreach (var linha in output.Split('\n')) { // Formato: " 192.168.1.1 00-50-56-c0-00-08 dinâmico" var partes = linha.Trim().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries); if (partes.Length < 3) continue; string ip = partes[0]; string mac = partes[1]; string tipo = partes[2]; // Filtros básicos if (!ip.Contains(".")) continue; if (mac == "ff-ff-ff-ff-ff-ff") continue; // broadcast if (ip.StartsWith("224.") || ip.StartsWith("239.")) continue; // multicast // Tenta resolver hostname via DNS reverso string hostname = TentarResolverHostname(ip); lista.Add(new DispositivoRedeInfo { Ip = ip, Mac = mac.ToUpper().Replace("-", ":"), Tipo = tipo, Hostname = hostname, Fabricante = ObterFabricanteMac(mac), Timestamp = DateTime.UtcNow }); } } } catch (Exception ex) { Logger.Error($"ColetarRedeArp: {ex.Message}"); } return lista; } // ── Helpers privados ────────────────────────────────────────────────── private string ObterValorWmi(string classe, string propriedade) { try { using (var q = new ManagementObjectSearcher($"SELECT {propriedade} FROM {classe}")) foreach (ManagementObject o in q.Get()) return o[propriedade]?.ToString(); } catch { } return null; } private double ObterUsoCpu() { try { using (var counter = new PerformanceCounter("Processor", "% Processor Time", "_Total")) { counter.NextValue(); // primeiro valor é sempre 0 System.Threading.Thread.Sleep(500); return counter.NextValue(); } } catch { return 0; } } private string ObterMacPrimario() { foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) if (ni.OperationalStatus == OperationalStatus.Up && ni.NetworkInterfaceType != NetworkInterfaceType.Loopback) return ni.GetPhysicalAddress().ToString(); return ""; } private string ObterIpPrimario() { foreach (var ni in NetworkInterface.GetAllNetworkInterfaces()) { if (ni.OperationalStatus != OperationalStatus.Up) continue; if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) continue; foreach (var ua in ni.GetIPProperties().UnicastAddresses) if (ua.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) return ua.Address.ToString(); } return ""; } private DateTime? TentarObterStartTime(Process p) { try { return p.StartTime; } catch { return null; } } private string TentarResolverHostname(string ip) { try { return System.Net.Dns.GetHostEntry(ip).HostName; } catch { return ""; } } /// /// Identifica o fabricante pelos 3 primeiros octetos do MAC (OUI). /// Lista parcial dos fabricantes mais comuns em ambientes corporativos. /// private string ObterFabricanteMac(string mac) { if (string.IsNullOrEmpty(mac)) return ""; string oui = mac.Replace("-", "").Replace(":", "").ToUpper(); if (oui.Length < 6) return ""; oui = oui.Substring(0, 6); var ouis = new Dictionary { {"000C29","VMware"}, {"000569","VMware"}, {"001A2B","Cisco"}, {"00E0FC","Huawei"}, {"B8BE93","HP"}, {"3C52A1","Dell"}, {"F4CE46","Apple"}, {"ACDE48","Apple"}, {"DC4A3E","Samsung"}, {"001E65","Cisco"}, {"B827EB","Raspberry"}, {"00155D","Microsoft"}, {"08002B","HP"}, {"00E04C","Realtek"}, {"001B78","Intelbras"}, {"000E8F","Linksys"}, {"001CB3","Apple"}, {"7C2664","Samsung"}, {"A0999B","Motorola"}, {"D8D385","Netgear"}, }; return ouis.TryGetValue(oui, out var fabricante) ? fabricante : ""; } } }