Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitacc89ee

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` => useregistry for locations- Release build pipeline
1 parentc2791f5 commitacc89ee

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+
<PropertyGroupCondition="$(Configuration) == 'Release'">
23+
<PublishTrimmed>true</PublishTrimmed>
24+
<TrimMode>CopyUsed</TrimMode>
25+
<PublishReadyToRun>true</PublishReadyToRun>
26+
<SelfContained>true</SelfContained>
1827
</PropertyGroup>
1928

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

24-
<ItemGroup>
25-
<ContentInclude="Images\SplashScreen.scale-200.png" />
26-
<ContentInclude="Images\Square150x150Logo.scale-200.png" />
27-
<ContentInclude="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+
<TargetName="CleanupTargetDir"AfterTargets="Build;_GenerateProjectPriFileCore"Condition="$(Configuration) == 'Release'">
39+
<ItemGroup>
40+
<FilesToDeleteInclude="$(TargetDir)**\*.xbf" />
41+
<FilesToDeleteInclude="$(TargetDir)createdump.exe" />
42+
<DirsToDeleteInclude="$(TargetDir)Controls" />
43+
<DirsToDeleteInclude="$(TargetDir)Views" />
44+
</ItemGroup>
45+
46+
<DeleteFiles="@(FilesToDelete)" />
47+
<RemoveDirDirectories="@(DirsToDelete)" />
48+
</Target>
2949

3050
<ItemGroup>
3151
<PackageReferenceInclude="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
usingSystem;
2-
usingSystem.Diagnostics;
2+
usingSystem.Threading.Tasks;
33
usingCoder.Desktop.App.Services;
44
usingCoder.Desktop.App.ViewModels;
55
usingCoder.Desktop.App.Views;
@@ -13,6 +13,8 @@ public partial class App : Application
1313
{
1414
privatereadonlyIServiceProvider_services;
1515

16+
privatebool_handleWindowClosed=true;
17+
1618
publicApp()
1719
{
1820
varservices=newServiceCollection();
@@ -36,18 +38,27 @@ public App()
3638

3739
_services=services.BuildServiceProvider();
3840

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

44+
publicasyncTaskExitApplication()
45+
{
46+
_handleWindowClosed=false;
47+
Exit();
48+
varrpcManager=_services.GetRequiredService<IRpcController>();
49+
// TODO: send a StopRequest if we're connected???
50+
awaitrpcManager.DisposeAsync();
51+
Environment.Exit(0);
52+
}
53+
4654
protectedoverridevoidOnLaunched(LaunchActivatedEventArgsargs)
4755
{
4856
vartrayWindow=_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+
usingSystem;
2+
usingSystem.Runtime.InteropServices;
3+
usingSystem.Threading;
4+
usingMicrosoft.UI.Dispatching;
5+
usingMicrosoft.UI.Xaml;
6+
usingMicrosoft.Windows.AppLifecycle;
7+
usingWinRT;
8+
9+
namespaceCoder.Desktop.App;
10+
11+
#ifDISABLE_XAML_GENERATED_MAIN
12+
publicstaticclassProgram
13+
{
14+
privatestaticApp?app;
15+
#ifDEBUG
16+
[DllImport("kernel32.dll")]
17+
privatestaticexternboolAllocConsole();
18+
#endif
19+
20+
[DllImport("user32.dll",CharSet=CharSet.Unicode)]
21+
privatestaticexternintMessageBoxW(IntPtrhWnd,stringtext,stringcaption,inttype);
22+
23+
[STAThread]
24+
privatestaticvoidMain(string[]args)
25+
{
26+
try
27+
{
28+
ComWrappersSupport.InitializeComWrappers();
29+
if(!CheckSingleInstance())return;
30+
Application.Start(p=>
31+
{
32+
varcontext=newDispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread());
33+
SynchronizationContext.SetSynchronizationContext(context);
34+
35+
app=newApp();
36+
app.UnhandledException+=(_,e)=>
37+
{
38+
e.Handled=true;
39+
ShowExceptionAndCrash(e.Exception);
40+
};
41+
});
42+
}
43+
catch(Exceptione)
44+
{
45+
ShowExceptionAndCrash(e);
46+
}
47+
}
48+
49+
[STAThread]
50+
privatestaticboolCheckSingleInstance()
51+
{
52+
#if!DEBUG
53+
conststringappInstanceName="Coder.Desktop.App";
54+
#else
55+
conststringappInstanceName="Coder.Desktop.App.Debug";
56+
#endif
57+
58+
varinstance=AppInstance.FindOrRegisterForKey(appInstanceName);
59+
returninstance.IsCurrent;
60+
}
61+
62+
[STAThread]
63+
privatestaticvoidShowExceptionAndCrash(Exceptione)
64+
{
65+
conststringtitle="Coder Desktop Fatal Error";
66+
varmessage=
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+
#ifDEBUG
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>
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>x64</Platform>
99
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
1010
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
11-
<SelfContained>true</SelfContained>
12-
<PublishSingleFile>False</PublishSingleFile>
1311
</PropertyGroup>
1412
</Project>
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>x86</Platform>
99
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
1010
<PublishDir>bin\$(Configuration)\$(TargetFramework)\$(RuntimeIdentifier)\publish\</PublishDir>
11-
<SelfContained>true</SelfContained>
12-
<PublishSingleFile>False</PublishSingleFile>
1311
</PropertyGroup>
1412
</Project>

‎App/Services/CredentialManager.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
usingSystem.Runtime.InteropServices;
33
usingSystem.Text;
44
usingSystem.Text.Json;
5+
usingSystem.Text.Json.Serialization;
56
usingSystem.Threading;
67
usingSystem.Threading.Tasks;
78
usingCoder.Desktop.App.Models;
@@ -10,6 +11,17 @@
1011

1112
namespaceCoder.Desktop.App.Services;
1213

14+
publicclassRawCredentials
15+
{
16+
publicrequiredstringCoderUrl{get;set;}
17+
publicrequiredstringApiToken{get;set;}
18+
}
19+
20+
[JsonSerializable(typeof(RawCredentials))]
21+
publicpartialclassRawCredentialsJsonContext:JsonSerializerContext
22+
{
23+
}
24+
1325
publicinterfaceICredentialManager
1426
{
1527
publiceventEventHandler<CredentialModel>CredentialsChanged;
@@ -123,7 +135,7 @@ private void UpdateState(CredentialModel newModel)
123135
RawCredentials?credentials;
124136
try
125137
{
126-
credentials=JsonSerializer.Deserialize<RawCredentials>(raw);
138+
credentials=JsonSerializer.Deserialize(raw,RawCredentialsJsonContext.Default.RawCredentials);
127139
}
128140
catch(JsonException)
129141
{
@@ -138,16 +150,10 @@ private void UpdateState(CredentialModel newModel)
138150

139151
privatestaticvoidWriteCredentials(RawCredentialscredentials)
140152
{
141-
varraw=JsonSerializer.Serialize(credentials);
153+
varraw=JsonSerializer.Serialize(credentials,RawCredentialsJsonContext.Default.RawCredentials);
142154
NativeApi.WriteCredentials(CredentialsTargetName,raw);
143155
}
144156

145-
privateclassRawCredentials
146-
{
147-
publicrequiredstringCoderUrl{get;set;}
148-
publicrequiredstringApiToken{get;set;}
149-
}
150-
151157
privatestaticclassNativeApi
152158
{
153159
privateconstintCredentialTypeGeneric=1;

‎App/Services/RpcController.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public VpnLifecycleException(string message) : base(message)
3232
}
3333
}
3434

35-
publicinterfaceIRpcController
35+
publicinterfaceIRpcController:IAsyncDisposable
3636
{
3737
publiceventEventHandler<RpcModel>StateChanged;
3838

@@ -224,6 +224,13 @@ public async Task StopVpn(CancellationToken ct = default)
224224
newInvalidOperationException($"Service reported failure:{reply.Stop.ErrorMessage}"));
225225
}
226226

227+
publicasyncValueTaskDisposeAsync()
228+
{
229+
if(_speaker!=null)
230+
await_speaker.DisposeAsync();
231+
GC.SuppressFinalize(this);
232+
}
233+
227234
privatevoidMutateState(Action<RpcModel>mutator)
228235
{
229236
RpcModelnewState;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp