GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — release: 5.8.4 · purelogiccode/SimpleLauncher@5a1f0e3

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • SimpleLauncher.Avalonia.SlowTests
    • SimpleLauncher.Avalonia.SlowTests.csproj
  • SimpleLauncher.Avalonia.Tests
    • MainViewModelQuickActionsTests.cs
    • RetroAchievementsServiceNetworkFailureTests.cs
    • SimpleLauncher.Avalonia.Tests.csproj
  • SimpleLauncher.Avalonia.Updater
    • SimpleLauncher.Avalonia.Updater.csproj
  • SimpleLauncher.Avalonia
    • DownloadImagePackWindow.axaml
    • Services/RetroAchievements
      • RetroAchievementsService.cs
    • SimpleLauncher.Avalonia.csproj
    • app.manifest
  • SimpleLauncher.Core
    • SimpleLauncher.Core.csproj
  • SimpleLauncher.ResourceTranslator
    • SimpleLauncher.ResourceTranslator.csproj
  • SimpleLauncher.SlowTests
    • SimpleLauncher.SlowTests.csproj
  • SimpleLauncher.Tests
    • RetroAchievementsServiceNetworkFailureTests.cs
    • SimpleLauncher.Tests.csproj
    • UpdateSimulationTests.cs
  • SimpleLauncher
    • Services
      • CheckForUpdatesService.cs
      • RetroAchievements
        • RetroAchievementsService.cs
    • SimpleLauncher.csproj
    • WhatsNew.md
    • app.manifest
  • Tools
    • Mame.DatCreator
      • Mame.DatCreator.csproj
    • RetroAchievements.DataFetcher
      • RetroAchievements.DataFetcher.csproj
    • XmlToBinaryConverter
      • XmlToBinaryConverter.csproj
  • docs
    • 01-overview.md
    • 02-projects-and-solution.md
    • 14-testing.md
    • 15-development.md
    • 16-updater.md
    • 17-release-notes.md
    • README.md
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎SimpleLauncher.Avalonia.SlowTests/SimpleLauncher.Avalonia.SlowTests.csproj‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia.SlowTests/SimpleLauncher.Avalonia.SlowTests.csproj
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
<Nullable>enable</Nullable>
1010
<LangVersion>14</LangVersion>
1111
<NoWarn>NU1903;xUnit1026</NoWarn>
12-
<AssemblyVersion>5.8.3</AssemblyVersion>
13-
<FileVersion>5.8.3</FileVersion>
14-
<Version>5.8.3</Version>
12+
<AssemblyVersion>5.8.4</AssemblyVersion>
13+
<FileVersion>5.8.4</FileVersion>
14+
<Version>5.8.4</Version>
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Meziantou.Analyzer" Version="3.0.314">
18+
<PackageReference Include="Meziantou.Analyzer" Version="3.0.315">
1919
<PrivateAssets>all</PrivateAssets>
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
</PackageReference>
Collapse file

‎SimpleLauncher.Avalonia.Tests/MainViewModelQuickActionsTests.cs‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia.Tests/MainViewModelQuickActionsTests.cs
+3-2Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,6 @@ public async Task NavigateToSystem_SortsByFileNameAndMachineDescription()
464464
.OrderByDescending(static f => Path.GetFileName(f), StringComparer.OrdinalIgnoreCase)
465465
.ToList();
466466

467-
void PrimeCache() => _gameCache.SetCachedFiles(system.SystemName, files, BuildSignature(system));
468-
469467
PrimeCache();
470468
await _viewModel.NavigateToSystemCommand.ExecuteAsync("Test System");
471469

@@ -491,6 +489,9 @@ public async Task NavigateToSystem_SortsByFileNameAndMachineDescription()
491489
new[] { "123start.zip", "beyond.zip", "abyss.zip", "zero.was", "cantina.zip" },
492490
_viewModel.Games.Select(static g => Path.GetFileName(g.FilePath)),
493491
StringComparer.OrdinalIgnoreCase);
492+
return;
493+
494+
void PrimeCache() => _gameCache.SetCachedFiles(system.SystemName, files, BuildSignature(system));
494495
}
495496

496497
private static string BuildSignature(SystemManagerConfig system)
Collapse file

‎SimpleLauncher.Avalonia.Tests/RetroAchievementsServiceNetworkFailureTests.cs‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia.Tests/RetroAchievementsServiceNetworkFailureTests.cs
+54-6Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
using System.Net;
12
using System.Security.Authentication;
3+
using System.Text;
24
using Microsoft.Extensions.Configuration;
35
using Moq;
46
using Serilog.Core;
@@ -9,12 +11,11 @@
911
namespace SimpleLauncher.Avalonia.Tests;
1012

