Files
csharp-tools-checksum/ChecksumWorker.cs
T
2024-01-15 13:21:21 +01:00

83 lines
2.6 KiB
C#

// See https://aka.ms/new-console-template for more information
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Diagnostics.CodeAnalysis;
using System.Security.Cryptography;
internal class ChecksumWorkerConfig
{
public string Directory {
get; set;
} = ".";
public string Extension {
get; set;
} = "*";
}
internal class ChecksumWorker : BackgroundService
{
private readonly SHA512 SHA = SHA512.Create();
private readonly ChecksumWorkerConfig _config;
private readonly ILogger<ChecksumWorker> _classLogger;
public ChecksumWorker(IOptions<ChecksumWorkerConfig> options, ILogger<ChecksumWorker> classLogger)
{
_config = options.Value;
_classLogger = classLogger;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var dateTime = DateTime.Now;
var directory = _config.Directory;
var extension = _config.Extension;
if (Directory.Exists(directory) == false) {
_classLogger.LogError($"Directory {directory} does not exist");
return;
}
_classLogger.LogInformation($"Watch in: {directory}");
_classLogger.LogInformation($"Watch for: {extension}");
while (stoppingToken.IsCancellationRequested == false) {
var items = Directory.GetFiles(directory, extension)
.Select(file => new {
time = File.GetLastWriteTime(file),
file = file,
})
.Where(x => x.time > dateTime)
.OrderBy(x => x.time);
foreach (var item in items) {
var fileTime = item.time;
if (fileTime > dateTime) {
if (await TryCalculateChecksumAsync(item.file) is { } checksum) {
_classLogger.LogInformation($"File {item.file} has changed {checksum}", checksum);
}
else {
break; // try again later
}
}
dateTime = fileTime;
}
await Task.Delay(1000, stoppingToken);
}
}
private async Task<string?> TryCalculateChecksumAsync(string file)
{
try {
using (var fs = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read)) {
var checksum = await SHA.ComputeHashAsync(fs);
return Convert.ToBase64String(checksum);
}
}
catch {
return default;
}
}
}