Skip to content

Commit 9594b7e

Browse files
committed
Added various launch safety checks
1 parent 13a5485 commit 9594b7e

13 files changed

+218
-142
lines changed

Diff for: ClipboardCanvas/App.xaml.cs

+2-22
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
using CommunityToolkit.Mvvm.DependencyInjection;
99
using CommunityToolkit.WinUI.Notifications;
1010
using ClipboardCanvas.GlobalizationExtensions;
11-
11+
using ClipboardCanvas.Helpers;
1212
using ClipboardCanvas.Services;
1313
using ClipboardCanvas.Services.Implementation;
1414
using Microsoft.AppCenter;
@@ -175,27 +175,7 @@ private void LogException(Exception e, Action tryHandleException = null)
175175

176176
private void LogExceptionToFile(Exception e)
177177
{
178-
string exceptionString = "";
179-
180-
exceptionString += DateTime.Now.ToString(Constants.FileSystem.EXCEPTION_BLOCK_DATE_FORMAT);
181-
exceptionString += "\n";
182-
exceptionString += $">>> HRESULT {e.HResult}\n";
183-
exceptionString += $">>> MESSAGE {e.Message}\n";
184-
exceptionString += $">>> STACKTRACE {e.StackTrace}\n";
185-
exceptionString += $">>> INNER {e.InnerException}\n";
186-
exceptionString += $">>> SOURCE {e.Source}\n\n";
187-
188-
ILogger logger;
189-
try
190-
{
191-
logger = Ioc.Default.GetService<ILogger>(); // Try get Ioc logger
192-
}
193-
catch
194-
{
195-
logger = new ExceptionToFileLogger(); // Use default logger
196-
}
197-
198-
logger.LogToFile(exceptionString);
178+
LoggingHelpers.SafeLogExceptionToFile(e);
199179
}
200180

201181
private void PushErrorNotification()

Diff for: ClipboardCanvas/ClipboardCanvas.csproj

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<OutputType>WinExe</OutputType>
4-
<TargetFramework>net6.0-windows10.0.19041.0</TargetFramework>
4+
<TargetFramework>net6.0-windows10.0.20348.0</TargetFramework>
55
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
66
<RootNamespace>ClipboardCanvas</RootNamespace>
77
<ApplicationManifest>app.manifest</ApplicationManifest>
@@ -25,6 +25,7 @@
2525
<MultilingualFallbackLanguage>en</MultilingualFallbackLanguage>
2626
<TranslationReport Condition="'$(Configuration)' == 'Release'">true</TranslationReport>
2727
<SuppressPseudoWarning Condition="'$(Configuration)' == 'Debug'">true</SuppressPseudoWarning>
28+
<SupportedOSPlatformVersion>10.0.18362.0</SupportedOSPlatformVersion>
2829
</PropertyGroup>
2930
<ItemGroup>
3031
<None Remove="Pages\MainWindowContentPage.xaml" />

Diff for: ClipboardCanvas/Helpers/InitialApplicationChecksHelpers.cs