1113
/// <summary>
12-
/// Regression tests for bugs #68173/#68172: an SSL failure
13-
/// ("The SSL connection could not be established") in GetUserProfileAsync used to be
14-
/// logged at Error, so every user with a broken proxy/antivirus TLS interception sent
15-
/// a bug report to the live API. Network failures and timeouts are expected external
16-
/// conditions and must be logged at Information only — never Warning/Error — so the
17-
/// bug report service stays silent.
14+
/// Regression tests for bugs #68173/#68172 and #68823-68828: network failures,
15+
/// timeouts and non-JSON API payloads (Cloudflare challenge / maintenance pages)
16+
/// used to be logged at Error, so every affected user sent a bug report to the live
17+
/// API. These are expected external conditions and must be logged at Information
18+
/// only — never Warning/Error — so the bug report service stays silent.
1819
/// </summary>
1920
public class RetroAchievementsServiceNetworkFailureTests
2021
{
@@ -46,6 +47,34 @@ public async Task GetUserProfileAsync_Timeout_IsLoggedAtInformation_NotAsBug()
4647
Assert.Contains(sink.Events, static e => e.Level == LogEventLevel.Information);
4748
}
4849

50+
[Fact]
51+
public async Task GetUserProfileAsync_HtmlResponse_IsLoggedAtInformation_NotAsBug()
52+
{
53+
var sink = new CaptureSink();
54+
var logger = new LoggerConfiguration().WriteTo.Sink(sink).CreateLogger();
55+
var service = CreateService(new HtmlResponseHandler(), logger);
56+
57+
var result = await service.GetUserProfileAsync("rcroadster", "api-key");
58+
59+
Assert.Null(result);
60+
Assert.DoesNotContain(sink.Events, static e => e.Level >= LogEventLevel.Warning);
61+
Assert.Contains(sink.Events, static e => e.Level == LogEventLevel.Information);
62+
}
63+
64+
[Fact]
65+
public async Task GetUserRecentlyPlayedGamesAsync_HtmlResponse_IsLoggedAtInformation_NotAsBug()
66+
{
67+
var sink = new CaptureSink();
68+
var logger = new LoggerConfiguration().WriteTo.Sink(sink).CreateLogger();
69+
var service = CreateService(new HtmlResponseHandler(), logger);
70+
71+
var result = await service.GetUserRecentlyPlayedGamesAsync("rcroadster", "api-key");
72+
73+
Assert.Null(result);
74+
Assert.DoesNotContain(sink.Events, static e => e.Level >= LogEventLevel.Warning);
75+
Assert.Contains(sink.Events, static e => e.Level == LogEventLevel.Information);
76+
}
77+
4978
private static RetroAchievementsService CreateService(HttpMessageHandler handler, ILogger logger)
5079
{
5180
var httpClientFactory = new Mock<IHttpClientFactory>();
@@ -90,6 +119,25 @@ protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage reques
90119
}
91120
}
92121

