using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using Newtonsoft.Json.Linq; namespace LD_SysInfo.Services { public static class OsqueryService { private static string GetLogPath(string filename) { string logDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "PSG-Oversight"); Directory.CreateDirectory(logDir); return Path.Combine(logDir, filename); } private static string GetOsqueryPath() { var baseDir = AppContext.BaseDirectory; var path = Path.Combine(baseDir, "Assets", "osqueryi.exe"); if (!File.Exists(path)) { try { File.AppendAllText(GetLogPath("osquery_error.log"), $"[{DateTime.Now}] ❌ osqueryi.exe not found at {path}\n"); } catch { /* Silently fail if we can't write logs */ } throw new FileNotFoundException("osqueryi.exe not found", path); } return path; } private static string RunQuery(string sql) { var processInfo = new ProcessStartInfo { FileName = GetOsqueryPath(), Arguments = $"--json \"{sql}\"", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using var process = Process.Start(processInfo); // ✅ FIXED — actually start the process if (process == null) throw new Exception("Failed to start osquery process"); string output = process.StandardOutput.ReadToEnd(); process.WaitForExit(); // Optional debug logging try { File.AppendAllText(GetLogPath("osquery_debug.log"), $"[{DateTime.Now}] Ran query: {sql}\nOutput length: {output.Length}\n"); } catch { /* Silently fail if we can't write logs */ } return output; } public static List> Query(string sql) { string json = RunQuery(sql); try { var jArray = JArray.Parse(json); var results = new List>(); foreach (var obj in jArray) { var dict = new Dictionary(); foreach (var prop in (JObject)obj) dict[prop.Key] = prop.Value?.ToString() ?? ""; results.Add(dict); } return results; } catch (Exception ex) { try { File.AppendAllText(GetLogPath("osquery_error.log"), $"[{DateTime.Now}] ⚠️ JSON parse failed for query '{sql}': {ex.Message}\n"); } catch { /* Silently fail if we can't write logs */ } return new List>(); } } } }