forked from amkovkov/GranuSightSoftware2
feat: results exporting
This commit is contained in:
@@ -1,51 +1,192 @@
|
||||
using System.Device.I2c;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
using GSS2.Core.Abstractions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace GSS2.Core.Hardware;
|
||||
|
||||
[Obsolete("Not implemented")]
|
||||
public class UsbService : IDisposable
|
||||
{
|
||||
private bool _disposedValue;
|
||||
private readonly ILogger<UsbService> _logger;
|
||||
private readonly Process _monitor;
|
||||
|
||||
public UsbService(ILogger<UsbService> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
|
||||
_logger.LogInformation("Инициализация");
|
||||
|
||||
_monitor = new Process();
|
||||
_monitor.StartInfo = new ProcessStartInfo()
|
||||
{
|
||||
FileName = "udisksctl",
|
||||
Arguments = "monitor",
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true
|
||||
};
|
||||
_monitor.OutputDataReceived += MonitorDataReceived;
|
||||
_monitor.ErrorDataReceived += MonitorDataReceived;
|
||||
_monitor.Exited += (s, ea) => _logger.LogWarning("Монитор udisksctl отключен");
|
||||
if (_monitor.Start())
|
||||
_logger.LogInformation("Монитор udisksctl запущен");
|
||||
else
|
||||
_logger.LogError("Не удалось запустить монитор udisksctl");
|
||||
_monitor.BeginOutputReadLine();
|
||||
_monitor.BeginErrorReadLine();
|
||||
|
||||
_logger.LogInformation("Инициализировано");
|
||||
}
|
||||
|
||||
private void MonitorDataReceived(object sender, DataReceivedEventArgs ea)
|
||||
public List<(string id, string name, bool mounted, string? mountPath)> GetDevices()
|
||||
{
|
||||
if (ea.Data is null)
|
||||
return;
|
||||
_logger.LogInformation("Data rec {}", ea.Data);
|
||||
var devices = new List<(string name, string id, bool mounted, string? mountPath)>();
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Получаем список дисков");
|
||||
var (exitCode, output, error) = RunCommand("lsblk", "-P -o NAME,PATH,RM,TYPE,MOUNTPOINT,LABEL,MODEL");
|
||||
if (exitCode != 0)
|
||||
{
|
||||
_logger.LogWarning("Не удалось получить список дисков: {} {}", exitCode, error.Trim());
|
||||
return devices;
|
||||
}
|
||||
|
||||
var lines = output.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var model = string.Empty;
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var dict = new Dictionary<string, string>();
|
||||
var matches = Regex.Matches(line, @"(\w+)=""([^""]*)""");
|
||||
foreach (Match m in matches)
|
||||
dict[m.Groups[1].Value] = m.Groups[2].Value;
|
||||
|
||||
if (dict.TryGetValue("RM", out var rm) &&
|
||||
dict.TryGetValue("TYPE", out var type) &&
|
||||
rm == "1" &&
|
||||
type == "disk")
|
||||
{
|
||||
model = dict.GetValueOrDefault("MODEL", "").Trim();
|
||||
}
|
||||
|
||||
if (dict.TryGetValue("RM", out rm) &&
|
||||
dict.TryGetValue("TYPE", out type) &&
|
||||
rm == "1" &&
|
||||
type == "part")
|
||||
{
|
||||
var id = dict.GetValueOrDefault("PATH", "");
|
||||
var mountpoint = dict.GetValueOrDefault("MOUNTPOINT", "");
|
||||
var label = dict.GetValueOrDefault("LABEL", "").Trim();
|
||||
var rawName = dict.GetValueOrDefault("NAME", "").Trim();
|
||||
|
||||
string displayName = string.Empty;
|
||||
if (!string.IsNullOrWhiteSpace(label))
|
||||
displayName = label;
|
||||
if (!string.IsNullOrWhiteSpace(model))
|
||||
displayName = displayName + (!string.IsNullOrWhiteSpace(displayName) ? " " : "") + model;
|
||||
else
|
||||
displayName = displayName + (!string.IsNullOrWhiteSpace(displayName) ? " " : "") + rawName;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(id))
|
||||
devices.Add((id, displayName, !string.IsNullOrWhiteSpace(mountpoint), string.IsNullOrWhiteSpace(mountpoint) ? null : mountpoint));
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Исключение при попытке получить список дисков");
|
||||
}
|
||||
|
||||
_logger.LogInformation("Список дисков: \n\t{}", string.Join("\n\t", devices.Select(d => $"{d.name} {d.mounted} {d.id}")));
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
public string? MountDevice(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Монтируем диск: {}", id);
|
||||
var (exitCode, output, error) = RunCommand("udisksctl", $"mount -b {id} --no-user-interaction");
|
||||
if (exitCode != 0)
|
||||
{
|
||||
_logger.LogWarning("Не удалось смонтировать диск {}: {} {}", id, exitCode, error.Trim());
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Диск смонтирован {}: {}", id, output.Trim());
|
||||
var result = output.Trim().Split("\n").Last();
|
||||
if (result.StartsWith($"Mounted {id} at "))
|
||||
{
|
||||
var path = result.Substring($"Mounted {id} at ".Count());
|
||||
return path;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Исключение при попытке смонтировать диск {}", id);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public string? GetMountPath(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Получаем информацию о диске: {}", id);
|
||||
var (exitCode, output, error) = RunCommand("udisksctl", $"info -b {id}");
|
||||
if (exitCode != 0)
|
||||
{
|
||||
_logger.LogWarning("Не удалось получить информацию о дисе {}: {} {}", id, exitCode, error.Trim());
|
||||
return null;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Информация о диске {}: {}", id, output.Trim());
|
||||
var result = output.Split("\n").FirstOrDefault(l => l.Trim().StartsWith("MountPoints:"));
|
||||
if (result is null)
|
||||
return null;
|
||||
result = result.Trim().Substring("MountPoints:".Count()).Trim();
|
||||
if (string.IsNullOrEmpty(result))
|
||||
return null;
|
||||
return result;
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Исключение при получении информации о диске {}", id);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool UnmountDevice(string id)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogInformation("Размонтируем диск {}", id);
|
||||
var (exitCode, output, error) = RunCommand("udisksctl", $"unmount -b {id} --no-user-interaction");
|
||||
if (exitCode != 0)
|
||||
{
|
||||
_logger.LogError("Не удалось размонтировать диск {}: {} {}", id, exitCode, error.Trim());
|
||||
return false;
|
||||
}
|
||||
|
||||
_logger.LogInformation("Диск размонтирован {}", id);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Исключение при попытке размонтировать диск {}", id);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnmountAllDevices()
|
||||
{
|
||||
_logger.LogInformation("Размонтируем все диски");
|
||||
var mountedDevices = GetDevices().Where(d => d.mounted).ToList();
|
||||
|
||||
foreach (var device in mountedDevices){
|
||||
Console.WriteLine(device.id);
|
||||
UnmountDevice(device.id);}
|
||||
}
|
||||
|
||||
private (int exitCode, string output, string error) RunCommand(string fileName, string arguments)
|
||||
{
|
||||
using var process = new Process
|
||||
{
|
||||
StartInfo = new ProcessStartInfo
|
||||
{
|
||||
FileName = fileName,
|
||||
Arguments = arguments,
|
||||
RedirectStandardOutput = true,
|
||||
RedirectStandardError = true,
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
string output = process.StandardOutput.ReadToEnd();
|
||||
string error = process.StandardError.ReadToEnd();
|
||||
process.WaitForExit();
|
||||
|
||||
return (process.ExitCode, output, error);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
@@ -53,13 +194,7 @@ public class UsbService : IDisposable
|
||||
if (!_disposedValue)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
try
|
||||
{
|
||||
_monitor.Close();
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
UnmountAllDevices();
|
||||
|
||||
_disposedValue = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user