122+
/// <summary>
123+
/// Simulates the HTML page Cloudflare/RetroAchievements serves with HTTP 200 during a
124+
/// challenge, rate limit or maintenance window (bugs #68823-68828).
125+
/// </summary>
126+
private sealed class HtmlResponseHandler : HttpMessageHandler
127+
{
128+
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
129+
CancellationToken cancellationToken)
130+
{
131+
const string html =
132+
"<!DOCTYPE html><html><head><title>Just a moment...</title></head><body>Checking your browser</body></html>";
133+
134+
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
135+
{
136+
Content = new StringContent(html, Encoding.UTF8, "text/html")
137+
});
138+
}
139+
}
140+
93141
/// <summary>Serilog sink that records every emitted event for level assertions.</summary>
94142
private sealed class CaptureSink : ILogEventSink
95143
{
Collapse file

‎SimpleLauncher.Avalonia.Tests/SimpleLauncher.Avalonia.Tests.csproj‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia.Tests/SimpleLauncher.Avalonia.Tests.csproj
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@
99
<Nullable>enable</Nullable>
1010
<LangVersion>14</LangVersion>
1111
<NoWarn>NU1903;xUnit1026</NoWarn>
12-
<AssemblyVersion>5.8.3</AssemblyVersion>
13-
<FileVersion>5.8.3</FileVersion>
14-
<Version>5.8.3</Version>
12+
<AssemblyVersion>5.8.4</AssemblyVersion>
13+
<FileVersion>5.8.4</FileVersion>
14+
<Version>5.8.4</Version>
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<PackageReference Include="Meziantou.Analyzer" Version="3.0.314">
18+
<PackageReference Include="Meziantou.Analyzer" Version="3.0.315">
1919
<PrivateAssets>all</PrivateAssets>
2020
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2121
</PackageReference>
Collapse file

‎SimpleLauncher.Avalonia.Updater/SimpleLauncher.Avalonia.Updater.csproj‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia.Updater/SimpleLauncher.Avalonia.Updater.csproj
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
<AssemblyName>Updater</AssemblyName>
1212
<Nullable>enable</Nullable>
1313
<ImplicitUsings>enable</ImplicitUsings>
14-
<AssemblyVersion>5.8.3</AssemblyVersion>
15-
<FileVersion>5.8.3</FileVersion>
16-
<Version>5.8.3</Version>
14+
<AssemblyVersion>5.8.4</AssemblyVersion>
15+
<FileVersion>5.8.4</FileVersion>
16+
<Version>5.8.4</Version>
1717
<IsPackable>false</IsPackable>
1818
<LangVersion>14</LangVersion>
1919
<ApplicationIcon>icon\icon.ico</ApplicationIcon>
@@ -42,7 +42,7 @@
4242
</ItemGroup>
4343

4444
<ItemGroup>
45-
<PackageReference Include="Meziantou.Analyzer" Version="3.0.314">
45+
<PackageReference Include="Meziantou.Analyzer" Version="3.0.315">
4646
<PrivateAssets>all</PrivateAssets>
4747
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4848
</PackageReference>
@@ -54,7 +54,7 @@
5454
<PackageReference Include="Serilog.Sinks.Async" Version="2.1.0" />
5555
<PackageReference Include="Serilog.Sinks.Debug" Version="3.0.0" />
5656
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
57-
<PackageReference Include="SharpCompress" Version="0.50.6" />
57+
<PackageReference Include="SharpCompress" Version="0.50.7" />
5858
<PackageReference Include="Avalonia" Version="12.1.4" />
5959
<PackageReference Include="Avalonia.Desktop" Version="12.1.4" />
6060
<PackageReference Include="Avalonia.Themes.Fluent" Version="12.1.4" />
Collapse file

‎SimpleLauncher.Avalonia/DownloadImagePackWindow.axaml‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia/DownloadImagePackWindow.axaml
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<!-- ReSharper disable once Xaml.RedundantNamespaceAlias -->
12
<Window x:Class="SimpleLauncher.Avalonia.DownloadImagePackWindow"
23
xmlns="https://github.com/avaloniaui"
34
xmlns:ext="using:SimpleLauncher.Avalonia.Extensions"
Collapse file

‎SimpleLauncher.Avalonia/Services/RetroAchievements/RetroAchievementsService.cs‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia/Services/RetroAchievements/RetroAchievementsService.cs
+74-10Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,14 +70,23 @@ public RetroAchievementsService(
7070
if (!response.IsSuccessStatusCode) return null;
7171

7272
var jsonString = await response.Content.ReadAsStringAsync();
73-
using var doc = JsonDocument.Parse(jsonString);
73+
if (!TryGetJsonPayload(jsonString, nameof(GetSessionTokenAsync), out var json)) return null;
74+
75+
using var doc = JsonDocument.Parse(json);
7476
var root = doc.RootElement;
7577

7678
return root.TryGetProperty("Success", out var success) && success.GetBoolean() &&
7779
root.TryGetProperty("Token", out var token)
7880
? token.GetString()
7981
: null;
8082
}
83+
catch (JsonException ex)
84+
{
85+
// Expected external condition (malformed/non-JSON API payload): not a bug.
86+
_logger.Information(ex,
87+
"[RA Service] Invalid JSON response in GetSessionTokenAsync; the API may be temporarily unavailable.");
88+
return null;
89+
}
8190
catch (Exception ex)
8291
{
8392
_logger.Error(ex, "[RA Service] Failed to get session token");
@@ -121,7 +130,7 @@ public RetroAchievementsService(
121130
}
122131

123132
var json = await response.Content.ReadAsStringAsync();
124-
var apiResponse = JsonSerializer.Deserialize<RaGameProgressResponse>(json);
133+
var apiResponse = DeserializeApiResponse<RaGameProgressResponse>(json, nameof(GetGameInfoAndUserProgressAsync));
125134

126135
if (apiResponse == null) return (null, null);
127136

@@ -208,7 +217,7 @@ public RetroAchievementsService(
208217
}
209218

210219
var json = await response.Content.ReadAsStringAsync();
211-
return JsonSerializer.Deserialize<RaGameExtendedDetails>(json);
220+
return DeserializeApiResponse<RaGameExtendedDetails>(json, nameof(GetGameExtendedAsync));
212221
}
213222
catch (RaUnauthorizedException)
214223
{
@@ -242,7 +251,7 @@ public RetroAchievementsService(
242251
}
243252

244253
var json = await response.Content.ReadAsStringAsync();
245-
return JsonSerializer.Deserialize<List<RaUserGameRank>>(json);
254+
return DeserializeApiResponse<List<RaUserGameRank>>(json, nameof(GetUserGameRankAndScoreAsync));
246255
}
247256
catch (RaUnauthorizedException)
248257
{
@@ -278,7 +287,7 @@ public RetroAchievementsService(
278287
}
279288

280289
var json = await response.Content.ReadAsStringAsync();
281-
return JsonSerializer.Deserialize<List<RaGameRankAndScore>>(json);
290+
return DeserializeApiResponse<List<RaGameRankAndScore>>(json, nameof(GetGameRankAndScoreAsync));
282291
}
283292
catch (RaUnauthorizedException)
284293
{
@@ -312,7 +321,7 @@ public RetroAchievementsService(
312321
}
313322

314323
var json = await response.Content.ReadAsStringAsync();
315-
return JsonSerializer.Deserialize<RaProfile>(json);
324+
return DeserializeApiResponse<RaProfile>(json, nameof(GetUserProfileAsync));
316325
}
317326
catch (RaUnauthorizedException)
318327
{
@@ -360,7 +369,7 @@ public RetroAchievementsService(
360369
}
361370

362371
var json = await response.Content.ReadAsStringAsync();
363-
return JsonSerializer.Deserialize<List<RaRecentlyPlayedGame>>(json);
372+
return DeserializeApiResponse<List<RaRecentlyPlayedGame>>(json, nameof(GetUserRecentlyPlayedGamesAsync));
364373
}
365374
catch (RaUnauthorizedException)
366375
{
@@ -398,7 +407,7 @@ public RetroAchievementsService(
398407
}
399408

400409
var json = await response.Content.ReadAsStringAsync();
401-
return JsonSerializer.Deserialize<List<RaEarnedAchievement>>(json);
410+
return DeserializeApiResponse<List<RaEarnedAchievement>>(json, nameof(GetAchievementsEarnedBetweenAsync));
402411
}
403412
catch (RaUnauthorizedException)
404413
{
@@ -433,7 +442,8 @@ public RetroAchievementsService(
433442
}
434443

435444
var json = await response.Content.ReadAsStringAsync();
436-
var apiResponse = JsonSerializer.Deserialize<RaUserCompletionProgressResponse>(json);
445+
var apiResponse = DeserializeApiResponse<RaUserCompletionProgressResponse>(json,
446+
nameof(GetUserCompletionProgressAsync));
437447

438448
if (apiResponse?.Results == null) return null;
439449

@@ -458,4 +468,58 @@ public RetroAchievementsService(
458468
return null;
459469
}
460470
}
461-
}
471+
472+
/// <summary>
473+
/// Deserializes a RetroAchievements API payload. An HTML or empty payload is an expected
474+
/// external condition (Cloudflare challenge, rate limit, maintenance page) and is logged at
475+
/// Information so it never reaches the bug report service (bugs #68823-68828).
476+
/// </summary>
477+
private T? DeserializeApiResponse<T>(string json, string operation)
478+
{
479+
if (!TryGetJsonPayload(json, operation, out var payload)) return default;
480+
481+
try
482+
{
483+
return JsonSerializer.Deserialize<T>(payload);
484+
}
485+
catch (JsonException ex)
486+
{
487+
// The API returned a payload that is not valid JSON: not an application bug.
488+
_logger.Information(ex,
489+
$"[RA Service] Invalid JSON response in {operation}; the API may be temporarily unavailable.");
490+
return default;
491+
}
492+
}
493+
494+
/// <summary>
495+
/// Returns false for empty or non-JSON (HTML) API payloads, logging them at Information
496+
/// level so they stay out of the bug report service.
497+
/// </summary>
498+
private bool TryGetJsonPayload(string json, string operation, out string payload)
499+
{
500+
payload = json;
501+
502+
if (string.IsNullOrWhiteSpace(json))
503+
{
504+
_logger.Information(
505+
$"[RA Service] Empty response in {operation}; the RetroAchievements API may be temporarily unavailable.");
506+
return false;
507+
}
508+
509+
var trimmed = json.AsSpan().TrimStart();
510+
if (!trimmed.IsEmpty && trimmed[0] == '<')
511+
{
512+
_logger.Information(
513+
$"[RA Service] Non-JSON response in {operation}; the RetroAchievements API returned an HTML page (maintenance, rate limit or challenge). Response starts with: {GetResponseSnippet(json)}");
514+
return false;
515+
}
516+
517+
return true;
518+
}
519+
520+
private static string GetResponseSnippet(string response)
521+
{
522+
var singleLine = response.ReplaceLineEndings(" ").Trim();
523+
return singleLine.Length <= 120 ? singleLine : $"{singleLine[..120]}...";
524+
}
525+
}
Collapse file

