diff --git a/LibSystemdCli/CommandExecutor.cs b/LibSystemdCli/CommandExecutor.cs
new file mode 100644
index 0000000..096f1c1
--- /dev/null
+++ b/LibSystemdCli/CommandExecutor.cs
@@ -0,0 +1,59 @@
+using System.Diagnostics;
+
+namespace LibSystemdCli;
+
+public class CommandExecutor
+{
+ public static async Task<string> ExecuteCommand(string command, string args)
+ {
+ Console.WriteLine($"[{DateTime.Now:O}] Executing command: {command} {args}");
+ var process = new Process
+ {
+ StartInfo =
+ {
+ FileName = command,
+ Arguments = args,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false
+ }
+ };
+ process.Start();
+ var output = await process.StandardOutput.ReadToEndAsync();
+ var error = await process.StandardError.ReadToEndAsync();
+ await process.WaitForExitAsync();
+ if (process.ExitCode != 0)
+ {
+ throw new Exception($"Command {command} {args} failed with exit code {process.ExitCode} and error: {error}");
+ }
+
+ return output;
+ }
+
+ public static async IAsyncEnumerable<string> ExecuteCommandAsync(string command, string args)
+ {
+ Console.WriteLine($"[{DateTime.Now:O}] Executing command asynchronously: {command} {args}");
+ var process = new Process
+ {
+ StartInfo =
+ {
+ FileName = command,
+ Arguments = args,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false
+ }
+ };
+ process.Start();
+ while (!process.StandardOutput.EndOfStream)
+ {
+ var line = await process.StandardOutput.ReadLineAsync();
+ yield return line;
+ }
+ await process.WaitForExitAsync();
+ if (process.ExitCode != 0)
+ {
+ throw new Exception($"Command {command} {args} failed with exit code {process.ExitCode}");
+ }
+ }
+}
\ No newline at end of file
diff --git a/LibSystemdCli/LibSystemdCli.csproj b/LibSystemdCli/LibSystemdCli.csproj
new file mode 100644
index 0000000..1d1bffa
--- /dev/null
+++ b/LibSystemdCli/LibSystemdCli.csproj
@@ -0,0 +1,13 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>net8.0</TargetFramework>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <Nullable>enable</Nullable>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\LibSystemdCli.Models\LibSystemdCli.Models.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/LibSystemdCli/SystemdExecutor.cs b/LibSystemdCli/SystemdExecutor.cs
new file mode 100644
index 0000000..eb6dfc9
--- /dev/null
+++ b/LibSystemdCli/SystemdExecutor.cs
@@ -0,0 +1,31 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using LibSystemdCli.Models;
+
+namespace LibSystemdCli;
+
+public class SystemdExecutor
+{
+ public static async IAsyncEnumerable<SystemdUnitListItem> GetUnits()
+ {
+ var output = await CommandExecutor.ExecuteCommand("systemctl", "list-units --all --no-legend --no-pager --no-legend -o json-pretty");
+
+ var data = JsonSerializer.Deserialize<List<SystemdUnitListItem>>(output);
+
+ foreach (var unit in data)
+ {
+ try
+ {
+ var fragmentOutput = await CommandExecutor.ExecuteCommand("systemctl", $"show -P FragmentPath --no-pager --no-legend -- {unit.Unit} ");
+ // Console.WriteLine(fragmentOutput);
+ unit.FragmentPaths = fragmentOutput.Split('\n', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).ToList();
+ }
+ catch
+ {
+ }
+
+ yield return unit;
+ // await Task.Delay(100);
+ }
+ }
+}
\ No newline at end of file
|