Skip to content

Commit 6ad0973

Browse files
DashboardViewModel
1 parent 3734589 commit 6ad0973

5 files changed

Lines changed: 129 additions & 34 deletions

File tree

LogAnalyzerForWindows/LogAnalyzerForWindows.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
<RootNamespace>LogAnalyzerForWindows</RootNamespace>
2626

2727
<!-- Version Info -->
28-
<AssemblyVersion>1.4.0.0</AssemblyVersion>
29-
<FileVersion>1.4.0.0</FileVersion>
30-
<InformationalVersion>1.4.0</InformationalVersion>
28+
<AssemblyVersion>1.4.1.0</AssemblyVersion>
29+
<FileVersion>1.4.1.0</FileVersion>
30+
<InformationalVersion>1.4.1</InformationalVersion>
3131

3232
<!-- Product Info -->
3333
<Authors>Bohdan Harabadzhyu</Authors>

LogAnalyzerForWindows/Program.cs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
using System.Runtime.Versioning;
1+
using System.Diagnostics;
2+
using System.Runtime.Versioning;
3+
using System.Security.Principal;
24
using Avalonia;
35
using Avalonia.ReactiveUI;
46
using LogAnalyzerForWindows.Services;
@@ -10,13 +12,21 @@ namespace LogAnalyzerForWindows;
1012
internal sealed class Program
1113
{
1214
public static SingleInstanceService? SingleInstance { get; private set; }
15+
private static bool IsElevated { get; set; }
1316

14-
// Initialization code. Don't use any Avalonia, third-party APIs or any
15-
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized
16-
// yet and stuff might break.
1717
[STAThread]
1818
public static void Main(string[] args)
1919
{
20+
IsElevated = IsRunningAsAdmin();
21+
22+
if (!IsElevated && !args.Contains("--no-elevate"))
23+
{
24+
if (TryRestartAsAdmin())
25+
{
26+
return;
27+
}
28+
}
29+
2030
SingleInstance = new SingleInstanceService();
2131

2232
if (!SingleInstance.TryStart())
@@ -35,7 +45,51 @@ public static void Main(string[] args)
3545
}
3646
}
3747

38-
// Avalonia configuration, don't remove; also used by visual designer.
48+
private static bool IsRunningAsAdmin()
49+
{
50+
try
51+
{
52+
using var identity = WindowsIdentity.GetCurrent();
53+
var principal = new WindowsPrincipal(identity);
54+
return principal.IsInRole(WindowsBuiltInRole.Administrator);
55+
}
56+
catch
57+
{
58+
return false;
59+
}
60+
}
61+
62+
private static bool TryRestartAsAdmin()
63+
{
64+
try
65+
{
66+
var exePath = Environment.ProcessPath;
67+
if (string.IsNullOrEmpty(exePath))
68+
{
69+
return false;
70+
}
71+
72+
var startInfo = new ProcessStartInfo
73+
{
74+
FileName = exePath,
75+
UseShellExecute = true,
76+
Verb = "runas",
77+
Arguments = string.Join(" ", Environment.GetCommandLineArgs().Skip(1))
78+
};
79+
80+
Process.Start(startInfo);
81+
return true;
82+
}
83+
catch (System.ComponentModel.Win32Exception ex) when (ex.NativeErrorCode == 1223)
84+
{
85+
return false;
86+
}
87+
catch
88+
{
89+
return false;
90+
}
91+
}
92+
3993
public static AppBuilder BuildAvaloniaApp()
4094
=> AppBuilder.Configure<App>()
4195
.UsePlatformDetect()

LogAnalyzerForWindows/ViewModels/DashboardViewModel.cs

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ internal sealed class DashboardViewModel : INotifyPropertyChanged
3434
private Axis[] _sourcesXAxes = [];
3535
private Axis[] _sourcesYAxes = [];
3636

37+
private Axis[] _eventIdsXAxes = [];
38+
private Axis[] _eventIdsYAxes = [];
39+
3740
public DashboardViewModel(ILogRepository repository)
3841
{
3942
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
@@ -114,6 +117,18 @@ public Axis[] TimelineYAxes
114117
private set => SetProperty(ref _timelineYAxes, value);
115118
}
116119

