diff --git a/Directory.Packages.props b/Directory.Packages.props
index 2633110b5cf..86878db9fb6 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -92,6 +92,7 @@
+
@@ -121,6 +122,7 @@
+
@@ -159,8 +161,8 @@
-
-
+
+
diff --git a/SteamToolsV2+.sln b/SteamToolsV2+.sln
index 78fe827bf84..c7e7647c43f 100644
--- a/SteamToolsV2+.sln
+++ b/SteamToolsV2+.sln
@@ -204,7 +204,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Essentials", "src\Co
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Essentials.Xamarin", "src\Common.Essentials.Xamarin\Common.Essentials.Xamarin.csproj", "{07C9AC06-5D84-41AB-A3C9-5C5B1A27F526}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Essentials.Maui", "src\Common.Essentials.Maui\Common.Essentials.Maui.csproj", "{5C440EC2-9251-4DB5-A14E-68FF37814F12}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Essentials.Maui", "src\Common.Essentials.Maui\Common.Essentials.Maui.csproj", "{5C440EC2-9251-4DB5-A14E-68FF37814F12}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.CommandLine", "src\ST.Client.CommandLine\ST.Client.CommandLine.csproj", "{1891DD14-628D-4921-8A1E-279320312E95}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.AppCenter", "src\ST.Client.AppCenter\ST.Client.AppCenter.csproj", "{3381B512-7CCB-4211-87B0-273260531BFC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.AppCenter.Avalonia", "src\ST.Client.AppCenter.Avalonia\ST.Client.AppCenter.Avalonia.csproj", "{CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.JumpList", "src\ST.Client.JumpList\ST.Client.JumpList.csproj", "{59E25DF3-C8D0-484E-BFD0-637FE5CBC198}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.JumpList.Avalonia", "src\ST.Client.JumpList.Avalonia\ST.Client.JumpList.Avalonia.csproj", "{F7938AFB-0573-47A9-BB99-F1D0501466D2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -2356,6 +2366,146 @@ Global
{5C440EC2-9251-4DB5-A14E-68FF37814F12}.Release|x64.Build.0 = Release|Any CPU
{5C440EC2-9251-4DB5-A14E-68FF37814F12}.Release|x86.ActiveCfg = Release|Any CPU
{5C440EC2-9251-4DB5-A14E-68FF37814F12}.Release|x86.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|ARM.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|x64.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Debug|x86.Build.0 = Debug|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|ARM.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|ARM.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|ARM64.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|iPhone.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|x64.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|x64.Build.0 = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|x86.ActiveCfg = Release|Any CPU
+ {1891DD14-628D-4921-8A1E-279320312E95}.Release|x86.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|ARM.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|x64.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Debug|x86.Build.0 = Debug|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|ARM.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|ARM.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|ARM64.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|iPhone.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|x64.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|x64.Build.0 = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|x86.ActiveCfg = Release|Any CPU
+ {3381B512-7CCB-4211-87B0-273260531BFC}.Release|x86.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|ARM.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|x64.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Debug|x86.Build.0 = Debug|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|ARM.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|ARM.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|ARM64.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|iPhone.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|x64.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|x64.Build.0 = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|x86.ActiveCfg = Release|Any CPU
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D}.Release|x86.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|ARM.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|x64.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Debug|x86.Build.0 = Debug|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|Any CPU.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|ARM.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|ARM.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|ARM64.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|iPhone.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|x64.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|x64.Build.0 = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|x86.ActiveCfg = Release|Any CPU
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198}.Release|x86.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|ARM.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|ARM.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|ARM64.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|ARM64.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|x64.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Debug|x86.Build.0 = Debug|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|ARM.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|ARM.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|ARM64.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|ARM64.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|iPhone.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|x64.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|x64.Build.0 = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|x86.ActiveCfg = Release|Any CPU
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -2435,6 +2585,11 @@ Global
{41434AB5-48C3-47D4-8721-D118D87F472B} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
{07C9AC06-5D84-41AB-A3C9-5C5B1A27F526} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
{5C440EC2-9251-4DB5-A14E-68FF37814F12} = {83186945-EC14-4B3F-8C6F-B205AA184CA4}
+ {1891DD14-628D-4921-8A1E-279320312E95} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
+ {3381B512-7CCB-4211-87B0-273260531BFC} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
+ {CCB0CAEB-FEFC-4424-B6F4-53D3BB70154D} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
+ {59E25DF3-C8D0-484E-BFD0-637FE5CBC198} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
+ {F7938AFB-0573-47A9-BB99-F1D0501466D2} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
RESX_NeutralResourcesLanguage = zh-Hans
diff --git a/src/Common.CoreLib/Platform.cs b/src/Common.CoreLib/Platform.cs
index 4c31e76e89f..15f1fcee4e6 100644
--- a/src/Common.CoreLib/Platform.cs
+++ b/src/Common.CoreLib/Platform.cs
@@ -36,6 +36,7 @@ public enum Platform
///
/// Universal Windows Platform
///
+ [Obsolete]
UWP = 64,
}
diff --git a/src/Common.Essentials.Maui/Common.Essentials.Maui.csproj b/src/Common.Essentials.Maui/Common.Essentials.Maui.csproj
index c9bbd5e075d..879a70dcfa4 100644
--- a/src/Common.Essentials.Maui/Common.Essentials.Maui.csproj
+++ b/src/Common.Essentials.Maui/Common.Essentials.Maui.csproj
@@ -1,37 +1,13 @@
-
+
- net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst
- $(TargetFrameworks);net6.0-windows10.0.19041.0
-
-
+ net6.0
System.Application.Services
- System.Common.EssentialsLib.Maui
+ Microsoft.Maui.Controls.Pages.UnitTests
true
true
enable
MAUI;$(DefineConstants)
- false
-
-
-
- 14.2
-
-
-
- 14.0
-
-
-
- 21.0
-
-
-
- 10.0.17763.0
-
-
-
- 6.5
@@ -56,7 +32,7 @@
-
+
diff --git a/src/Common.Essentials.Maui/MauiExtensions.cs b/src/Common.Essentials.Maui/MauiExtensions.cs
new file mode 100644
index 00000000000..558b0ba023d
--- /dev/null
+++ b/src/Common.Essentials.Maui/MauiExtensions.cs
@@ -0,0 +1,11 @@
+namespace Microsoft.Maui;
+
+public static class MauiExtensions
+{
+ ///
+ /// https://github.com/dotnet/maui/blob/c963d0a5d971a5f3f012480a190a984e3c733d34/src/Controls/src/Core/HandlerImpl/Window/Window.Impl.cs#L164
+ ///
+ ///
+ ///
+ public static bool IsActivated(this Window window) => window.IsActivated;
+}
diff --git a/src/Common.Essentials/Properties/InternalsVisibleTo.Essentials.cs b/src/Common.Essentials/Properties/InternalsVisibleTo.Essentials.cs
index 842d8967beb..a99eadc7733 100644
--- a/src/Common.Essentials/Properties/InternalsVisibleTo.Essentials.cs
+++ b/src/Common.Essentials/Properties/InternalsVisibleTo.Essentials.cs
@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using static System.Properties.ThisAssembly;
-[assembly: InternalsVisibleTo("System.Common.EssentialsLib.Maui" + PublicKey)]
-[assembly: InternalsVisibleTo("System.Common.EssentialsLib.Xamarin" + PublicKey)]
\ No newline at end of file
+//[assembly: InternalsVisibleTo("System.Common.EssentialsLib.Maui" + PublicKey)]
+[assembly: InternalsVisibleTo("System.Common.EssentialsLib.Xamarin" + PublicKey)]
+[assembly: InternalsVisibleTo("Microsoft.Maui.Controls.Pages.UnitTests" + PublicKey)]
\ No newline at end of file
diff --git a/src/Common.Essentials/Services/IDeviceInfoPlatformService.cs b/src/Common.Essentials/Services/IDeviceInfoPlatformService.cs
index 22b812e8e5b..e68c39e727a 100644
--- a/src/Common.Essentials/Services/IDeviceInfoPlatformService.cs
+++ b/src/Common.Essentials/Services/IDeviceInfoPlatformService.cs
@@ -28,15 +28,7 @@ static EPlatform Platform
{
if (OperatingSystem2.IsWindows())
{
- var i = Interface;
- if (i != null && i.IsUWP)
- {
- return EPlatform.UWP;
- }
- else
- {
- return EPlatform.Windows;
- }
+ return EPlatform.Windows;
}
else if (OperatingSystem2.IsAndroid())
{
diff --git a/src/ST.Client.Android.App.Modern/ST.Client.Android.App.Modern.csproj b/src/ST.Client.Android.App.Modern/ST.Client.Android.App.Modern.csproj
index 3f5481aad41..275244a800c 100644
--- a/src/ST.Client.Android.App.Modern/ST.Client.Android.App.Modern.csproj
+++ b/src/ST.Client.Android.App.Modern/ST.Client.Android.App.Modern.csproj
@@ -59,9 +59,6 @@
Properties\InternalsVisibleTo.cs
-
- VisualStudioAppCenterSDK.cs
-
Services\Implementation\Permissions
@@ -172,9 +169,6 @@
-
-
-
@@ -207,6 +201,7 @@
+
diff --git a/src/ST.Client.Android/ST.Client.Android.csproj b/src/ST.Client.Android/ST.Client.Android.csproj
index 41af8f1b9b6..221a4405c35 100644
--- a/src/ST.Client.Android/ST.Client.Android.csproj
+++ b/src/ST.Client.Android/ST.Client.Android.csproj
@@ -35,9 +35,6 @@
Properties\InternalsVisibleTo.cs
-
- VisualStudioAppCenterSDK.cs
-
Services\Implementation\Permissions
@@ -134,9 +131,6 @@
-
-
-
@@ -165,6 +159,7 @@
+
diff --git a/src/ST.Client.AppCenter.Avalonia/ST.Client.AppCenter.Avalonia.csproj b/src/ST.Client.AppCenter.Avalonia/ST.Client.AppCenter.Avalonia.csproj
new file mode 100644
index 00000000000..5e0539cf18f
--- /dev/null
+++ b/src/ST.Client.AppCenter.Avalonia/ST.Client.AppCenter.Avalonia.csproj
@@ -0,0 +1,42 @@
+
+
+
+ net6.0-windows
+ System.Application
+ System.Application.SteamTools.Client.AppCenter
+ enable
+
+
+
+
+ Properties\AssemblyInfo.cs
+
+
+ Properties\AssemblyInfo.Version.cs
+
+
+ Properties\InternalsVisibleTo.cs
+
+
+ Properties\AssemblyInfo.OS.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ST.Client.AppCenter/ST.Client.AppCenter.csproj b/src/ST.Client.AppCenter/ST.Client.AppCenter.csproj
new file mode 100644
index 00000000000..f1882665740
--- /dev/null
+++ b/src/ST.Client.AppCenter/ST.Client.AppCenter.csproj
@@ -0,0 +1,43 @@
+
+
+
+ MonoAndroid12.0;Xamarin.iOS10;net6.0-android;net6.0-windows
+ System.Application
+ System.Application.SteamTools.Client.AppCenter
+ enable
+
+
+
+
+ Properties\AssemblyInfo.cs
+
+
+ Properties\AssemblyInfo.Version.cs
+
+
+ Properties\InternalsVisibleTo.cs
+
+
+ Properties\AssemblyInfo.OS.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ST.Client.Desktop.Windows/VisualStudioAppCenterSDK.cs b/src/ST.Client.AppCenter/VisualStudioAppCenterSDK.cs
similarity index 92%
rename from src/ST.Client.Desktop.Windows/VisualStudioAppCenterSDK.cs
rename to src/ST.Client.AppCenter/VisualStudioAppCenterSDK.cs
index 116c48b74a0..18750ff8eb0 100644
--- a/src/ST.Client.Desktop.Windows/VisualStudioAppCenterSDK.cs
+++ b/src/ST.Client.AppCenter/VisualStudioAppCenterSDK.cs
@@ -1,19 +1,15 @@
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
-using System;
-using System.ComponentModel;
-using System.Diagnostics.CodeAnalysis;
-using System.IO;
-using System.Security;
-using System.Threading.Tasks;
using System.Application.Security;
-//using static System.Application.AppClientAttribute;
#if WINDOWS
using System.Reflection;
-using static System.Application.VisualStudioAppCenterSDK;
using System.Text;
using Microsoft.AppCenter.Utils;
+using System.Security;
+using System.Diagnostics.CodeAnalysis;
+using System.ComponentModel;
+using static System.Application.VisualStudioAppCenterSDK;
#if DEBUG
using static System.Application.UI.ViewModels.DebugPageViewModel;
#endif
@@ -48,6 +44,8 @@ public static void Init()
static readonly Lazy _AppSecret = new(() =>
{
+#pragma warning disable SA1114 // Parameter list should follow declaration
+#pragma warning disable SA1111 // Closing parenthesis should be on line of last parameter
var r = GetResValue(
#if XAMARIN_MAC || MONO_MAC || MAC
"appcenter-secret-mac"
@@ -59,6 +57,8 @@ public static void Init()
"appcenter-secret"
#endif
);
+#pragma warning restore SA1111 // Closing parenthesis should be on line of last parameter
+#pragma warning restore SA1114 // Parameter list should follow declaration
return r;
});
@@ -170,7 +170,7 @@ namespace Microsoft.Extensions.DependencyInjection
{
public static partial class ServiceCollectionExtensions
{
- static IServiceCollection AddMSAppCenterApplicationSettings(this IServiceCollection services)
+ public static IServiceCollection AddMSAppCenterApplicationSettings(this IServiceCollection services)
{
if (TryGetAppSecret(out var _))
{
diff --git a/src/ST.Client.CommandLine/CommandLineHost.cs b/src/ST.Client.CommandLine/CommandLineHost.cs
new file mode 100644
index 00000000000..b10b14762f8
--- /dev/null
+++ b/src/ST.Client.CommandLine/CommandLineHost.cs
@@ -0,0 +1,223 @@
+using System.Application.UI;
+using System.Application.Services;
+using System.CommandLine;
+using System.CommandLine.NamingConventionBinder;
+using LogLevel = Microsoft.Extensions.Logging.LogLevel;
+
+namespace System.Application.CommandLine;
+
+///
+/// 命令行工具(Command Line Tools/CLT)
+///
+public abstract class CommandLineHost
+{
+ public const string command_main = "main";
+
+ protected abstract IApplication.IDesktopProgramHost Host { get; }
+
+ protected abstract void ConfigureServices(IApplication.IStartupArgs args, DILevel level);
+
+#if StartWatchTrace
+ protected abstract void StartWatchTraceRecord(string? mark = null, bool dispose = false);
+#endif
+
+ public IApplication.SingletonInstance? AppInstance { get; protected set; }
+
+ protected abstract void StartApplication(string[] args);
+
+ public abstract IApplication? Application { get; }
+
+ protected abstract void SetIsMainProcess(bool value);
+
+ protected abstract void SetIsCLTProcess(bool value);
+
+ public int Run(string[] args)
+ {
+ if (args.Length == 0) args = new[] { "-h" };
+
+ // https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2019/march/net-parse-the-command-line-with-system-commandline
+ var rootCommand = new RootCommand("命令行工具(Command Line Tools/CLT)");
+
+ void MainHandler() => MainHandler_(null);
+ void MainHandler_(Action? onInitStartuped)
+ {
+#if StartWatchTrace
+ StartWatchTraceRecord("ProcessCheck");
+#endif
+ ConfigureServices(Host, Host.IsMainProcess ? DILevel.MainProcess : DILevel.Min);
+#if StartWatchTrace
+ StartWatchTraceRecord("Startup.Init");
+#endif
+ onInitStartuped?.Invoke();
+ if (Host.IsMainProcess)
+ {
+ var isInitAppInstanceReset = false;
+ initAppInstance: AppInstance = new();
+ if (!AppInstance.IsFirst)
+ {
+ //Console.WriteLine("ApplicationInstance.SendMessage(string.Empty);");
+ if (IApplication.SingletonInstance.SendMessage(string.Empty))
+ {
+ return;
+ }
+ else
+ {
+ if (!isInitAppInstanceReset &&
+ IApplication.SingletonInstance.TryKillCurrentAllProcess())
+ {
+ isInitAppInstanceReset = true;
+ AppInstance.Dispose();
+ goto initAppInstance;
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+ AppInstance.MessageReceived += value =>
+ {
+ if (string.IsNullOrEmpty(value))
+ {
+ var app = Application;
+ if (app != null)
+ {
+ MainThread2.BeginInvokeOnMainThread(app.RestoreMainWindow);
+ }
+ }
+ };
+ }
+ //#if StartWatchTrace
+ // StartWatchTraceRecord("ApplicationInstance");
+ //#endif
+ // initCef();
+ //#if StartWatchTrace
+ // StartWatchTraceRecord("InitCefNetApp");
+ //#endif
+ if (Host.IsMainProcess)
+ {
+ StartApplication(args);
+ }
+#if StartWatchTrace
+ StartWatchTrace.Record("InitAvaloniaApp");
+#endif
+ }
+ void MainHandlerByCLT() => MainHandlerByCLT_(null);
+ void MainHandlerByCLT_(Action? onInitStartuped)
+ {
+ SetIsMainProcess(true);
+ SetIsCLTProcess(false);
+ MainHandler_(onInitStartuped);
+ }
+
+#if DEBUG
+ // -clt debug -args 730
+ var debug = new Command("debug", "调试");
+ debug.AddOption(new Option("-args", () => "", "测试参数"));
+ debug.Handler = CommandHandler.Create((string args) => // 参数名与类型要与 Option 中一致!
+ {
+ //Console.WriteLine("-clt debug -args " + args);
+ // OutputType WinExe 导致控制台输入不会显示,只能附加一个新的控制台窗口显示内容,不合适
+ // 如果能取消 管理员权限要求,改为运行时管理员权限,
+ // 则可尝试通过 Windows Terminal 或直接 Host 进行命令行模式
+ MainHandlerByCLT();
+ });
+ rootCommand.AddCommand(debug);
+#endif
+
+ var main = new Command(command_main)
+ {
+ Handler = CommandHandler.Create(MainHandler),
+ };
+ rootCommand.AddCommand(main);
+
+ // -clt devtools
+ // -clt devtools -disable_gpu
+ // -clt devtools -use_wgl
+ var devtools = new Command("devtools");
+ devtools.AddOption(new Option("-disable_gpu", () => false, "禁用 GPU 硬件加速"));
+ devtools.AddOption(new Option("-use_wgl", () => false, "使用 Native OpenGL(仅 Windows)"));
+ devtools.Handler = CommandHandler.Create((bool disable_gpu, bool use_wgl) =>
+ {
+ IApplication.EnableDevtools = true;
+ IApplication.DisableGPU = disable_gpu;
+ IApplication.UseWgl = use_wgl;
+ MainHandlerByCLT_(onInitStartuped: () =>
+ {
+ IApplication.LoggerMinLevel = LogLevel.Debug;
+ });
+ });
+ rootCommand.AddCommand(devtools);
+
+ // -clt c -silence
+ var common = new Command("c", "common");
+ common.AddOption(new Option("-silence", "静默启动(不弹窗口)"));
+ common.Handler = CommandHandler.Create((bool silence) =>
+ {
+ Host.IsMinimize = silence;
+ MainHandlerByCLT();
+ });
+ rootCommand.AddCommand(common);
+
+ // -clt steam -account
+ var steamuser = new Command("steam", "Steam 相关操作");
+ steamuser.AddOption(new Option("-account", "指定对应 Steam 用户名"));
+ steamuser.Handler = CommandHandler.Create((string account) =>
+ {
+ if (!string.IsNullOrEmpty(account))
+ {
+ ConfigureServices(Host, DILevel.Steam);
+
+ var steamService = ISteamService.Instance;
+
+ var users = steamService.GetRememberUserList();
+
+ var currentuser = users.Where(s => s.AccountName == account).FirstOrDefault();
+
+ if (currentuser != null)
+ {
+ currentuser.MostRecent = true;
+ steamService.UpdateLocalUserData(users);
+ steamService.SetCurrentUser(account);
+ }
+
+ steamService.TryKillSteamProcess();
+ steamService.StartSteam();
+ }
+ });
+ rootCommand.AddCommand(steamuser);
+
+ // -clt app -id 632360
+ var unlock_achievement = new Command("app", "打开成就解锁窗口");
+ unlock_achievement.AddOption(new Option("-id", "指定一个 Steam 游戏 Id"));
+ unlock_achievement.AddOption(new Option("-silence", "挂运行服务,不加载窗口,内存占用更小"));
+ unlock_achievement.Handler = CommandHandler.Create(async (int id, bool silence) =>
+ {
+ try
+ {
+ if (id <= 0) return;
+ if (!silence)
+ {
+ ConfigureServices(Host, DILevel.GUI | DILevel.Steam | DILevel.HttpClientFactory);
+ IViewModelManager.Instance.InitUnlockAchievement(id);
+ StartApplication(args);
+ }
+ else
+ {
+ ConfigureServices(Host, DILevel.Steam);
+ SteamConnectService.Current.Initialize(id);
+ TaskCompletionSource tcs = new();
+ await tcs.Task;
+ }
+ }
+ catch (Exception ex)
+ {
+ Log.Error(nameof(unlock_achievement), ex, "Start");
+ }
+ });
+ rootCommand.AddCommand(unlock_achievement);
+
+ var r = rootCommand.InvokeAsync(args).GetAwaiter().GetResult();
+ return r;
+ }
+}
diff --git a/src/ST.Client.CommandLine/ST.Client.CommandLine.csproj b/src/ST.Client.CommandLine/ST.Client.CommandLine.csproj
new file mode 100644
index 00000000000..37d0ba502ef
--- /dev/null
+++ b/src/ST.Client.CommandLine/ST.Client.CommandLine.csproj
@@ -0,0 +1,35 @@
+
+
+
+ net6.0
+ System.Application.CommandLine
+ System.Application.SteamTools.Client.CommandLine
+ enable
+
+
+
+
+ Properties\AssemblyInfo.cs
+
+
+ Properties\AssemblyInfo.Version.cs
+
+
+ Properties\InternalsVisibleTo.cs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj b/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj
index d47ae7470e7..293861ae80d 100644
--- a/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj
+++ b/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj
@@ -72,6 +72,9 @@
+
+
+
@@ -84,11 +87,6 @@
-
-
-
-
-
diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge2/ST.Client.Avalonia.App.MsixPackage.csproj b/src/ST.Client.Desktop.Avalonia.App.Bridge2/ST.Client.Avalonia.App.MsixPackage.csproj
index 7ec593d56c7..c4a632fbef6 100644
--- a/src/ST.Client.Desktop.Avalonia.App.Bridge2/ST.Client.Avalonia.App.MsixPackage.csproj
+++ b/src/ST.Client.Desktop.Avalonia.App.Bridge2/ST.Client.Avalonia.App.MsixPackage.csproj
@@ -83,6 +83,9 @@
+
+
+
@@ -95,11 +98,6 @@
-
-
-
-
-
diff --git a/src/ST.Client.Desktop.Avalonia.App/Program.cs b/src/ST.Client.Desktop.Avalonia.App/Program.cs
index de8c4fc74d0..ebcac1c5a90 100644
--- a/src/ST.Client.Desktop.Avalonia.App/Program.cs
+++ b/src/ST.Client.Desktop.Avalonia.App/Program.cs
@@ -1,17 +1,12 @@
using System.Linq;
using System.Net;
using System.Runtime.Versioning;
-using System.Reflection;
-using System.Threading.Tasks;
using System.Application.Settings;
-using System.Application.Services;
-using System.CommandLine;
-using System.CommandLine.NamingConventionBinder;
+using System.Application.CommandLine;
using NLog;
using Avalonia;
using Avalonia.ReactiveUI;
using Avalonia.Controls;
-using LogLevel = Microsoft.Extensions.Logging.LogLevel;
#if MAC
[assembly: SupportedOSPlatform("macOS")]
@@ -33,9 +28,7 @@ namespace System.Application.UI
{
static partial class Program
{
- const string command_main = "main";
- static IApplication.SingletonInstance? appInstance;
- static readonly ProgramHost host = new();
+ const string command_main = CommandLineHost.command_main;
[STAThread]
static int Main(string[] args)
@@ -43,6 +36,8 @@ static int Main(string[] args)
// fix The request was aborted: Could not create SSL/TLS secure channel
TrySetSecurityProtocol();
+ var host = ProgramHost.Instance;
+
host.IsMainProcess = args.Length == 0;
host.IsCLTProcess = !host.IsMainProcess && args.FirstOrDefault() == "-clt";
@@ -67,7 +62,7 @@ static int Main(string[] args)
{
args_clt = new[] { command_main };
}
- return CommandLineTools.Run(args_clt);
+ return host.Run(args_clt);
}
catch (Exception ex)
{
@@ -76,7 +71,22 @@ static int Main(string[] args)
}
finally
{
- appInstance?.Dispose();
+ try
+ {
+ host.Application?.Dispose();
+ }
+ catch
+ {
+
+ }
+ try
+ {
+ host.AppInstance?.Dispose();
+ }
+ catch
+ {
+
+ }
// Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
LogManager.Shutdown();
ArchiSteamFarm.LogManager.Shutdown();
@@ -149,36 +159,6 @@ static void InitWithMAC(string[] args)
}
#endif
- private sealed class ProgramHost : IApplication.IDesktopProgramHost
- {
- public bool IsMinimize { get; set; }
-
- public bool IsCLTProcess { get; set; }
-
- public bool IsMainProcess { get; set; }
-
- public bool IsTrayProcess { get; set; }
-
- public void ConfigureServices(DILevel level) => Program.ConfigureServices(this, level);
-
- public void InitVisualStudioAppCenterSDK()
- {
-#if WINDOWS || XAMARIN_MAC || __MOBILE__ || __ANDROID__ || __IOS__
-#pragma warning disable IDE0079 // 请删除不必要的忽略
-#pragma warning disable CA1416 // 验证平台兼容性
- VisualStudioAppCenterSDK.Init();
-#pragma warning restore CA1416 // 验证平台兼容性
-#pragma warning restore IDE0079 // 请删除不必要的忽略
-#endif
- }
-
- public void OnStartup() => Program.OnStartup(this);
-
- IApplication IApplication.IProgramHost.Application => App.Instance;
-
- void IApplication.IDesktopProgramHost.OnCreateAppExecuted(Action? handlerViewModelManager, bool isTrace) => Program.OnCreateAppExecuted(this, handlerViewModelManager, isTrace);
- }
-
//static void InitCefNetApp(string[] args) => CefNetApp.Init(AppHelper.LogDirPath, args);
///
@@ -195,7 +175,7 @@ static AppBuilder BuildAvaloniaApp()
OnCreateAppExecuting();
}
#endif
- var builder = AppBuilder.Configure(() => new App(host))
+ var builder = AppBuilder.Configure(() => new App(ProgramHost.Instance))
.UsePlatformDetect()
.LogToTrace()
.UseReactiveUI();
@@ -239,201 +219,5 @@ static void StartAvaloniaApp(string[] args, ShutdownMode shutdownMode = Shutdown
var builder = BuildAvaloniaApp();
builder.StartWithClassicDesktopLifetime(args, shutdownMode);
}
-
- ///
- /// 命令行工具(Command Line Tools/CLT)
- ///
- static class CommandLineTools
- {
- public static int Run(string[] args)
- {
- if (args.Length == 0) args = new[] { "-h" };
-
- // https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2019/march/net-parse-the-command-line-with-system-commandline
- var rootCommand = new RootCommand("命令行工具(Command Line Tools/CLT)");
-
- void MainHandler() => MainHandler_(null);
- void MainHandler_(Action? onInitStartuped)
- {
-#if StartWatchTrace
- StartWatchTrace.Record("ProcessCheck");
-#endif
- ConfigureServices(host, host.IsMainProcess ? DILevel.MainProcess : DILevel.Min);
-#if StartWatchTrace
- StartWatchTrace.Record("Startup.Init");
-#endif
- onInitStartuped?.Invoke();
- if (host.IsMainProcess)
- {
- var isInitAppInstanceReset = false;
- initAppInstance: appInstance = new();
- if (!appInstance.IsFirst)
- {
- //Console.WriteLine("ApplicationInstance.SendMessage(string.Empty);");
- if (IApplication.SingletonInstance.SendMessage(string.Empty))
- {
- return;
- }
- else
- {
- if (!isInitAppInstanceReset &&
- IApplication.SingletonInstance.TryKillCurrentAllProcess())
- {
- isInitAppInstanceReset = true;
- appInstance.Dispose();
- goto initAppInstance;
- }
- else
- {
- return;
- }
- }
- }
- appInstance.MessageReceived += value =>
- {
- if (string.IsNullOrEmpty(value))
- {
- var app = App.Instance;
- if (app != null)
- {
- MainThread2.BeginInvokeOnMainThread(app.RestoreMainWindow);
- }
- }
- };
- }
- //#if StartWatchTrace
- // StartWatchTrace.Record("ApplicationInstance");
- //#endif
- // initCef();
- //#if StartWatchTrace
- // StartWatchTrace.Record("InitCefNetApp");
- //#endif
- if (host.IsMainProcess)
- {
- StartAvaloniaApp(args);
- }
-#if StartWatchTrace
- StartWatchTrace.Record("InitAvaloniaApp");
-#endif
- }
- void MainHandlerByCLT() => MainHandlerByCLT_(null);
- void MainHandlerByCLT_(Action? onInitStartuped)
- {
- host.IsMainProcess = true;
- host.IsCLTProcess = false;
- MainHandler_(onInitStartuped);
- }
-
-#if DEBUG
- // -clt debug -args 730
- var debug = new Command("debug", "调试");
- debug.AddOption(new Option("-args", () => "", "测试参数"));
- debug.Handler = CommandHandler.Create((string args) => // 参数名与类型要与 Option 中一致!
- {
- //Console.WriteLine("-clt debug -args " + args);
- // OutputType WinExe 导致控制台输入不会显示,只能附加一个新的控制台窗口显示内容,不合适
- // 如果能取消 管理员权限要求,改为运行时管理员权限,
- // 则可尝试通过 Windows Terminal 或直接 Host 进行命令行模式
- MainHandlerByCLT();
- });
- rootCommand.AddCommand(debug);
-#endif
-
- var main = new Command(command_main)
- {
- Handler = CommandHandler.Create(MainHandler),
- };
- rootCommand.AddCommand(main);
-
- // -clt devtools
- // -clt devtools -disable_gpu
- // -clt devtools -use_wgl
- var devtools = new Command("devtools");
- devtools.AddOption(new Option("-disable_gpu", () => false, "禁用 GPU 硬件加速"));
- devtools.AddOption(new Option("-use_wgl", () => false, "使用 Native OpenGL(仅 Windows)"));
- devtools.Handler = CommandHandler.Create((bool disable_gpu, bool use_wgl) =>
- {
- IApplication.EnableDevtools = true;
- IApplication.DisableGPU = disable_gpu;
- IApplication.UseWgl = use_wgl;
- MainHandlerByCLT_(onInitStartuped: () =>
- {
- IApplication.LoggerMinLevel = LogLevel.Debug;
- });
- });
- rootCommand.AddCommand(devtools);
-
- // -clt c -silence
- var common = new Command("c", "common");
- common.AddOption(new Option("-silence", "静默启动(不弹窗口)"));
- common.Handler = CommandHandler.Create((bool silence) =>
- {
- host.IsMinimize = silence;
- MainHandlerByCLT();
- });
- rootCommand.AddCommand(common);
-
- // -clt steam -account
- var steamuser = new Command("steam", "Steam 相关操作");
- steamuser.AddOption(new Option("-account", "指定对应 Steam 用户名"));
- steamuser.Handler = CommandHandler.Create((string account) =>
- {
- if (!string.IsNullOrEmpty(account))
- {
- ConfigureServices(host, DILevel.Steam);
-
- var steamService = ISteamService.Instance;
-
- var users = steamService.GetRememberUserList();
-
- var currentuser = users.Where(s => s.AccountName == account).FirstOrDefault();
-
- if (currentuser != null)
- {
- currentuser.MostRecent = true;
- steamService.UpdateLocalUserData(users);
- steamService.SetCurrentUser(account);
- }
-
- steamService.TryKillSteamProcess();
- steamService.StartSteam();
- }
- });
- rootCommand.AddCommand(steamuser);
-
- // -clt app -id 632360
- var unlock_achievement = new Command("app", "打开成就解锁窗口");
- unlock_achievement.AddOption(new Option("-id", "指定一个 Steam 游戏 Id"));
- unlock_achievement.AddOption(new Option("-silence", "挂运行服务,不加载窗口,内存占用更小"));
- unlock_achievement.Handler = CommandHandler.Create(async (int id, bool silence) =>
- {
- try
- {
- if (id <= 0) return;
- if (!silence)
- {
- ConfigureServices(host, DILevel.GUI | DILevel.Steam | DILevel.HttpClientFactory);
- IViewModelManager.Instance.InitUnlockAchievement(id);
- StartAvaloniaApp(args);
- }
- else
- {
- ConfigureServices(host, DILevel.Steam);
- SteamConnectService.Current.Initialize(id);
- TaskCompletionSource tcs = new();
- await tcs.Task;
- }
- }
- catch (Exception ex)
- {
- Log.Error(nameof(unlock_achievement), ex, "Start");
- }
- });
- rootCommand.AddCommand(unlock_achievement);
-
- var r = rootCommand.InvokeAsync(args).Result;
- return r;
- }
- }
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop.Avalonia.App/Program.shared.cs b/src/ST.Client.Desktop.Avalonia.App/Program.shared.cs
new file mode 100644
index 00000000000..b968eca6aae
--- /dev/null
+++ b/src/ST.Client.Desktop.Avalonia.App/Program.shared.cs
@@ -0,0 +1,81 @@
+using System.Application.CommandLine;
+using System.Application.Services;
+#if MAUI
+using Program = System.Application.UI.MauiProgram;
+#endif
+
+namespace System.Application.UI;
+
+static partial class
+#if MAUI
+ MauiProgram
+#else
+ Program
+#endif
+{
+ private sealed partial class ProgramHost
+ {
+ public static ProgramHost Instance { get; } = new();
+
+ private ProgramHost()
+ {
+
+ }
+ }
+
+ partial class ProgramHost : IApplication.IDesktopProgramHost
+ {
+ public bool IsMinimize { get; set; }
+
+ public bool IsCLTProcess { get; set; }
+
+ public bool IsMainProcess { get; set; }
+
+ public bool IsTrayProcess { get; set; }
+
+ public void ConfigureServices(DILevel level) => Program.ConfigureServices(this, level);
+
+ public void InitVisualStudioAppCenterSDK()
+ {
+#if !MAUI && (WINDOWS || XAMARIN_MAC || __MOBILE__ || __ANDROID__ || __IOS__ || MACCATALYST || IOS)
+#pragma warning disable IDE0079 // 请删除不必要的忽略
+#pragma warning disable CA1416 // 验证平台兼容性
+ VisualStudioAppCenterSDK.Init();
+#pragma warning restore CA1416 // 验证平台兼容性
+#pragma warning restore IDE0079 // 请删除不必要的忽略
+#endif
+ }
+
+ public void OnStartup() => Program.OnStartup(this);
+
+ IApplication IApplication.IProgramHost.Application => App.Instance;
+
+ void IApplication.IDesktopProgramHost.OnCreateAppExecuted(Action? handlerViewModelManager, bool isTrace) => Program.OnCreateAppExecuted(this, handlerViewModelManager, isTrace);
+ }
+
+ partial class ProgramHost : CommandLineHost
+ {
+ protected override IApplication.IDesktopProgramHost Host => this;
+
+ protected override void ConfigureServices(IApplication.IStartupArgs args, DILevel level)
+ => Program.ConfigureServices(args, level);
+
+#if StartWatchTrace
+ protected override void StartWatchTraceRecord(string? mark = null, bool dispose = false)
+ => StartWatchTrace.Record(mark, dispose);
+#endif
+
+ protected override void StartApplication(string[] args) =>
+#if MAUI
+ StartMauiApp();
+#else
+ StartAvaloniaApp(args);
+#endif
+
+ public override IApplication? Application => App.Instance;
+
+ protected override void SetIsMainProcess(bool value) => IsMainProcess = value;
+
+ protected override void SetIsCLTProcess(bool value) => IsCLTProcess = value;
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj b/src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj
index 8ae87f12a0f..470ff9a81ea 100644
--- a/src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj
+++ b/src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj
@@ -102,6 +102,7 @@
+
@@ -114,6 +115,8 @@
+
+
diff --git a/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs b/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs
index 57e5dc15a8d..7b10a7efe62 100644
--- a/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs
+++ b/src/ST.Client.Desktop.Avalonia/Application/UI/App.axaml.cs
@@ -75,7 +75,7 @@ public AppTheme Theme
var isLightOrDarkTheme = dps.IsLightOrDarkTheme;
if (isLightOrDarkTheme.HasValue)
{
- switch_value = GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
+ switch_value = IApplication.GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
dps.SetLightOrDarkThemeFollowingSystem(true);
if (switch_value == mTheme) goto setValue;
}
@@ -87,7 +87,7 @@ public AppTheme Theme
var isLightOrDarkTheme = dps.IsLightOrDarkTheme;
if (isLightOrDarkTheme.HasValue)
{
- var mThemeFS = GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
+ var mThemeFS = IApplication.GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
if (mThemeFS == switch_value) goto setValue;
}
}
@@ -98,19 +98,6 @@ public AppTheme Theme
}
}
- static AppTheme GetAppThemeByIsLightOrDarkTheme(bool isLightOrDarkTheme) => isLightOrDarkTheme ? AppTheme.Light : AppTheme.Dark;
-
- AppTheme IApplication.GetActualThemeByFollowingSystem()
- {
- var dps = IPlatformService.Instance;
- var isLightOrDarkTheme = dps.IsLightOrDarkTheme;
- if (isLightOrDarkTheme.HasValue)
- {
- return GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
- }
- return _DefaultActualTheme;
- }
-
public void SetThemeNotChangeValue(AppTheme value)
{
string? the;
diff --git a/src/ST.Client.Desktop.Mac/ST.Client.Mac.csproj b/src/ST.Client.Desktop.Mac/ST.Client.Mac.csproj
index dd71035a950..387c16940ef 100644
--- a/src/ST.Client.Desktop.Mac/ST.Client.Mac.csproj
+++ b/src/ST.Client.Desktop.Mac/ST.Client.Mac.csproj
@@ -36,21 +36,13 @@
-
-
- VisualStudioAppCenterSDK.cs
-
-
-
-
-
-
+
diff --git a/src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj b/src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj
index c9b9d62fe9c..79fc2b9756a 100644
--- a/src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj
+++ b/src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj
@@ -34,18 +34,13 @@
-
-
-
-
-
-
+
+
+
Exe
@@ -11,6 +12,7 @@
true
true
enable
+ MAUI;$(DefineConstants)
Watt Toolkit
@@ -60,13 +62,23 @@
Properties\AssemblyInfo.OS.cs
+
+
+ MauiProgram.shared.cs
+
+
+
+
+
+
+
diff --git a/src/ST.Client.Maui/ST.Client.Maui.csproj b/src/ST.Client.Maui/ST.Client.Maui.csproj
index 67d2c9a95b0..a1d5ba325d1 100644
--- a/src/ST.Client.Maui/ST.Client.Maui.csproj
+++ b/src/ST.Client.Maui/ST.Client.Maui.csproj
@@ -1,37 +1,13 @@
- net6.0;net6.0-android;net6.0-ios;net6.0-maccatalyst
- $(TargetFrameworks);net6.0-windows10.0.19041.0
-
-
+ net6.0
System.Application
System.Application.SteamTools.Client.Maui
true
true
enable
MAUI;$(DefineConstants)
- false
-
-
-
- 14.2
-
-
-
- 14.0
-
-
-
- 21.0
-
-
-
- 10.0.17763.0
-
-
-
- 6.5
@@ -47,6 +23,9 @@
Properties\AssemblyInfo.OS.cs
+
+ Properties\AssemblyInfo.XamlCompilation.cs
+
Converters
@@ -59,6 +38,16 @@
Extensions
+
+ UI\Views\Base\IPage.cs
+
+
+ UI\Views\Base\BaseContentPage.cs
+
+
+
+
+
@@ -67,13 +56,17 @@
-
+
+
+
+
+
-
+
diff --git a/src/ST.Client.Maui/UI/App.xaml b/src/ST.Client.Maui/UI/App.xaml
index ded120cf966..d281bd04958 100644
--- a/src/ST.Client.Maui/UI/App.xaml
+++ b/src/ST.Client.Maui/UI/App.xaml
@@ -2,14 +2,13 @@
-
+
diff --git a/src/ST.Client.Maui/UI/App.xaml.cs b/src/ST.Client.Maui/UI/App.xaml.cs
index 1e725699cb2..f58283527fe 100644
--- a/src/ST.Client.Maui/UI/App.xaml.cs
+++ b/src/ST.Client.Maui/UI/App.xaml.cs
@@ -1,18 +1,135 @@
+using System.Application.Mvvm;
+using System.Application.UI.Styles;
+using System.Reactive.Disposables;
+using System.Windows.Input;
+using EAppTheme = System.Application.Models.AppTheme;
using MauiApplication = Microsoft.Maui.Controls.Application;
-using UI_Styles_Colors_xaml = __XamlGeneratedCode__.__TypeD77312341DE78E28;
-using UI_Styles_Styles_xaml = __XamlGeneratedCode__.__TypeE0CAB8CC0B793AB6;
+using OSAppTheme = Microsoft.Maui.ApplicationModel.AppTheme;
namespace System.Application.UI;
-public partial class App : MauiApplication
+public partial class App : MauiApplication, IDisposableHolder, IApplication
{
- public App()
+ public static App Instance => Current is App app ? app : throw new ArgumentNullException(nameof(app));
+
+ #region IApplication.IDesktopProgramHost
+
+ public IApplication.IDesktopProgramHost ProgramHost { get; }
+
+ IApplication.IProgramHost IApplication.ProgramHost => ProgramHost;
+
+ #endregion
+
+ public App(IApplication.IDesktopProgramHost host)
{
+ ProgramHost = host;
+
InitializeComponent();
+ AppTheme = PlatformAppTheme;
+ RequestedThemeChanged += (_, e) => AppTheme = e.RequestedTheme;
+ MainPage = new AppShell();
+ }
- Resources.MergedDictionaries.Add(new UI_Styles_Colors_xaml());
- Resources.MergedDictionaries.Add(new UI_Styles_Styles_xaml());
+ #region IDisposable members
- MainPage = new AppShell();
+ readonly CompositeDisposable compositeDisposable = new();
+
+ CompositeDisposable IApplication.CompositeDisposable => compositeDisposable;
+
+ ICollection IDisposableHolder.CompositeDisposable => compositeDisposable;
+
+ void IDisposable.Dispose()
+ {
+ compositeDisposable.Dispose();
+ GC.SuppressFinalize(this);
+ }
+
+ #endregion
+
+ #region IApplication
+
+ readonly Dictionary mNotifyIconMenus = new();
+
+ public IReadOnlyDictionary NotifyIconMenus => mNotifyIconMenus;
+
+ #region Theme
+
+ OSAppTheme _AppTheme = OSAppTheme.Light;
+
+ public OSAppTheme AppTheme
+ {
+ get => _AppTheme;
+ set
+ {
+ if (value == OSAppTheme.Unspecified) value = OSAppTheme.Light;
+ if (_AppTheme == value) return;
+
+ _AppTheme = value;
+
+ SetThemeNotChangeValue(value.Convert());
+ }
+ }
+
+ EAppTheme IApplication.Theme
+ {
+ get => AppTheme.Convert();
+ set => AppTheme = value.Convert();
+ }
+
+ const EAppTheme _DefaultActualTheme = EAppTheme.Light;
+
+ EAppTheme IApplication.DefaultActualTheme => _DefaultActualTheme;
+
+ public void SetThemeNotChangeValue(EAppTheme value)
+ {
+ var isDark = value == EAppTheme.Dark;
+ var themeRes = Resources.MergedDictionaries.First();
+ if (isDark)
+ {
+ if (themeRes is ThemeDark) return;
+ }
+ else
+ {
+ if (themeRes is ThemeLight) return;
+ }
+
+ var resources = Resources.MergedDictionaries.Skip(1).ToArray();
+ Resources.MergedDictionaries.Clear();
+
+ themeRes = isDark ? new ThemeDark() : new ThemeLight();
+ Resources.MergedDictionaries.Add(themeRes);
+
+ Array.ForEach(resources, Resources.MergedDictionaries.Add);
}
+
+ #endregion
+
+ object IApplication.CurrentPlatformUIHost
+ {
+ get
+ {
+ foreach (var window in Windows)
+ {
+ if (window.IsActivated()) return window;
+ }
+ throw new ArgumentNullException(nameof(IApplication.CurrentPlatformUIHost));
+ }
+ }
+
+ bool IApplication.HasActiveWindow()
+ {
+ foreach (var window in Windows)
+ {
+ if (window.IsActivated()) return true;
+ }
+ return false;
+ }
+
+ #endregion;
+
+ #region Compat
+
+ public void Shutdown() => Quit();
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/AppShell.xaml b/src/ST.Client.Maui/UI/AppShell.xaml
index cbacfb69aba..05eb352bb68 100644
--- a/src/ST.Client.Maui/UI/AppShell.xaml
+++ b/src/ST.Client.Maui/UI/AppShell.xaml
@@ -3,12 +3,72 @@
x:Class="System.Application.UI.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
- xmlns:local="clr-namespace:System.Application.UI"
+ xmlns:local="clr-namespace:System.Application.UI.Views"
+ xmlns:resx="clr-namespace:System.Application.UI.Resx;assembly=System.Application.SteamTools.Client"
+ xmlns:vm="clr-namespace:System.Application.UI.ViewModels;assembly=System.Application.SteamTools.Client"
+ Title="{Binding Title}"
+ x:DataType="vm:MainWindowViewModel"
Shell.FlyoutBehavior="Disabled">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
diff --git a/src/ST.Client.Maui/UI/AppShell.xaml.cs b/src/ST.Client.Maui/UI/AppShell.xaml.cs
index ad04bb0ca2f..d872d39757d 100644
--- a/src/ST.Client.Maui/UI/AppShell.xaml.cs
+++ b/src/ST.Client.Maui/UI/AppShell.xaml.cs
@@ -6,4 +6,9 @@ public AppShell()
{
InitializeComponent();
}
+
+ void OnFlyoutHeaderTapped(object? sender, EventArgs e)
+ {
+
+ }
}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/Colors.xaml b/src/ST.Client.Maui/UI/Styles/Colors.xaml
deleted file mode 100644
index 245758ba179..00000000000
--- a/src/ST.Client.Maui/UI/Styles/Colors.xaml
+++ /dev/null
@@ -1,44 +0,0 @@
-
-
-
-
- #512BD4
- #DFD8F7
- #2B0B98
- White
- Black
- #E1E1E1
- #C8C8C8
- #ACACAC
- #919191
- #6E6E6E
- #404040
- #212121
- #141414
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- #F7B548
- #FFD590
- #FFE5B9
- #28C2D1
- #7BDDEF
- #C3F2F4
- #3E8EED
- #72ACF1
- #A7CBF6
-
-
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/Controls.xaml b/src/ST.Client.Maui/UI/Styles/Controls.xaml
new file mode 100644
index 00000000000..e7a36792e0d
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/Controls.xaml
@@ -0,0 +1,383 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/Controls.xaml.cs b/src/ST.Client.Maui/UI/Styles/Controls.xaml.cs
new file mode 100644
index 00000000000..1701c30c889
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/Controls.xaml.cs
@@ -0,0 +1,9 @@
+namespace System.Application.UI.Styles;
+
+public partial class Controls : ResourceDictionary
+{
+ public Controls()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/DrawingSvg.xaml b/src/ST.Client.Maui/UI/Styles/DrawingSvg.xaml
new file mode 100644
index 00000000000..1a46dd20fbd
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/DrawingSvg.xaml
@@ -0,0 +1,20 @@
+
+
+
+ M909.937778 664.803556c-18.432-110.876444-95.829333-183.523556-95.829333-183.523556 11.064889-100.664889-29.496889-118.528-29.496889-118.528C776.106667 51.313778 517.432889 56.775111 512 56.917333c-5.432889-0.142222-264.135111-5.603556-272.611556 305.863111 0 0-40.561778 17.863111-29.496889 118.528 0 0-77.397333 72.647111-95.829333 183.523556 0 0-9.841778 187.335111 88.462222 22.954667 0 0 22.129778 62.435556 62.663111 118.528 0 0-72.504889 25.486222-66.332444 91.761778 0 0-2.474667 73.898667 154.823111 68.835556 0 0 110.563556-8.903111 143.758222-57.344l29.240889 0c33.166222 48.440889 143.758222 57.344 143.758222 57.344 157.240889 5.091556 154.794667-68.835556 154.794667-68.835556 6.115556-66.247111-66.332444-91.761778-66.332444-91.761778 40.533333-56.092444 62.663111-118.528 62.663111-118.528C919.751111 852.167111 909.937778 664.803556 909.937778 664.803556L909.937778 664.803556zM909.937778 664.803556
+
+
+ M905.714286 694.285714q-22.285714 71.428571-70.285714 142.857143-73.714286 112-146.857143 112-28 0-80-18.285714-49.142857-18.285714-86.285714-18.285714-34.857143 0-81.142857 18.857143-46.285714 19.428571-75.428571 19.428571-86.857143 0-172-148-84-149.142857-84-287.428571 0-130.285714 64.571429-213.714286 64-82.285714 162.285714-82.285714 41.142857 0 101.142857 17.142857 59.428571 17.142857 78.857143 17.142857 25.714286 0 81.714286-19.428571 58.285714-19.428571 98.857143-19.428571 68 0 121.714286 37.142857 29.714286 20.571429 59.428571 57.142857-45.142857 38.285714-65.142857 67.428571-37.142857 53.714286-37.142857 118.285714 0 70.857143 39.428571 127.428571t90.285714 72zm-214.857143-670.285714q0 34.857143-16.571429 77.714286-17.142857 42.857143-53.142857 78.857143-30.857143 30.857143-61.714286 41.142857-21.142857 6.285714-59.428571 9.714286 1.714286-85.142857 44.571429-146.857143 42.285714-61.142857 142.857143-84.571429 0.571429 1.714286 1.428571 6.285714t1.428571 6.285714q0 2.285714 2.857143 5.714286t2.857143 5.714286z
+
+
+ M369.9 318.2c44.3 54.3 64.7 98.8 54.4 118.7-7.9 15.1-56.7 44.6-92.6 55.9-29.6 9.3-68.4 13.3-100.4 10.2-38.2-3.7-76.9-17.4-110.1-39C93.3 445.8 87 438.3 87 423.4c0-29.9 32.9-82.3 89.2-142.1 32-33.9 76.5-73.7 81.4-72.6 9.4 2.1 84.3 75.1 112.3 109.5zM188.6 143.8c-29.7-26.9-58.1-53.9-86.4-63.4-15.2-5.1-16.3-4.8-28.7 8.1-29.2 30.4-53.5 79.7-60.3 122.4-5.4 34.2-6.1 43.8-4.2 60.5 5.6 50.5 17.3 85.4 40.5 120.9 9.5 14.6 12.1 17.3 9.3 9.9-4.2-11-.3-37.5 9.5-64 14.3-39 53.9-112.9 120.3-194.4zm311.6 63.5C483.3 127.3 432.7 77 425.6 77c-7.3 0-24.2 6.5-36 13.9-23.3 14.5-41 31.4-64.3 52.8C367.7 197 427.5 283.1 448.2 346c6.8 20.7 9.7 41.1 7.4 52.3-1.7 8.5-1.7 8.5 1.4 4.6 6.1-7.7 19.9-31.3 25.4-43.5 7.4-16.2 15-40.2 18.6-58.7 4.3-22.5 3.9-70.8-.8-93.4zM141.3 43C189 40.5 251 77.5 255.6 78.4c.7.1 10.4-4.2 21.6-9.7 63.9-31.1 94-25.8 107.4-25.2-63.9-39.3-152.7-50-233.9-11.7-23.4 11.1-24 11.9-9.4 11.2z
+
+
+ M496 256c0 137-111.2 248-248.4 248-113.8 0-209.6-76.3-239-180.4l95.2 39.3c6.4 32.1 34.9 56.4 68.9 56.4 39.2 0 71.9-32.4 70.2-73.5l84.5-60.2c52.1 1.3 95.8-40.9 95.8-93.5 0-51.6-42-93.5-93.7-93.5s-93.7 42-93.7 93.5v1.2L176.6 279c-15.5-.9-30.7 3.4-43.5 12.1L0 236.1C10.2 108.4 117.1 8 247.6 8 384.8 8 496 119 496 256zM155.7 384.3l-30.5-12.6a52.79 52.79 0 0 0 27.2 25.8c26.9 11.2 57.8-1.6 69-28.4 5.4-13 5.5-27.3.1-40.3-5.4-13-15.5-23.2-28.5-28.6-12.9-5.4-26.7-5.2-38.9-.6l31.5 13c19.8 8.2 29.2 30.9 20.9 50.7-8.3 19.9-31 29.2-50.8 21zm173.8-129.9c-34.4 0-62.4-28-62.4-62.3s28-62.3 62.4-62.3 62.4 28 62.4 62.3-27.9 62.3-62.4 62.3zm.1-15.6c25.9 0 46.9-21 46.9-46.8 0-25.9-21-46.8-46.9-46.8s-46.9 21-46.9 46.8c.1 25.8 21.1 46.8 46.9 46.8z
+
+
+ M15.75 2C16.9926 2 18 3.00736 18 4.25V19.75C18 20.9926 16.9926 22 15.75 22H8.25C7.00736 22 6 20.9926 6 19.75V4.25C6 3.00736 7.00736 2 8.25 2H15.75ZM13.25 18H10.75C10.3358 18 10 18.3358 10 18.75C10 19.1642 10.3358 19.5 10.75 19.5H13.25C13.6642 19.5 14 19.1642 14 18.75C14 18.3358 13.6642 18 13.25 18Z
+
+
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/DrawingSvg.xaml.cs b/src/ST.Client.Maui/UI/Styles/DrawingSvg.xaml.cs
new file mode 100644
index 00000000000..88e600e39e1
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/DrawingSvg.xaml.cs
@@ -0,0 +1,9 @@
+namespace System.Application.UI.Styles;
+
+public partial class DrawingSvg : ResourceDictionary
+{
+ public DrawingSvg()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/Styles.xaml b/src/ST.Client.Maui/UI/Styles/Styles.xaml
deleted file mode 100644
index 3b0fdc41232..00000000000
--- a/src/ST.Client.Maui/UI/Styles/Styles.xaml
+++ /dev/null
@@ -1,384 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ST.Client.Maui/UI/Styles/ThemeDark.xaml b/src/ST.Client.Maui/UI/Styles/ThemeDark.xaml
new file mode 100644
index 00000000000..1ae2282f900
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/ThemeDark.xaml
@@ -0,0 +1,55 @@
+
+
+ #2196F3
+
+ #141414
+
+ #f2f2f7
+
+ #979797
+
+ #0089ff
+ #121212
+ White
+
+
+
+
+ #DFD8F7
+ #2B0B98
+ White
+ Black
+ #E1E1E1
+ #C8C8C8
+ #ACACAC
+ #919191
+ #6E6E6E
+ #404040
+ #212121
+ #141414
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #F7B548
+ #FFD590
+ #FFE5B9
+ #28C2D1
+ #7BDDEF
+ #C3F2F4
+ #3E8EED
+ #72ACF1
+ #A7CBF6
+
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/ThemeDark.xaml.cs b/src/ST.Client.Maui/UI/Styles/ThemeDark.xaml.cs
new file mode 100644
index 00000000000..6ed7f7ee6c2
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/ThemeDark.xaml.cs
@@ -0,0 +1,9 @@
+namespace System.Application.UI.Styles;
+
+public partial class ThemeDark : ResourceDictionary
+{
+ public ThemeDark()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/ThemeLight.xaml b/src/ST.Client.Maui/UI/Styles/ThemeLight.xaml
new file mode 100644
index 00000000000..7aa6703f5a3
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/ThemeLight.xaml
@@ -0,0 +1,55 @@
+
+
+ #2196F3
+
+ #F9F9F9
+
+ #333333
+
+ #666666
+
+ #007ffc
+ White
+ #222222
+
+
+
+
+ #DFD8F7
+ #2B0B98
+ White
+ Black
+ #E1E1E1
+ #C8C8C8
+ #ACACAC
+ #919191
+ #6E6E6E
+ #404040
+ #212121
+ #141414
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #F7B548
+ #FFD590
+ #FFE5B9
+ #28C2D1
+ #7BDDEF
+ #C3F2F4
+ #3E8EED
+ #72ACF1
+ #A7CBF6
+
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Styles/ThemeLight.xaml.cs b/src/ST.Client.Maui/UI/Styles/ThemeLight.xaml.cs
new file mode 100644
index 00000000000..361552b9a1e
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Styles/ThemeLight.xaml.cs
@@ -0,0 +1,9 @@
+namespace System.Application.UI.Styles;
+
+public partial class ThemeLight : ResourceDictionary
+{
+ public ThemeLight()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Views/MainPage.xaml b/src/ST.Client.Maui/UI/Views/MainPage.xaml
deleted file mode 100644
index 5190c12a618..00000000000
--- a/src/ST.Client.Maui/UI/Views/MainPage.xaml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/ST.Client.Maui/UI/Views/MainPage.xaml.cs b/src/ST.Client.Maui/UI/Views/MainPage.xaml.cs
deleted file mode 100644
index fb4ed2731a2..00000000000
--- a/src/ST.Client.Maui/UI/Views/MainPage.xaml.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-namespace System.Application.UI
-{
- public partial class MainPage : ContentPage
- {
- int count = 0;
-
- public MainPage()
- {
- InitializeComponent();
- }
-
- private void OnCounterClicked(object sender, EventArgs e)
- {
- count++;
-
- if (count == 1)
- CounterBtn.Text = $"Clicked {count} time";
- else
- CounterBtn.Text = $"Clicked {count} times";
-
- SemanticScreenReader.Announce(CounterBtn.Text);
- }
- }
-}
\ No newline at end of file
diff --git a/src/ST.Client.Maui/UI/Views/UnderConstructionPage.xaml b/src/ST.Client.Maui/UI/Views/UnderConstructionPage.xaml
new file mode 100644
index 00000000000..9d26c34c62a
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Views/UnderConstructionPage.xaml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
diff --git a/src/ST.Client.Maui/UI/Views/UnderConstructionPage.xaml.cs b/src/ST.Client.Maui/UI/Views/UnderConstructionPage.xaml.cs
new file mode 100644
index 00000000000..cbc62cff3a6
--- /dev/null
+++ b/src/ST.Client.Maui/UI/Views/UnderConstructionPage.xaml.cs
@@ -0,0 +1,9 @@
+namespace System.Application.UI.Views;
+
+public partial class UnderConstructionPage : ContentPage
+{
+ public UnderConstructionPage()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.ResSecrets/Properties/InternalsVisibleTo.cs b/src/ST.Client.ResSecrets/Properties/InternalsVisibleTo.cs
index 4978c0e88d4..bb02f1fd6be 100644
--- a/src/ST.Client.ResSecrets/Properties/InternalsVisibleTo.cs
+++ b/src/ST.Client.ResSecrets/Properties/InternalsVisibleTo.cs
@@ -12,4 +12,6 @@
[assembly: InternalsVisibleTo("System.Application.SteamTools.Client.Windows" + PublicKey)]
[assembly: InternalsVisibleTo("System.Application.SteamTools.Client.Linux" + PublicKey)]
[assembly: InternalsVisibleTo("Assembly-CSharp" + PublicKey)]
-[assembly: InternalsVisibleTo("Steam++" + PublicKey)]
\ No newline at end of file
+[assembly: InternalsVisibleTo("System.Application.SteamTools.Client.AppCenter" + PublicKey)]
+[assembly: InternalsVisibleTo("Steam++" + PublicKey)]
+[assembly: InternalsVisibleTo("Watt Toolkit" + PublicKey)]
\ No newline at end of file
diff --git a/src/ST.Client.XamarinForms/Extensions/AppThemeEnumExtensions.cs b/src/ST.Client.XamarinForms/Extensions/AppThemeEnumExtensions.cs
index f0424285d08..ecce4454433 100644
--- a/src/ST.Client.XamarinForms/Extensions/AppThemeEnumExtensions.cs
+++ b/src/ST.Client.XamarinForms/Extensions/AppThemeEnumExtensions.cs
@@ -16,4 +16,11 @@ public static class AppThemeEnumExtensions
AppTheme.Light => OSAppTheme.Light,
_ => OSAppTheme.Unspecified,
};
+
+ public static AppTheme Convert(this OSAppTheme theme) => theme switch
+ {
+ OSAppTheme.Dark => AppTheme.Dark,
+ OSAppTheme.Light => AppTheme.Light,
+ _ => AppTheme.FollowingSystem,
+ };
}
diff --git a/src/ST.Client.XamarinForms/Properties/AssemblyInfo.XamlCompilation.cs b/src/ST.Client.XamarinForms/Properties/AssemblyInfo.XamlCompilation.cs
index c859952e34b..03410a5681d 100644
--- a/src/ST.Client.XamarinForms/Properties/AssemblyInfo.XamlCompilation.cs
+++ b/src/ST.Client.XamarinForms/Properties/AssemblyInfo.XamlCompilation.cs
@@ -1,3 +1,5 @@
+#if !MAUI
using Xamarin.Forms.Xaml;
+#endif
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
\ No newline at end of file
diff --git a/src/ST.Client.XamarinForms/UI/Views/BaseContentPage.cs b/src/ST.Client.XamarinForms/UI/Views/Base/BaseContentPage.cs
similarity index 94%
rename from src/ST.Client.XamarinForms/UI/Views/BaseContentPage.cs
rename to src/ST.Client.XamarinForms/UI/Views/Base/BaseContentPage.cs
index 0ab7851708f..cb99a6fdf36 100644
--- a/src/ST.Client.XamarinForms/UI/Views/BaseContentPage.cs
+++ b/src/ST.Client.XamarinForms/UI/Views/Base/BaseContentPage.cs
@@ -1,11 +1,15 @@
-using ReactiveUI.XamForms;
using System;
using System.Application.Services;
using System.Application.UI.ViewModels;
using System.Collections.Generic;
using System.Linq;
using System.Text;
+#if !MAUI
using Xamarin.Forms;
+using ReactiveUI.XamForms;
+#else
+using ReactiveUI.Maui;
+#endif
namespace System.Application.UI.Views
{
diff --git a/src/ST.Client.XamarinForms/UI/Views/Base/IPage.cs b/src/ST.Client.XamarinForms/UI/Views/Base/IPage.cs
index e80d8925999..ae45ab2817a 100644
--- a/src/ST.Client.XamarinForms/UI/Views/Base/IPage.cs
+++ b/src/ST.Client.XamarinForms/UI/Views/Base/IPage.cs
@@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
+#if !MAUI
using Xamarin.Forms;
+#endif
// ReSharper disable once CheckNamespace
namespace System.Application.UI.Views
diff --git a/src/ST.Client.iOS/ST.Client.iOS.csproj b/src/ST.Client.iOS/ST.Client.iOS.csproj
index f5283522b0b..f62c5295732 100644
--- a/src/ST.Client.iOS/ST.Client.iOS.csproj
+++ b/src/ST.Client.iOS/ST.Client.iOS.csproj
@@ -18,9 +18,6 @@
Properties\InternalsVisibleTo.cs
-
- VisualStudioAppCenterSDK.cs
-
Services\Implementation
@@ -32,15 +29,13 @@
+
-
-
-
diff --git a/src/ST.Client/UI/IApplication.Log.cs b/src/ST.Client/UI/IApplication.Log.cs
index 183a7b4e288..5bdca9554a4 100644
--- a/src/ST.Client/UI/IApplication.Log.cs
+++ b/src/ST.Client/UI/IApplication.Log.cs
@@ -164,7 +164,7 @@ public static void InitLogDir(string? alias = null)
{
if (!string.IsNullOrEmpty(LogDirPath)) return;
- var devicePlatform = DeviceInfo2.Platform();
+ //var devicePlatform = DeviceInfo2.Platform();
//LogUnderCache = devicePlatform switch
//{
// Platform.Windows => DesktopBridge.IsRunningAsUwp,
diff --git a/src/ST.Client/UI/IApplication.cs b/src/ST.Client/UI/IApplication.cs
index 5635c78a0ed..825d7ceaefe 100644
--- a/src/ST.Client/UI/IApplication.cs
+++ b/src/ST.Client/UI/IApplication.cs
@@ -41,11 +41,22 @@ public partial interface IApplication
///
protected AppTheme DefaultActualTheme { get; }
+ static AppTheme GetAppThemeByIsLightOrDarkTheme(bool isLightOrDarkTheme) => isLightOrDarkTheme ? AppTheme.Light : AppTheme.Dark;
+
///
/// 获取当前应用主题跟随系统时的实际主题
///
///
- protected AppTheme GetActualThemeByFollowingSystem();
+ protected AppTheme GetActualThemeByFollowingSystem()
+ {
+ var dps = IPlatformService.Instance;
+ var isLightOrDarkTheme = dps.IsLightOrDarkTheme;
+ if (isLightOrDarkTheme.HasValue)
+ {
+ return GetAppThemeByIsLightOrDarkTheme(isLightOrDarkTheme.Value);
+ }
+ return DefaultActualTheme;
+ }
///
/// 获取当前平台 UI Host
diff --git a/src/ST.Client/UI/Resx/R.cs b/src/ST.Client/UI/Resx/R.cs
index 1b3f776f885..ff946a91c88 100644
--- a/src/ST.Client/UI/Resx/R.cs
+++ b/src/ST.Client/UI/Resx/R.cs
@@ -22,7 +22,7 @@ public R()
public static readonly IReadOnlyDictionary Languages;
public static readonly IReadOnlyDictionary SteamLanguages;
- static readonly Lazy>> mFonts = new(() => IFontManager.Instance.GetFonts());
+ static readonly Lazy>> mFonts = new(IFontManager.Instance.GetFonts);
public static IReadOnlyCollection> Fonts => mFonts.Value;
diff --git a/src/ST/ProxyType.cs b/src/ST/ProxyType.cs
index 3ecc7d71a0c..11d41b46cc9 100644
--- a/src/ST/ProxyType.cs
+++ b/src/ST/ProxyType.cs
@@ -3,7 +3,7 @@ namespace System.Application
///
/// 代理类型
///
- public enum ProxyType:byte
+ public enum ProxyType : byte
{
///
/// 本地代理
diff --git a/src/Startup.cs b/src/Startup.cs
index e494d9106b4..765e95940c5 100644
--- a/src/Startup.cs
+++ b/src/Startup.cs
@@ -2,13 +2,15 @@
#pragma warning disable SA1211 // Using alias directives should be ordered alphabetically by alias name
#pragma warning disable SA1216 // Using static directives should be placed at the correct location
#pragma warning disable SA1209 // Using alias directives should be placed after other using directives
+#if !MAUI
#if !__MOBILE__ && !CONSOLEAPP
using Avalonia;
using Avalonia.Controls;
using Avalonia.Platform;
-#elif !MAUI
+#else
using Xamarin.Essentials;
#endif
+#endif
#if UI_DEMO
using Moq;
#endif
@@ -44,7 +46,9 @@
#elif !__MOBILE__
using ReactiveUI;
using System.Reactive;
+#if !MAUI
using AvaloniaApplication = Avalonia.Application;
+#endif
using PlatformApplication = System.Application.UI.App;
#endif
#if StartWatchTrace
@@ -69,7 +73,9 @@
namespace System.Application.UI
{
partial class
-#if __ANDROID__
+#if MAUI
+ MauiProgram
+#elif __ANDROID__
MainApplication
#elif __IOS__
Program
@@ -223,6 +229,12 @@ static void ConfigureRequiredServices(IServiceCollection services, IApplication.
// 平台服务 此项放在其他通用业务实现服务之前
services.AddPlatformService(options);
#endif
+#if WINDOWS
+#if !MAUI
+ services.AddMSAppCenterApplicationSettings();
+#endif
+ services.AddJumpListService();
+#endif
// 添加日志实现
services.AddGeneralLogging();
@@ -265,7 +277,7 @@ static void ConfigureDemandServices(IServiceCollection services, IApplication.IS
if (options.HasGUI)
{
services.AddPinyin();
-#if __MOBILE__
+#if __MOBILE__ || MAUI
services.TryAddFontManager();
#else
services.TryAddAvaloniaFontManager(useGdiPlusFirst: true);
@@ -285,6 +297,8 @@ static void ConfigureDemandServices(IServiceCollection services, IApplication.IS
services.AddTelephonyService();
//services.AddMSALPublicClientApp(AppSettings.MASLClientId);
+#elif MAUI
+ services.AddSingleton(_ => PlatformApplication.Instance);
#else
services.AddSingleton(_ => PlatformApplication.Instance);
services.TryAddSingleton(_ => PlatformApplication.Instance);
@@ -313,7 +327,11 @@ static void ConfigureDemandServices(IServiceCollection services, IApplication.IS
* - 按钮文本(ButtonText)缺少本地化翻译(Translate)
* - 某些图标图片与枚举值不太匹配,例如 Information
*/
+#if !MAUI
services.TryAddWindowManager();
+#else
+ Console.WriteLine("TODO: TryAddWindowManager");
+#endif
#if WINDOWS
// 可选项,在 Win 平台使用 WPF 实现的 MessageBox
@@ -473,7 +491,11 @@ void AddNotificationService()
if (options.HasMainProcessRequired)
{
// 应用程序更新服务
+#if !MAUI
services.AddApplicationUpdateService();
+#else
+ Console.WriteLine("TODO: AddApplicationUpdateService");
+#endif
#if StartWatchTrace
StartWatchTrace.Record("DI.ConfigureDemandServices.AppUpdateService");
#endif
@@ -531,7 +553,7 @@ public MockServiceProvider(Action configureServices)
static void OnCreateAppExecuting(bool isTrace = false)
{
bool isDesignMode =
-#if !__MOBILE__
+#if !(__MOBILE__ || MAUI)
Design.IsDesignMode;
#else
false;
@@ -654,7 +676,7 @@ static async void ActiveUserPost(IApplication.IStartupArgs args, ActiveUserType
await userService.SaveUserAsync(rspRUserInfo.Content);
}
}
-#if !__MOBILE__
+#if !__MOBILE__ && !MAUI
var screens = PlatformApplication.Instance.MainWindow!.Screens;
#else
var mainDisplayInfo = DeviceDisplay.MainDisplayInfo;
@@ -664,7 +686,7 @@ static async void ActiveUserPost(IApplication.IStartupArgs args, ActiveUserType
var req = new ActiveUserRecordDTO
{
Type = type,
-#if __MOBILE__
+#if __MOBILE__ || MAUI
ScreenCount = 1,
PrimaryScreenPixelDensity = mainDisplayInfo.Density,
PrimaryScreenWidth = mainDisplayInfoW,
@@ -813,7 +835,7 @@ public static void Handler(Exception ex, string name, bool? isTerminating = null
try
{
- if (AvaloniaApplication.Current is IApplication app)
+ if (PlatformApplication.Instance is IApplication app)
{
app.CompositeDisposable.Dispose();
}