‎SimpleLauncher.Avalonia/SimpleLauncher.Avalonia.csproj‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia/SimpleLauncher.Avalonia.csproj
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
<AssemblyName>SimpleLauncher.Avalonia</AssemblyName>
1919
<RootNamespace>SimpleLauncher.Avalonia</RootNamespace>
2020
<SupportedOSPlatformVersion>7.0</SupportedOSPlatformVersion>
21-
<AssemblyVersion>5.8.3</AssemblyVersion>
22-
<FileVersion>5.8.3</FileVersion>
23-
<Version>5.8.3</Version>
21+
<AssemblyVersion>5.8.4</AssemblyVersion>
22+
<FileVersion>5.8.4</FileVersion>
23+
<Version>5.8.4</Version>
2424
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
2525
<ApplicationIcon>icon\icon.ico</ApplicationIcon>
2626
<PackageIcon>icon\icon2.png</PackageIcon>
@@ -78,7 +78,7 @@
7878

7979
<ItemGroup>
8080
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
81-
<PackageReference Include="Meziantou.Analyzer" Version="3.0.314">
81+
<PackageReference Include="Meziantou.Analyzer" Version="3.0.315">
8282
<PrivateAssets>all</PrivateAssets>
8383
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
8484
</PackageReference>
Collapse file