120+
public Axis[] EventIdsXAxes
121+
{
122+
get => _eventIdsXAxes;
123+
private set => SetProperty(ref _eventIdsXAxes, value);
124+
}
125+
126+
public Axis[] EventIdsYAxes
127+
{
128+
get => _eventIdsYAxes;
129+
private set => SetProperty(ref _eventIdsYAxes, value);
130+
}
131+
117132
public ISeries[] TopSourcesSeries
118133
{
119134
get => _topSourcesSeries;
@@ -186,6 +201,27 @@ private void InitializeChartAxes()
186201
MinLimit = 0
187202
}
188203
];
204+
205+
EventIdsYAxes =
206+
[
207+
new Axis
208+
{
209+
Labels = [],
210+
LabelsPaint = new SolidColorPaint(SKColors.LightGray),
211+
TextSize = 12
212+
}
213+
];
214+
215+
EventIdsXAxes =
216+
[
217+
new Axis
218+
{
219+
Name = "Count",
220+
NamePaint = new SolidColorPaint(SKColors.White),
221+
LabelsPaint = new SolidColorPaint(SKColors.LightGray),
222+
MinLimit = 0
223+
}
224+
];
189225
}
190226

191227
public async Task LoadSessionsAsync()
@@ -363,24 +399,46 @@ private void UpdateTopEventIdsChart(List<(int EventId, int Count)> topEventIds)
363399
if (topEventIds.Count == 0)
364400
{
365401
TopEventIdsSeries = [];
402+
EventIdsYAxes = [new Axis { Labels = [] }];
366403
return;
367404
}
368405

369-
var data = topEventIds
370-
.Select(e => new { Label = $"ID: {e.EventId}", Value = e.Count })
371-
.ToList();
406+
var labels = topEventIds.Select(e => $"ID: {e.EventId}").ToArray();
407+
var values = topEventIds.Select(e => e.Count).ToArray();
372408

373409
TopEventIdsSeries =
374410
[
375411
new RowSeries<int>
376412
{
377413
Name = "Event Count",
378-
Values = data.Select(d => d.Value).ToArray(),
414+
Values = values,
379415
Fill = new SolidColorPaint(SKColors.Coral),
380416
Stroke = null,
381417
MaxBarWidth = 25,
382418
DataLabelsPaint = new SolidColorPaint(SKColors.White),
383-
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.End
419+
DataLabelsPosition = LiveChartsCore.Measure.DataLabelsPosition.End,
420+
DataLabelsFormatter = point => point.Coordinate.PrimaryValue.ToString(CultureInfo.InvariantCulture)
421+
}
422+
];
423+
424+
EventIdsYAxes =
425+
[
426+
new Axis
427+
{
428+
Labels = labels,
429+
LabelsPaint = new SolidColorPaint(SKColors.LightGray),
430+
TextSize = 11
431+
}
432+
];
433+
434+
EventIdsXAxes =
435+
[
436+
new Axis
437+
{
438+
Name = "Count",
439+
NamePaint = new SolidColorPaint(SKColors.White),
440+
LabelsPaint = new SolidColorPaint(SKColors.LightGray),
441+
MinLimit = 0
384442
}
385443
];
386444
}

LogAnalyzerForWindows/Views/DashboardView.axaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@
187187
Foreground="White"
188188
Margin="0,0,0,10" />
189189
<lvc:CartesianChart Grid.Row="1"
190-
Series="{Binding TopEventIdsSeries}" />
190+
Series="{Binding TopEventIdsSeries}"
191+
XAxes="{Binding EventIdsXAxes}"
192+
YAxes="{Binding EventIdsYAxes}" />
191193
</Grid>
192194
</Border>
193195
</Grid>

LogAnalyzerForWindows/app.manifest

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,25 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
3-
<!-- This manifest is used on Windows only.
4-
Don't remove it as it might cause problems with window transparency and embeded controls.
5-
For more details visit https://learn.microsoft.com/en-us/windows/win32/sbscs/application-manifests -->
63
<assemblyIdentity version="1.0.0.0" name="LogAnalyzerForWindows.Desktop"/>
74

85
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
96
<security>
107
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
11-
<!-- UAC Manifest Options
12-
13-
14-
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
15-
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
16-
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
17-
-->
18-
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
8+
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
199
</requestedPrivileges>
2010
</security>
2111
</trustInfo>
2212

2313
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
2414
<application>
25-
<!-- A list of the Windows versions that this application has been tested on
26-
and is designed to work with. -->
27-
28-
<!-- Windows 10 and Windows 11 -->
2915
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
3016
</application>
3117
</compatibility>
3218

33-
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
34-
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
35-
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
36-
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
3719
<application xmlns="urn:schemas-microsoft-com:asm.v3">
3820
<windowsSettings>
3921
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
4022
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
4123
</windowsSettings>
4224
</application>
43-
4425
</assembly>

0 commit comments

Comments
 (0)