Skip to content

Commit 2002cfd

Browse files
Add StatsService to record application usage
- Introduced `StatsService` to send usage statistics asynchronously to a remote API. - Updated `App.xaml.cs` to initialize and dispose `StatsService` alongside `BugReportService`. - Added constants for the Stats API URL and key in `AppConfig`. - Cleaned up resource exclusion rules in the project file by removing redundant entries.
1 parent c28739d commit 2002cfd

4 files changed

Lines changed: 73 additions & 13 deletions

File tree

BatchConvertToCHD/App.xaml.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace BatchConvertToCHD;
88
public partial class App : IDisposable
99
{
1010
private BugReportService? _bugReportService;
11+
private StatsService? _statsService;
1112

1213
/// <summary>
1314
/// Provides a shared, static instance of the BugReportService for the entire application.
@@ -16,10 +17,12 @@ public partial class App : IDisposable
1617

1718
public App()
1819
{
19-
// Initialize the bug report service first to ensure it's available for reporting initialization errors
20+
// Initialize services
2021
SharedBugReportService = new BugReportService(AppConfig.BugReportApiUrl, AppConfig.BugReportApiKey, AppConfig.ApplicationName);
2122
_bugReportService = SharedBugReportService;
2223

24+
_statsService = new StatsService(AppConfig.ApplicationStatsApiUrl, AppConfig.ApplicationStatsApiKey, AppConfig.ApplicationName);
25+
2326
// Set up global exception handling
2427
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
2528
DispatcherUnhandledException += App_DispatcherUnhandledException;
@@ -36,6 +39,9 @@ protected override void OnStartup(StartupEventArgs e)
3639

3740
base.OnStartup(e);
3841

42+
// Record usage statistics on a background thread
43+
_ = _statsService?.RecordUsageAsync();
44+
3945
// Preload assemblies on background thread to improve responsiveness
4046
Task.Run(static () =>
4147
{
@@ -85,12 +91,14 @@ private static void DeleteOldDllFiles()
8591

8692
private void App_Exit(object sender, ExitEventArgs e)
8793
{
88-
// Dispose the bug report service and clear references to prevent double disposal
89-
// if Dispose() is called explicitly later
94+
// Dispose services and clear references to prevent double disposal
9095
_bugReportService?.Dispose();
9196
_bugReportService = null;
9297
SharedBugReportService = null;
9398

99+
_statsService?.Dispose();
100+
_statsService = null;
101+
94102
// Unregister static event handlers to prevent memory leaks
95103
AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
96104
DispatcherUnhandledException -= App_DispatcherUnhandledException;
@@ -141,12 +149,12 @@ public void Dispose()
141149
{
142150
// Cleanup is primarily handled in App_Exit. This method provides a safety net
143151
// for explicit disposal scenarios and prevents double disposal.
144-
if (_bugReportService != null)
145-
{
146-
_bugReportService.Dispose();
147-
_bugReportService = null;
148-
SharedBugReportService = null;
149-
}
152+
_bugReportService?.Dispose();
153+
_bugReportService = null;
154+
SharedBugReportService = null;
155+
156+
_statsService?.Dispose();
157+
_statsService = null;
150158

151159
// Unregister static event handlers to prevent them from firing after disposal
152160
AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;

BatchConvertToCHD/AppConfig.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ internal static class AppConfig
1212
public const string PsxPackagerExeName = "psxpackager.exe";
1313
public const string BugReportApiUrl = "https://www.purelogiccode.com/bugreport/api/send-bug-report";
1414
public const string BugReportApiKey = "hjh7yu6t56tyr540o9u8767676r5674534453235264c75b6t7ggghgg76trf564e";
15+
public const string ApplicationStatsApiUrl = "https://www.purelogiccode.com/ApplicationStats/stats";
16+
public const string ApplicationStatsApiKey = "hjh7yu6t56tyr540o9u8767676r5674534453235264c75b6t7ggghgg76trf564e";
1517
public const string ApplicationName = "BatchConvertToCHD";
1618
public const int WriteSpeedUpdateIntervalMs = 1000;
1719

BatchConvertToCHD/BatchConvertToCHD.csproj

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,7 @@
4444
</ItemGroup>
4545

4646
<ItemGroup>
47-
<Compile Remove="References\**" />
48-
<None Remove="References\**" />
49-
<Page Remove="References\**" />
5047
<Resource Remove="References\**" />
51-
<EmbeddedResource Remove="References\**" />
5248
<ApplicationDefinition Remove="References\**" />
5349
</ItemGroup>
5450

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using System.Net.Http;
2+
using System.Net.Http.Json;
3+
using System.Reflection;
4+
5+
namespace BatchConvertToCHD.Services;
6+
7+
/// <summary>
8+
/// Service responsible for recording application usage statistics.
9+
/// </summary>
10+
public class StatsService : IDisposable
11+
{
12+
private readonly HttpClient _httpClient = new();
13+
private readonly string _apiUrl;
14+
private readonly string _apiKey;
15+
private readonly string _applicationId;
16+
17+
public StatsService(string apiUrl, string apiKey, string applicationId)
18+
{
19+
_apiUrl = apiUrl;
20+
_apiKey = apiKey;
21+
_applicationId = applicationId;
22+
23+
// Authorization header as specified in the API documentation
24+
_httpClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {_apiKey}");
25+
}
26+
27+
/// <summary>
28+
/// Records application usage statistics by sending a POST request to the Stats API.
29+
/// </summary>
30+
public async Task RecordUsageAsync()
31+
{
32+
try
33+
{
34+
var version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "1.0.0";
35+
36+
var payload = new
37+
{
38+
applicationId = _applicationId, version
39+
};
40+
41+
await _httpClient.PostAsJsonAsync(_apiUrl, payload);
42+
}
43+
catch
44+
{
45+
// Silently fail to not interrupt application startup
46+
}
47+
}
48+
49+
public void Dispose()
50+
{
51+
_httpClient.Dispose();
52+
GC.SuppressFinalize(this);
53+
}
54+
}

0 commit comments

Comments
 (0)