/*
* 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 : "";
}
}
}