2
0

refactor(ci): rename DellMonitorControl to MonitorControl
All checks were successful
Build / build (push) Successful in 9h0m26s
Build and Release / build (push) Successful in 8h0m15s

Rename project from DellMonitorControl to MonitorControl to reflect broader monitor compatibility beyond Dell hardware. Update all references in solution file, workflow, and project paths.

Add DDC/CI rate limiting and throttling logic to prevent command failures:
- Minimum 50ms interval between commands to same monitor
- 8-second grace period after system resume before sending commands
- 3-second cooldown after timeout to allow monitor recovery
- Global semaphore to prevent command collisions

Replace old icon with new generic monitor icon (ico and png formats).
This commit is contained in:
2026-01-29 18:14:58 -05:00
parent 3c6cc15281
commit 404e6f42da
24 changed files with 262 additions and 53 deletions

View File

@@ -0,0 +1,119 @@
using System;
using System.Diagnostics;
using System.Net.Http;
using System.Reflection;
using System.Text.Json;
using System.Threading.Tasks;
namespace MonitorControl;
public class UpdateChecker
{
private const string ReleasesApiUrl = "https://git.marketally.com/api/v1/repos/misc/ControlMyMonitorManagement/releases/latest";
private static readonly HttpClient _httpClient = new() { Timeout = TimeSpan.FromSeconds(10) };
public static Version CurrentVersion => Assembly.GetExecutingAssembly().GetName().Version ?? new Version(1, 0, 0);
public static async Task<UpdateInfo?> CheckForUpdateAsync()
{
try
{
DebugLogger.Log($"Checking for updates... Current version: {CurrentVersion}");
var response = await _httpClient.GetStringAsync(ReleasesApiUrl);
var release = JsonSerializer.Deserialize<GiteaRelease>(response);
if (release == null || string.IsNullOrEmpty(release.tag_name))
{
DebugLogger.Log("No release info found");
return null;
}
var latestVersionStr = release.tag_name.TrimStart('v', 'V');
if (!Version.TryParse(latestVersionStr, out var latestVersion))
{
DebugLogger.Log($"Could not parse version: {release.tag_name}");
return null;
}
DebugLogger.Log($"Latest version: {latestVersion}");
if (latestVersion > CurrentVersion)
{
// Find the installer asset
string? downloadUrl = null;
if (release.assets != null)
{
foreach (var asset in release.assets)
{
if (asset.name?.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) == true)
{
downloadUrl = asset.browser_download_url;
break;
}
}
}
// Fallback to release page if no direct download
downloadUrl ??= release.html_url;
DebugLogger.Log($"Update available: {latestVersion}, URL: {downloadUrl}");
return new UpdateInfo
{
CurrentVersion = CurrentVersion,
LatestVersion = latestVersion,
DownloadUrl = downloadUrl ?? "",
ReleaseNotes = release.body ?? ""
};
}
DebugLogger.Log("No update available");
return null;
}
catch (Exception ex)
{
DebugLogger.LogError("Update check failed", ex);
return null;
}
}
public static void OpenDownloadPage(string url)
{
try
{
Process.Start(new ProcessStartInfo
{
FileName = url,
UseShellExecute = true
});
}
catch (Exception ex)
{
DebugLogger.LogError("Failed to open download page", ex);
}
}
}
public class UpdateInfo
{
public Version CurrentVersion { get; set; } = new(1, 0, 0);
public Version LatestVersion { get; set; } = new(1, 0, 0);
public string DownloadUrl { get; set; } = "";
public string ReleaseNotes { get; set; } = "";
}
public class GiteaRelease
{
public string? tag_name { get; set; }
public string? name { get; set; }
public string? body { get; set; }
public string? html_url { get; set; }
public GiteaAsset[]? assets { get; set; }
}
public class GiteaAsset
{
public string? name { get; set; }
public string? browser_download_url { get; set; }
}