Skip to content

Commit acc89ee

Browse files
authored
chore: various finish line tasks (#23)
Related to #22 Fixes: - Exception handler - Exit button shouldn't hang the app - No default locations for `coder-vpn.exe` and `CoderDesktop.log` => use registry for locations - Release build pipeline
1 parent c2791f5 commit acc89ee

26 files changed

+403
-107
lines changed

.github/workflows/ci.yaml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ jobs:
5151
cache-dependency-path: '**/packages.lock.json'
5252
- name: dotnet restore
5353
run: dotnet restore --locked-mode
54-
#- name: dotnet publish
55-
# run: dotnet publish --no-restore --configuration Release --output .\publish
56-
#- name: Upload artifact
57-
# uses: actions/upload-artifact@v4
58-
# with:
59-
# name: publish
60-
# path: .\publish\
54+
# This doesn't call `dotnet publish` on the entire solution, just the
55+
# projects we care about building. Doing a full publish includes test
56+
# libraries and stuff which is pointless.
57+
- name: dotnet publish Coder.Desktop.Vpn.Service
58+
run: dotnet publish .\Vpn.Service\Vpn.Service.csproj --configuration Release --output .\publish\Vpn.Service
59+
- name: dotnet publish Coder.Desktop.App
60+
run: dotnet publish .\App\App.csproj --configuration Release --output .\publish\App
61+
- name: Upload artifact
62+
uses: actions/upload-artifact@v4
63+
with:
64+
name: publish
65+
path: .\publish\

.github/workflows/release.yaml

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
runs-on: windows-latest
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- name: Setup .NET
19+
uses: actions/setup-dotnet@v4
20+
with:
21+
dotnet-version: '8.0.x'
22+
23+
- name: Get version from tag
24+
id: version
25+
shell: pwsh
26+
run: |
27+
$tag = $env:GITHUB_REF -replace 'refs/tags/',''
28+
if ($tag -notmatch '^v\d+\.\d+\.\d+$') {
29+
throw "Tag must be in format v1.2.3"
30+
}
31+
$version = $tag -replace '^v',''
32+
$assemblyVersion = "$version.0"
33+
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
34+
echo "ASSEMBLY_VERSION=$assemblyVersion" >> $env:GITHUB_OUTPUT
35+
36+
- name: Build and publish x64
37+
run: |
38+
dotnet publish src/App/App.csproj -c Release -r win-x64 -p:Version=${{ steps.version.outputs.ASSEMBLY_VERSION }} -o publish/x64
39+
dotnet publish src/Vpn.Service/Vpn.Service.csproj -c Release -r win-x64 -p:Version=${{ steps.version.outputs.ASSEMBLY_VERSION }} -o publish/x64
40+
41+
- name: Build and publish arm64
42+
run: |
43+
dotnet publish src/App/App.csproj -c Release -r win-arm64 -p:Version=${{ steps.version.outputs.ASSEMBLY_VERSION }} -o publish/arm64
44+
dotnet publish src/Vpn.Service/Vpn.Service.csproj -c Release -r win-arm64 -p:Version=${{ steps.version.outputs.ASSEMBLY_VERSION }} -o publish/arm64
45+
46+
- name: Create ZIP archives
47+
shell: pwsh
48+
run: |
49+
Compress-Archive -Path "publish/x64/*" -DestinationPath "./publish/CoderDesktop-${{ steps.version.outputs.VERSION }}-x64.zip"
50+
Compress-Archive -Path "publish/arm64/*" -DestinationPath "./publish/CoderDesktop-${{ steps.version.outputs.VERSION }}-arm64.zip"
51+
52+
- name: Create Release
53+
uses: softprops/action-gh-release@v1
54+
with:
55+
files: |
56+
./publish/CoderDesktop-${{ steps.version.outputs.VERSION }}-x64.zip
57+
./publish/CoderDesktop-${{ steps.version.outputs.VERSION }}-arm64.zip
58+
name: Release ${{ steps.version.outputs.VERSION }}
59+
generate_release_notes: true
60+
env:
61+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,5 +403,7 @@ FodyWeavers.xsd
403403
.idea/**/shelf
404404

405405
publish
406-
WindowsAppRuntimeInstall-x64.exe
406+
WindowsAppRuntimeInstall-*.exe
407+
windowsdesktop-runtime-*.exe
407408
wintun.dll
409+
wintun-*.dll

App/App.csproj

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,42 @@
1010
<PublishProfile>Properties\PublishProfiles\win-$(Platform).pubxml</PublishProfile>
1111
<UseWinUI>true</UseWinUI>
1212
<Nullable>enable</Nullable>
13-
<EnableMsixTooling>false</EnableMsixTooling>
13+
<EnableMsixTooling>true</EnableMsixTooling>
1414
<WindowsPackageType>None</WindowsPackageType>
1515
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
1616
<!-- To use CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute: -->
1717
<LangVersion>preview</LangVersion>
18+
<!-- We have our own implementation of main with exception handling -->
19+
<DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants>
20+
</PropertyGroup>
21+
22+
<PropertyGroup Condition="$(Configuration) == 'Release'">
23+
<PublishTrimmed>true</PublishTrimmed>
24+
<TrimMode>CopyUsed</TrimMode>
25+
<PublishReadyToRun>true</PublishReadyToRun>
26+
<SelfContained>true</SelfContained>
1827
</PropertyGroup>
1928

2029
<ItemGroup>
2130
<Manifest Include="$(ApplicationManifest)" />
2231
</ItemGroup>
2332

24-
<ItemGroup>
25-
<Content Include="Images\SplashScreen.scale-200.png" />
26-
<Content Include="Images\Square150x150Logo.scale-200.png" />
27-
<Content Include="Images\Square44x44Logo.scale-200.png" />
28-
</ItemGroup>
33+
<!--
34+
Clean up unnecessary files (including .xbf XAML Binary Format files)
35+
and (now) empty directories from target. The .xbf files are not
36+
necessary as they are contained within resources.pri.
37+
-->
38+
<Target Name="CleanupTargetDir" AfterTargets="Build;_GenerateProjectPriFileCore" Condition="$(Configuration) == 'Release'">
39+
<ItemGroup>
40+
<FilesToDelete Include="$(TargetDir)**\*.xbf" />
41+
<FilesToDelete Include="$(TargetDir)createdump.exe" />
42+
<DirsToDelete Include="$(TargetDir)Controls" />
43+
<DirsToDelete Include="$(TargetDir)Views" />
44+
</ItemGroup>
45+
46+
<Delete Files="@(FilesToDelete)" />
47+
<RemoveDir Directories="@(DirsToDelete)" />
48+
</Target>
2949

3050
<ItemGroup>
3151
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />

App/App.xaml.cs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
using System;
2-
using System.Diagnostics;
2+
using System.Threading.Tasks;
33
using Coder.Desktop.App.Services;
44
using Coder.Desktop.App.ViewModels;
55
using Coder.Desktop.App.Views;
@@ -13,6 +13,8 @@ public partial class App : Application
1313
{
1414
private readonly IServiceProvider _services;
1515

16+
private bool _handleWindowClosed = true;
17+
1618
public App()
1719
{
1820
var services = new ServiceCollection();
@@ -36,18 +38,27 @@ public App()
3638

3739
_services = services.BuildServiceProvider();
3840

39-
#if DEBUG
40-
UnhandledException += (_, e) => { Debug.WriteLine(e.Exception.ToString()); };
41-
#endif
42-
4341
InitializeComponent();
4442
}
4543

44+
public async Task ExitApplication()
45+
{
46+
_handleWindowClosed = false;
47+
Exit();
48+
var rpcManager = _services.GetRequiredService<IRpcController>();
49+
// TODO: send a StopRequest if we're connected???
50+
await rpcManager.DisposeAsync();
51+
Environment.Exit(0);
52+
}
53+
4654
protected override void OnLaunched(LaunchActivatedEventArgs args)
4755
{
4856
var trayWindow = _services.GetRequiredService<TrayWindow>();
57+
58+
// Prevent the TrayWindow from closing, just hide it.
4959
trayWindow.Closed += (sender, args) =>
5060
{
61+
if (!_handleWindowClosed) return;
5162
args.Handled = true;
5263
trayWindow.AppWindow.Hide();
5364
};

App/Images/SplashScreen.scale-200.png

-5.25 KB
Binary file not shown.
-1.71 KB
Binary file not shown.
-637 Bytes
Binary file not shown.

App/Program.cs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
using System.Threading;
4+
using Microsoft.UI.Dispatching;
5+
using Microsoft.UI.Xaml;
6+
using Microsoft.Windows.AppLifecycle;
7+
using WinRT;
8+
9+
namespace Coder.Desktop.App;
10+
11+
#if DISABLE_XAML_GENERATED_MAIN
12+
public static class Program
13+
{
14+
private static App? app;
15+
#if DEBUG
16+
[DllImport("kernel32.dll")]
17+
private static extern bool AllocConsole();
18+
#endif
19+
20+
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
21+
private static extern int MessageBoxW(IntPtr hWnd, string text, string caption, int type);
22+
23+
[STAThread]
24+
private static void Main(string[] args)
25+
{
26+
try
27+
{
28+
ComWrappersSupport.InitializeComWrappers();
29+
if (!CheckSingleInstance()) return;
30+
Application.Start(p =>
31+
{
32+
var context = new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread());
33+
SynchronizationContext.SetSynchronizationContext(context);
34+
35+
app = new App();
36+
app.UnhandledException += (_, e) =>
37+
{
38+
e.Handled = true;
39+
ShowExceptionAndCrash(e.Exception);
40+
};
41+
});
42+
}
43+
catch (Exception e)
44+
{
45+
ShowExceptionAndCrash(e);
46+
}
47+
}
48+
49+
[STAThread]
50+
private static bool CheckSingleInstance()
51+
{
52+
#if !DEBUG
53+
const string appInstanceName = "Coder.Desktop.App";
54+
#else
55+
const string appInstanceName = "Coder.Desktop.App.Debug";
56+
#endif
57+
58+
var instance = AppInstance.FindOrRegisterForKey(appInstanceName);
59+
return instance.IsCurrent;
60+
}
61+
62+
[STAThread]
63+
private static void ShowExceptionAndCrash(Exception e)
64+
{
65+
const string title = "Coder Desktop Fatal Error";
66+
var message =
67+
"Coder Desktop has encountered a fatal error and must exit.\n\n" +
68+
e + "\n\n" +
69+
Environment.StackTrace;
70+
MessageBoxW(IntPtr.Zero, message, title, 0);
71+
72+
if (app != null)
73+
app.Exit();
74+
75+
// This will log the exception to the Windows Event Log.
76+
#if DEBUG
77+
// And, if in DEBUG mode, it will also log to the console window.
78+
AllocConsole();
79+
#endif
80+
Environment.FailFast("Coder Desktop has encountered a fatal error and must exit.", e);
81+
}
82+
}
83+
#endif
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<!--
33
https://go.microsoft.com/fwlink/?LinkID=208121.
44
-->
@@ -8,7 +8,5 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
88
<Platform>ARM64</Platform>
99
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
1010
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
11-
<SelfContained>true</SelfContained>
12-
<PublishSingleFile>False</PublishSingleFile>
1311
</PropertyGroup>
1412
</Project>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy