Files
IT-Nexus/agent-cs/Services/NotificationService.cs

111 lines
3.7 KiB
C#

using ITNexusAgent.Models;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Management;
using System.Text;
namespace ITNexusAgent.Services;
public class NotificationService
{
private readonly string _exePath;
private readonly string _dataDir;
private readonly string _shownIdsPath;
private readonly HashSet<int> _shownIds;
public NotificationService(string exePath, string dataDir)
{
_exePath = exePath;
_dataDir = dataDir;
_shownIdsPath = Path.Combine(dataDir, "shown_announcements.json");
_shownIds = LoadShownIds();
}
private HashSet<int> LoadShownIds()
{
try
{
if (File.Exists(_shownIdsPath))
{
var ids = JsonConvert.DeserializeObject<List<int>>(File.ReadAllText(_shownIdsPath));
return ids != null ? new HashSet<int>(ids) : [];
}
}
catch { }
return [];
}
private void SaveShownIds()
{
try { File.WriteAllText(_shownIdsPath, JsonConvert.SerializeObject(_shownIds.ToList())); }
catch { }
}
public void ShowAnnouncements(List<Announcement> announcements)
{
foreach (var ann in announcements)
{
if (_shownIds.Contains(ann.Id)) continue;
_shownIds.Add(ann.Id);
SaveShownIds();
ShowNotification(ann);
}
}
// Vollständigen eingeloggten User aus WMI holen (z.B. "WINKEL\gruessing" oder "AzureAD\gruessing")
public static string GetLoggedOnUser()
{
try
{
using var searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
foreach (ManagementObject obj in searcher.Get())
{
var user = obj["UserName"]?.ToString();
if (!string.IsNullOrEmpty(user)) return user;
}
}
catch { }
return "";
}
private void ShowNotification(Announcement ann)
{
try
{
var fullUser = GetLoggedOnUser();
if (string.IsNullOrEmpty(fullUser)) return;
var json = Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(ann)));
var taskName = $"ITNexus-Ann-{ann.Id}";
// Alten Task entfernen
Process.Start(new ProcessStartInfo("schtasks.exe", $"/delete /tn \"{taskName}\" /f")
{ CreateNoWindow = true })?.WaitForExit();
// Task mit Trigger weit in der Zukunft erstellen (damit er nicht abläuft vor /run)
var triggerTime = DateTime.Now.AddMinutes(60).ToString("HH:mm:ss");
var args = $"/create /tn \"{taskName}\" /tr \"\\\"{_exePath}\\\" --notify {json}\" " +
$"/sc ONCE /st {triggerTime} /ru \"{fullUser}\" /it /f";
var p = Process.Start(new ProcessStartInfo("schtasks.exe", args)
{ CreateNoWindow = true, RedirectStandardError = true, UseShellExecute = false });
p?.WaitForExit();
// Sofort ausführen
var run = Process.Start(new ProcessStartInfo("schtasks.exe", $"/run /tn \"{taskName}\"")
{ CreateNoWindow = true });
run?.WaitForExit();
// Task löschen damit der +60min Trigger nicht nochmal feuert
Thread.Sleep(3000);
Process.Start(new ProcessStartInfo("schtasks.exe", $"/delete /tn \"{taskName}\" /f")
{ CreateNoWindow = true })?.WaitForExit();
AgentWorker.Log($"NOTIFY: Task '{taskName}' für User '{fullUser}' gestartet (ExitCode={p?.ExitCode})");
}
catch (Exception ex)
{
AgentWorker.Log($"NOTIFY ERROR: {ex.Message}");
}
}
}