diff --git a/LogAnalyzerForWindows/LogAnalyzerForWindows.csproj b/LogAnalyzerForWindows/LogAnalyzerForWindows.csproj
index 8f68546..f2f478d 100644
--- a/LogAnalyzerForWindows/LogAnalyzerForWindows.csproj
+++ b/LogAnalyzerForWindows/LogAnalyzerForWindows.csproj
@@ -25,9 +25,9 @@
LogAnalyzerForWindows
- 1.4.0.0
- 1.4.0.0
- 1.4.0
+ 1.4.1.0
+ 1.4.1.0
+ 1.4.1
Bohdan Harabadzhyu
diff --git a/LogAnalyzerForWindows/Program.cs b/LogAnalyzerForWindows/Program.cs
index be21a86..5681874 100644
--- a/LogAnalyzerForWindows/Program.cs
+++ b/LogAnalyzerForWindows/Program.cs
@@ -1,4 +1,6 @@
-using System.Runtime.Versioning;
+using System.Diagnostics;
+using System.Runtime.Versioning;
+using System.Security.Principal;
using Avalonia;
using Avalonia.ReactiveUI;
using LogAnalyzerForWindows.Services;
@@ -10,13 +12,21 @@ namespace LogAnalyzerForWindows;
internal sealed class Program
{
public static SingleInstanceService? SingleInstance { get; private set; }
+ private static bool IsElevated { get; set; }
- // Initialization code. Don't use any Avalonia, third-party APIs or any
- // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
- // yet and stuff might break.
[STAThread]
public static void Main(string[] args)
{
+ IsElevated = IsRunningAsAdmin();
+
+ if (!IsElevated && !args.Contains("--no-elevate"))
+ {
+ if (TryRestartAsAdmin())
+ {
+ return;
+ }
+ }
+
SingleInstance = new SingleInstanceService();
if (!SingleInstance.TryStart())
@@ -35,7 +45,51 @@ public static void Main(string[] args)
}
}
- // Avalonia configuration, don't remove; also used by visual designer.
+ private static bool IsRunningAsAdmin()
+ {
+ try
+ {
+ using var identity = WindowsIdentity.GetCurrent();
+ var principal = new WindowsPrincipal(identity);
+ return principal.IsInRole(WindowsBuiltInRole.Administrator);
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
+ private static bool TryRestartAsAdmin()
+ {
+ try
+ {
+ var exePath = Environment.ProcessPath;
+ if (string.IsNullOrEmpty(exePath))
+ {
+ return false;
+ }
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = exePath,
+ UseShellExecute = true,
+ Verb = "runas",
+ Arguments = string.Join(" ", Environment.GetCommandLineArgs().Skip(1))
+ };
+
+ Process.Start(startInfo);
+ return true;
+ }
+ catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 1223)
+ {
+ return false;
+ }
+ catch
+ {
+ return false;
+ }
+ }
+
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure()
.UsePlatformDetect()
diff --git a/LogAnalyzerForWindows/ViewModels/DashboardViewModel.cs b/LogAnalyzerForWindows/ViewModels/DashboardViewModel.cs
index e33ad22..417dad7 100644
--- a/LogAnalyzerForWindows/ViewModels/DashboardViewModel.cs
+++ b/LogAnalyzerForWindows/ViewModels/DashboardViewModel.cs
@@ -34,6 +34,9 @@ internal sealed class DashboardViewModel : INotifyPropertyChanged
private Axis[] _sourcesXAxes = [];
private Axis[] _sourcesYAxes = [];
+ private Axis[] _eventIdsXAxes = [];
+ private Axis[] _eventIdsYAxes = [];
+
public DashboardViewModel(ILogRepository repository)
{
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
@@ -114,6 +117,18 @@ public Axis[] TimelineYAxes
private set => SetProperty(ref _timelineYAxes, value);
}
+ public Axis[] EventIdsXAxes
+ {
+ get => _eventIdsXAxes;
+ private set => SetProperty(ref _eventIdsXAxes, value);
+ }
+
+ public Axis[] EventIdsYAxes
+ {
+ get => _eventIdsYAxes;
+ private set => SetProperty(ref _eventIdsYAxes, value);
+ }
+
public ISeries[] TopSourcesSeries
{
get => _topSourcesSeries;
@@ -186,6 +201,27 @@ private void InitializeChartAxes()
MinLimit = 0
}
];
+
+ EventIdsYAxes =
+ [
+ new Axis
+ {
+ Labels = [],
+ LabelsPaint = new SolidColorPaint(SKColors.LightGray),
+ TextSize = 12
+ }
+ ];
+
+ EventIdsXAxes =
+ [
+ new Axis
+ {
+ Name = "Count",
+ NamePaint = new SolidColorPaint(SKColors.White),
+ LabelsPaint = new SolidColorPaint(SKColors.LightGray),
+ MinLimit = 0
+ }
+ ];
}
public async Task LoadSessionsAsync()
@@ -363,24 +399,46 @@ private void UpdateTopEventIdsChart(List<(int EventId, int Count)> topEventIds)
if (topEventIds.Count == 0)
{
TopEventIdsSeries = [];
+ EventIdsYAxes = [new Axis { Labels = [] }];
return;
}
- var data = topEventIds
- .Select(e => new { Label = $"ID: {e.EventId}", Value = e.Count })
- .ToList();
+ var labels = topEventIds.Select(e => $"ID: {e.EventId}").ToArray();
+ var values = topEventIds.Select(e => e.Count).ToArray();
TopEventIdsSeries =
[
new RowSeries
{
Name = "Event Count",
- Values = data.Select(d => d.Value).ToArray(),
+ Values = values,
Fill = new SolidColorPaint(SKColors.Coral),
Stroke = null,
MaxBarWidth = 25,
DataLabelsPaint = new SolidColorPaint(SKColors.White),
- DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.End
+ DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.End,
+ DataLabelsFormatter = point => point.Coordinate.PrimaryValue.ToString(CultureInfo.InvariantCulture)
+ }
+ ];
+
+ EventIdsYAxes =
+ [
+ new Axis
+ {
+ Labels = labels,
+ LabelsPaint = new SolidColorPaint(SKColors.LightGray),
+ TextSize = 11
+ }
+ ];
+
+ EventIdsXAxes =
+ [
+ new Axis
+ {
+ Name = "Count",
+ NamePaint = new SolidColorPaint(SKColors.White),
+ LabelsPaint = new SolidColorPaint(SKColors.LightGray),
+ MinLimit = 0
}
];
}
diff --git a/LogAnalyzerForWindows/Views/DashboardView.axaml b/LogAnalyzerForWindows/Views/DashboardView.axaml
index cfa1b9e..3eb2c2f 100644
--- a/LogAnalyzerForWindows/Views/DashboardView.axaml
+++ b/LogAnalyzerForWindows/Views/DashboardView.axaml
@@ -187,7 +187,9 @@
Foreground="White"
Margin="0,0,0,10" />
+ Series="{Binding TopEventIdsSeries}"
+ XAxes="{Binding EventIdsXAxes}"
+ YAxes="{Binding EventIdsYAxes}" />
diff --git a/LogAnalyzerForWindows/app.manifest b/LogAnalyzerForWindows/app.manifest
index 7f44dcc..635d398 100644
--- a/LogAnalyzerForWindows/app.manifest
+++ b/LogAnalyzerForWindows/app.manifest
@@ -1,44 +1,25 @@
-
-
-
+
-
-
-
-
true
true
-