‎SimpleLauncher.Avalonia/app.manifest‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Avalonia/app.manifest
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
3-
<assemblyIdentity version="5.8.3.0" name="SimpleLauncher.Avalonia" />
3+
<assemblyIdentity version="5.8.4.0" name="SimpleLauncher.Avalonia" />
44
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
55
<security>
66
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
Collapse file

‎SimpleLauncher.Core/SimpleLauncher.Core.csproj‎

Copy file name to clipboardExpand all lines: SimpleLauncher.Core/SimpleLauncher.Core.csproj
+5-5Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@
1414
<DebugSymbols>true</DebugSymbols>
1515
<RepositoryUrl>https://github.com/purelogiccode/SimpleLauncher</RepositoryUrl>
1616
<RepositoryType>git</RepositoryType>
17-
<AssemblyVersion>5.8.3</AssemblyVersion>
18-
<FileVersion>5.8.3</FileVersion>
19-
<Version>5.8.3</Version>
17+
<AssemblyVersion>5.8.4</AssemblyVersion>
18+
<FileVersion>5.8.4</FileVersion>
19+
<Version>5.8.4</Version>
2020
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
2121
</PropertyGroup>
2222

@@ -30,7 +30,7 @@
3030
<PackageReference Include="CHDSharp" Version="1.5.0" />
3131
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.2" />
3232
<PackageReference Include="InputSimulatorCore" Version="1.0.5" />
33-
<PackageReference Include="Meziantou.Analyzer" Version="3.0.314">
33+
<PackageReference Include="Meziantou.Analyzer" Version="3.0.315">
3434
<PrivateAssets>all</PrivateAssets>
3535
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3636
</PackageReference>
@@ -56,7 +56,7 @@
5656
<PrivateAssets>all</PrivateAssets>
5757
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
5858
</PackageReference>
59-
<PackageReference Include="SharpCompress" Version="0.50.6" />
59+
<PackageReference Include="SharpCompress" Version="0.50.7" />
6060
<PackageReference Include="SourceGear.sqlite3" Version="3.53.4" />
6161
<PackageReference Include="System.Security.Cryptography.ProtectedData" Version="10.0.13" />
6262
<PackageReference Include="Tomlyn" Version="2.10.1" />

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.