+50-34
Original file line numberDiff line numberDiff line change
@@ -17,61 +17,77 @@ public static class InitialApplicationChecksHelpers
1717
{
1818
public static async Task CheckVersionAndShowDialog()
1919
{
20-
IApplicationSettingsService applicationSettings = Ioc.Default.GetService<IApplicationSettingsService>();
21-
IApplicationService applicationService = Ioc.Default.GetService<IApplicationService>();
22-
IDialogService dialogService = Ioc.Default.GetService<IDialogService>();
20+
try
21+
{
22+
IApplicationSettingsService applicationSettings = Ioc.Default.GetService<IApplicationSettingsService>();
23+
IApplicationService applicationService = Ioc.Default.GetService<IApplicationService>();
24+
IDialogService dialogService = Ioc.Default.GetService<IDialogService>();
2325

24-
string lastVersion = applicationSettings.LastVersionNumber;
25-
string currentVersion = applicationService.AppVersion;
26+
string lastVersion = applicationSettings.LastVersionNumber;
27+
string currentVersion = applicationService.AppVersion;
2628

27-
if (string.IsNullOrEmpty(lastVersion))
28-
{
29-
// No version yet, Clipboard Canvas is freshly installed
30-
// update the version setting with current version
31-
applicationSettings.LastVersionNumber = currentVersion;
32-
}
33-
else
34-
{
35-
// Compare two versions
36-
if (VersionHelpers.IsVersionDifferentThan(lastVersion, currentVersion))
29+
if (string.IsNullOrEmpty(lastVersion))
3730
{
38-
// Update the last version number to be the current number
31+
// No version yet, Clipboard Canvas is freshly installed
32+
// update the version setting with current version
3933
applicationSettings.LastVersionNumber = currentVersion;
34+
}
35+
else
36+
{
37+
// Compare two versions
38+
if (VersionHelpers.IsVersionDifferentThan(lastVersion, currentVersion))
39+
{
40+
// Update the last version number to be the current number
41+
applicationSettings.LastVersionNumber = currentVersion;
4042

41-
// Show the update dialog
42-
await dialogService.ShowDialog(new UpdateChangeLogDialogViewModel());
43+
// Show the update dialog
44+
await dialogService.ShowDialog(new UpdateChangeLogDialogViewModel());
45+
}
4346
}
4447
}
48+
catch (Exception ex)
49+
{
50+
LoggingHelpers.SafeLogExceptionToFile(ex);
51+
}
4552
}
4653

4754
public static async Task HandleFileSystemPermissionDialog(IWindowTitleBarControlModel windowTitleBar)
4855
{
49-
IDialogService dialogService = Ioc.Default.GetService<IDialogService>();
50-
IApplicationService applicationService = Ioc.Default.GetService<IApplicationService>();
51-
52-
string testForFolderOnFS = Path.GetFullPath(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
53-
SafeWrapper<StorageFolder> testFolderResult = await StorageHelpers.ToStorageItemWithError<StorageFolder>(testForFolderOnFS);
54-
55-
if (!testFolderResult)
56+
try
5657
{
57-
applicationService.IsInRestrictedAccessMode = true;
58+
IDialogService dialogService = Ioc.Default.GetService<IDialogService>();
59+
IApplicationService applicationService = Ioc.Default.GetService<IApplicationService>();
5860

59-
DialogResult dialogResult = await dialogService.ShowDialog(new FileSystemAccessDialogViewModel());
61+
string testForFolderOnFS =
62+
Path.GetFullPath(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
63+
SafeWrapper<StorageFolder> testFolderResult =
64+
await StorageHelpers.ToStorageItemWithError<StorageFolder>(testForFolderOnFS);
6065

61-
if (dialogResult == DialogResult.Primary)
66+
if (!testFolderResult)
6267
{
63-
// Restart the app
64-
await CoreApplication.RequestRestartAsync(string.Empty);
68+
applicationService.IsInRestrictedAccessMode = true;
69+
70+
DialogResult dialogResult = await dialogService.ShowDialog(new FileSystemAccessDialogViewModel());
71+
72+
if (dialogResult == DialogResult.Primary)
73+
{
74+
// Restart the app
75+
await CoreApplication.RequestRestartAsync(string.Empty);
76+
}
77+
else
78+
{
79+
// Continue in Restricted Access
80+
windowTitleBar.IsInRestrictedAccess = true;
81+
}
6582
}
6683
else
6784
{
68-
// Continue in Restricted Access
69-
windowTitleBar.IsInRestrictedAccess = true;
85+
return;
7086
}
7187
}
72-
else
88+
catch (Exception ex)
7389
{
74-
return;
90+
LoggingHelpers.SafeLogExceptionToFile(ex);
7591
}
7692
}
7793
}

Diff for: ClipboardCanvas/Helpers/LoggingHelpers.cs

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
using ClipboardCanvas.Services;
7+
using ClipboardCanvas.Services.Implementation;
8+
using CommunityToolkit.Mvvm.DependencyInjection;
9+
10+
namespace ClipboardCanvas.Helpers
11+
{
12+
public static class LoggingHelpers
13+
{
14+
public static void SafeLogExceptionToFile(Exception ex)
15+
{
16+
if (ex == null)
17+
{
18+
return;
19+
}
20+
21+
string exceptionString = "";
22+
23+
exceptionString += DateTime.Now.ToString(Constants.FileSystem.EXCEPTION_BLOCK_DATE_FORMAT);
24+
exceptionString += "\n";
25+
exceptionString += $">>> HRESULT {ex.HResult}\n";
26+
exceptionString += $">>> MESSAGE {ex.Message}\n";
27+
exceptionString += $">>> STACKTRACE {ex.StackTrace}\n";
28+
exceptionString += $">>> INNER {ex.InnerException}\n";
29+
exceptionString += $">>> SOURCE {ex.Source}\n\n";
30+
31+
ILogger logger;
32+
try
33+
{
34+
logger = Ioc.Default.GetService<ILogger>(); // Try get Ioc logger
35+
}
36+
catch
37+
{
38+
logger = new ExceptionToFileLogger(); // Use default logger
39+
}
40+
41+
logger?.LogToFile(exceptionString);
42+
}
43+
}
44+
}

Diff for: ClipboardCanvas/MainWindow.xaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
66
xmlns:local="using:ClipboardCanvas"
77
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
xmlns:pg="using:ClipboardCanvas.Pages"
89
xmlns:uc="using:ClipboardCanvas.UserControls"
910
xmlns:uc2="using:ClipboardCanvas.UserControls.OOBE"
1011
mc:Ignorable="d">
1112

12-
<Frame x:Name="MainWindowFrame" />
13+
<pg:MainWindowContentPage x:Name="MainPageHost" />
1314

1415
</Window>

Diff for: ClipboardCanvas/MainWindow.xaml.cs

+16-14
Original file line numberDiff line numberDiff line change
@@ -22,32 +22,34 @@ public sealed partial class MainWindow : Window
2222
{
2323
public static MainWindow Instance;
2424

25-
public MainWindowContentPage MainWindowContentPage => MainWindowFrame.Content as MainWindowContentPage;
25+
public MainWindowContentPage MainWindowContentPage => MainPageHost;
2626

2727
public static ApplicationViewTitleBar TitleBar { get; private set; }
2828

2929
public static CoreApplicationViewTitleBar CoreTitleBar { get; private set; }
3030

3131
public MainWindow()
3232
{
33-
this.InitializeComponent();
3433
Instance = this;
35-
MainWindowFrame.Navigate(typeof(MainWindowContentPage), null, new SuppressNavigationTransitionInfo());
34+
this.InitializeComponent();
3635

37-
Initialize();
36+
EnsureSafeInitialization();
3837
}
3938

40-
private void Initialize()
39+
private void EnsureSafeInitialization()
4140
{
42-
Title = "Clipboard Canvas";
43-
ExtendsContentIntoTitleBar = true;
44-
SetTitleBar(MainWindowContentPage.WindowTitleBar.DraggableRegion);
45-
46-
IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
47-
int wndLong = User32.GetWindowLong(hwnd, User32.WindowLongFlags.GWL_STYLE);
48-
User32.SetWindowLong(hwnd, User32.WindowLongFlags.GWL_STYLE, wndLong | (int)User32.WindowStyles.WS_SYSMENU);
49-
50-
ThemeHelper.Initialize();
41+
try
42+
{
43+
Title = "Clipboard Canvas";
44+
ExtendsContentIntoTitleBar = true;
45+
SetTitleBar(MainWindowContentPage.WindowTitleBar.DraggableRegion);
46+
47+
ThemeHelper.Initialize();
48+
}
49+
catch (Exception ex)
50+
{
51+
LoggingHelpers.SafeLogExceptionToFile(ex);
52+
}
5153
}
5254
}
5355
}

Diff for: ClipboardCanvas/Services/Implementation/ApplicationService.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.UI.Windowing;
88

99
using ClipboardCanvas.DataModels;
10+
using ClipboardCanvas.Helpers;
1011

1112
namespace ClipboardCanvas.Services.Implementation
1213
{
@@ -36,8 +37,15 @@ public IntPtr GetHwnd(Window wnd)
3637

3738
public ApplicationService()
3839
{
39-
MainWindow.Instance.Activated -= Current_Activated;
40-
MainWindow.Instance.Activated += Current_Activated;
40+
try
41+
{
42+
MainWindow.Instance.Activated -= Current_Activated;
43+
MainWindow.Instance.Activated += Current_Activated;
44+
}
45+
catch (Exception ex)
46+
{
47+
LoggingHelpers.SafeLogExceptionToFile(ex);
48+
}
4149
}
4250

4351
private void Current_Activated(object sender, WindowActivatedEventArgs e)

Diff for: ClipboardCanvas/Services/Implementation/NavigationService.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
using ClipboardCanvas.DisplayFrameEventArgs;
1010
using ClipboardCanvas.ViewModels.UserControls.Collections;
1111

12+
#nullable enable
13+
1214
namespace ClipboardCanvas.Services.Implementation
1315
{
1416
public class NavigationService : INavigationService
1517
{
16-
public Frame DisplayFrame { get; internal set; }
18+
public Frame? DisplayFrame { get; internal set; }
1719

18-
public Func<bool> CheckCollectionAvailabilityBeforePageNavigation { get; internal set; }
20+
public Func<bool>? CheckCollectionAvailabilityBeforePageNavigation { get; internal set; }
1921

2022
public DisplayPageType CurrentPage { get; private set; }
2123

@@ -39,7 +41,7 @@ public bool OpenNewCanvas(ICollectionModel collection, NavigationTransitionType
3941
BaseDisplayFrameParameterDataModel navigationParameter = new CanvasPageNavigationParameterModel(collection, (CanvasType)canvasType);
4042
LastPage = CurrentPage;
4143
CurrentPage = DisplayPageType.CanvasPage;
42-
DisplayFrame.Navigate(typeof(CanvasPage), navigationParameter, transitionType.ToNavigationTransition());
44+
DisplayFrame?.Navigate(typeof(CanvasPage), navigationParameter, transitionType.ToNavigationTransition());
4345

4446
OnNavigationFinishedEvent?.Invoke(this, new NavigationFinishedEventArgs(true, null, collection, (CanvasType)canvasType, DisplayPageType.CanvasPage));
4547

@@ -53,7 +55,7 @@ public bool OpenCanvasPage(ICollectionModel collection, CollectionItemViewModel
5355
canvasType = collection.AssociatedCanvasType;
5456
}
5557

56-
if (!CheckCollectionAvailabilityBeforePageNavigation())
58+
if (!CheckCollectionAvailabilityBeforePageNavigation?.Invoke() ?? true)
5759
{
5860
OnNavigationFinishedEvent?.Invoke(this, new NavigationFinishedEventArgs(false, null, collection, (CanvasType)canvasType, DisplayPageType.CanvasPage));
5961
return false;

Diff for: ClipboardCanvas/ValueConverters/BooleanInvertConverter.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public object Convert(object value, Type targetType, object parameter, string la
1212
return false;
1313
}
1414

15-
if (parameter is string strParam && strParam.ToLower() == "invert") // For debugging purposes
15+
if (parameter is string strParam && strParam.ToLower() == "invert")
1616
{
1717
return boolVal;
1818
}

Diff for: ClipboardCanvas/ViewModels/UserControls/Autopaste/AutopasteControlViewModel.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
using ClipboardCanvas.ViewModels.UserControls.Autopaste.Rules;
2222
using ClipboardCanvas.ViewModels.UserControls.Collections;
2323

24+
#nullable enable
25+
2426
namespace ClipboardCanvas.ViewModels.UserControls.Autopaste
2527
{
2628
public class AutopasteControlViewModel : ObservableObject, IRuleActions, IDisposable
@@ -137,7 +139,7 @@ public Task Initialize()
137139
{
138140
if (!string.IsNullOrEmpty(AutopasteSettingsService.AutopastePath))
139141
{
140-
IAutopasteTarget autopasteTarget = CollectionsWidgetViewModel.FindCollection(AutopasteSettingsService.AutopastePath);
142+
var autopasteTarget = CollectionsWidgetViewModel.FindCollection(AutopasteSettingsService.AutopastePath);
141143
UpdateTarget(autopasteTarget);
142144
}
143145

@@ -168,7 +170,7 @@ private void AddRuleToRuleset(BaseAutopasteRuleViewModel ruleViewModel)
168170
_itemAddedInternally = false;
169171
}
170172

171-
public void UpdateTarget(IAutopasteTarget autopasteTarget)
173+
public void UpdateTarget(IAutopasteTarget? autopasteTarget)
172174
{
173175
this.AutopasteTarget = autopasteTarget;
174176
OnPropertyChanged(nameof(AutopasteTargetName));

0 commit comments

Comments
 (0)