diff --git a/SteamToolsV2+.sln b/SteamToolsV2+.sln index db76bc043..f37c63e32 100644 --- a/SteamToolsV2+.sln +++ b/SteamToolsV2+.sln @@ -35,10 +35,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.AreaLib", "src\Commo EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.ClientLib", "src\Common.ClientLib\Common.ClientLib.csproj", "{371B4824-FA2D-415A-AD90-722B341F23F3}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.ClientLib.Droid", "src\Common.ClientLib.Droid\Common.ClientLib.Droid.csproj", "{938BEBE3-67A9-4D90-A72C-C378F90FF164}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.ClientLib.iOS", "src\Common.ClientLib.iOS\Common.ClientLib.iOS.csproj", "{FD6FF872-77D6-4E5D-8E75-0271352D3054}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Repositories.sqlite-net-pcl", "src\Repositories.sqlite-net-pcl\Repositories.sqlite-net-pcl.csproj", "{A203BA92-B3B6-411C-91E1-8F3FF7BF2163}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Authenticator", "references\WinAuth\Authenticator\Authenticator.csproj", "{FEB554A3-1CAD-4E77-A300-CD8CA520EED6}" @@ -55,33 +51,19 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Titanium.Web.Proxy", "refer EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UnitTest", "tests\Common.UnitTest\Common.UnitTest.csproj", "{3D74BDE9-847A-46F9-B6FA-6F445F217843}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.UnitTest.Droid", "tests\Common.UnitTest.Droid\Common.UnitTest.Droid.csproj", "{DAEE295C-1C4B-4D64-B0FD-46FE6C139841}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.UnitTest.Droid.App", "tests\Common.UnitTest.Droid.App\Common.UnitTest.Droid.App.csproj", "{AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.UnitTest", "tests\ST.Client.UnitTest\ST.Client.UnitTest.csproj", "{EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.UnitTest", "tests\ST.Client.Desktop.UnitTest\ST.Client.Desktop.UnitTest.csproj", "{931C8F51-0350-4CFC-92B4-E2D89CC41C9A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST", "src\ST\ST.csproj", "{BC5F6313-435E-4748-99D5-BB6F3B109F91}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client", "src\ST.Client\ST.Client.csproj", "{6C907586-BC27-4BED-AD6D-52F0755172CB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop", "src\ST.Client.Desktop\ST.Client.Desktop.csproj", "{95DF567C-C766-4382-B8A7-C0D99EDC73B0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Avalonia", "src\ST.Client.Desktop.Avalonia\ST.Client.Avalonia.csproj", "{1D95FBB4-A43D-4805-B307-91C92D3E91C1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.Avalonia", "src\ST.Client.Desktop.Avalonia\ST.Client.Desktop.Avalonia.csproj", "{1D95FBB4-A43D-4805-B307-91C92D3E91C1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Linux", "src\ST.Client.Desktop.Linux\ST.Client.Linux.csproj", "{E1005888-262E-4477-858B-497FF2DBFCFF}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.Linux", "src\ST.Client.Desktop.Linux\ST.Client.Desktop.Linux.csproj", "{E1005888-262E-4477-858B-497FF2DBFCFF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Mac", "src\ST.Client.Desktop.Mac\ST.Client.Mac.csproj", "{0AE2FEC7-BE21-48DA-8D74-B932DEE1B4DE}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.Mac", "src\ST.Client.Desktop.Mac\ST.Client.Desktop.Mac.csproj", "{0AE2FEC7-BE21-48DA-8D74-B932DEE1B4DE}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.Windows", "src\ST.Client.Desktop.Windows\ST.Client.Desktop.Windows.csproj", "{5597B34A-4337-4A17-B0B0-BB1438D435B0}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Mobile", "src\ST.Client.Mobile\ST.Client.Mobile.csproj", "{E5E808A7-32B9-4699-874D-B31AFF1246F6}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Mobile.Droid", "src\ST.Client.Mobile.Droid\ST.Client.Mobile.Droid.csproj", "{FB829D3F-CA33-4413-A84C-C0C80E28AA2D}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Mobile.iOS", "src\ST.Client.Mobile.iOS\ST.Client.Mobile.iOS.csproj", "{3BFEFB3F-3D91-4271-BEA7-780879D464C1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Windows", "src\ST.Client.Desktop.Windows\ST.Client.Windows.csproj", "{5597B34A-4337-4A17-B0B0-BB1438D435B0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Services.CloudService.Models", "src\ST.Services.CloudService.Models\ST.Services.CloudService.Models.csproj", "{F08C0D0F-2399-439B-9C62-A249141A7F7E}" EndProject @@ -101,15 +83,13 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Tools.Packager.Installer EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Tools.Translate", "src\ST.Tools.Translate\ST.Tools.Translate.csproj", "{7A27EDB5-2E6A-4E01-AA55-62C8B3117226}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.Avalonia.App", "src\ST.Client.Desktop.Avalonia.App\ST.Client.Desktop.Avalonia.App.csproj", "{1CB40DC8-8FBC-4278-A19A-D872CFA353C0}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ST.Client.Mobile.Droid.App", "src\ST.Client.Mobile.Droid.App\ST.Client.Mobile.Droid.App.csproj", "{B355E372-27D2-4217-A129-D3355573681F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Avalonia.App", "src\ST.Client.Desktop.Avalonia.App\ST.Client.Avalonia.App.csproj", "{1CB40DC8-8FBC-4278-A19A-D872CFA353C0}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Tools.AndroidResourceLink", "src\ST.Tools.AndroidResourceLink\ST.Tools.AndroidResourceLink.csproj", "{9A8D2254-9B2B-4B92-8498-43A73BB9A410}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiSteamFarm.Library", "references\ArchiSteamFarm\ArchiSteamFarm.Library\ArchiSteamFarm.Library.csproj", "{F4D8CD7B-6DF4-445C-AFA9-44466A552922}" EndProject -Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "ST.Client.Desktop.Avalonia.App.Bridge.Package", "src\ST.Client.Desktop.Avalonia.App.Bridge.Package\ST.Client.Desktop.Avalonia.App.Bridge.Package.wapproj", "{1F659618-71E2-4AAF-9D86-62700FD4CF02}" +Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "ST.Client.Avalonia.App.Bridge.Package", "src\ST.Client.Desktop.Avalonia.App.Bridge.Package\ST.Client.Avalonia.App.Bridge.Package.wapproj", "{1F659618-71E2-4AAF-9D86-62700FD4CF02}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SQLite-net-std", "references\sqlite-net\nuget\SQLite-net-std\SQLite-net-std.csproj", "{B1F221F6-E19B-45D8-959D-A9CDA471C2D4}" EndProject @@ -117,12 +97,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Steam++", "src\ST.Client.De EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Tools.DesktopBridgeLink", "src\ST.Tools.DesktopBridgeLink\ST.Tools.DesktopBridgeLink.csproj", "{137690DF-A3CB-4817-ACB8-9EAF3A52B5B5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Server.Resources", "src\ST.Server.Resources\ST.Server.Resources.csproj", "{9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FluentAvalonia", "references\FluentAvalonia\FluentAvalonia\FluentAvalonia.csproj", "{42154590-445B-41CF-AAEB-AACD1B65FA2C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ST.Client.Desktop.Linux.App.TrayIcon", "src\ST.Client.Desktop.Linux.App.TrayIcon\ST.Client.Desktop.Linux.App.TrayIcon.csproj", "{D9AF058F-D954-439B-BD72-51C47F65E7BE}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.PinyinLib", "src\Common.PinyinLib\Common.PinyinLib.csproj", "{84AA1922-CB8D-4C6F-9117-10C611FD0FB1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.PinyinLib.CFStringTransform", "src\Common.PinyinLib.CFStringTransform\Common.PinyinLib.CFStringTransform.csproj", "{5C97EE6C-3E87-4FF8-A3F9-19A4459F5427}" @@ -131,6 +107,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.PinyinLib.ChnCharInf EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.PinyinLib.TinyPinyin", "src\Common.PinyinLib.TinyPinyin\Common.PinyinLib.TinyPinyin.csproj", "{D30203AC-97AB-4A51-BFA5-826251C9A28E}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Platforms", "Platforms", "{E50441E8-75F3-406E-9921-30BFC211B5CE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UI Framework", "UI Framework", "{8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web API", "Web API", "{4E7DF449-F136-4B90-82CE-D1418CD5123C}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -233,62 +215,6 @@ Global {371B4824-FA2D-415A-AD90-722B341F23F3}.Release|x64.Build.0 = Release|Any CPU {371B4824-FA2D-415A-AD90-722B341F23F3}.Release|x86.ActiveCfg = Release|Any CPU {371B4824-FA2D-415A-AD90-722B341F23F3}.Release|x86.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|Any CPU.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|ARM.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|ARM.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|ARM64.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|iPhone.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|x64.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|x64.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|x86.ActiveCfg = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Debug|x86.Build.0 = Debug|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|Any CPU.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|Any CPU.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|ARM.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|ARM.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|ARM64.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|ARM64.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|iPhone.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|iPhone.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|x64.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|x64.Build.0 = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|x86.ActiveCfg = Release|Any CPU - {938BEBE3-67A9-4D90-A72C-C378F90FF164}.Release|x86.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|ARM.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|ARM.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|ARM64.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|iPhone.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|x64.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|x64.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|x86.ActiveCfg = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Debug|x86.Build.0 = Debug|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|Any CPU.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|ARM.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|ARM.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|ARM64.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|ARM64.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|iPhone.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|iPhone.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|x64.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|x64.Build.0 = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|x86.ActiveCfg = Release|Any CPU - {FD6FF872-77D6-4E5D-8E75-0271352D3054}.Release|x86.Build.0 = Release|Any CPU {A203BA92-B3B6-411C-91E1-8F3FF7BF2163}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A203BA92-B3B6-411C-91E1-8F3FF7BF2163}.Debug|Any CPU.Build.0 = Debug|Any CPU {A203BA92-B3B6-411C-91E1-8F3FF7BF2163}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -513,76 +439,6 @@ Global {3D74BDE9-847A-46F9-B6FA-6F445F217843}.Release|x64.Build.0 = Release|Any CPU {3D74BDE9-847A-46F9-B6FA-6F445F217843}.Release|x86.ActiveCfg = Release|Any CPU {3D74BDE9-847A-46F9-B6FA-6F445F217843}.Release|x86.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|ARM.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|ARM.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|ARM64.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|iPhone.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|x64.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|x64.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|x86.ActiveCfg = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Debug|x86.Build.0 = Debug|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|Any CPU.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|ARM.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|ARM.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|ARM64.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|ARM64.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|iPhone.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|iPhone.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|x64.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|x64.Build.0 = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|x86.ActiveCfg = Release|Any CPU - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841}.Release|x86.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM64.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|ARM64.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhone.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhone.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x64.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x64.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x64.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x86.ActiveCfg = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x86.Build.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Debug|x86.Deploy.0 = Debug|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|Any CPU.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|Any CPU.Deploy.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM.Deploy.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM64.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM64.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|ARM64.Deploy.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhone.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhone.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhone.Deploy.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x64.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x64.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x64.Deploy.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x86.ActiveCfg = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x86.Build.0 = Release|Any CPU - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA}.Release|x86.Deploy.0 = Release|Any CPU {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -611,34 +467,6 @@ Global {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}.Release|x64.Build.0 = Release|Any CPU {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}.Release|x86.ActiveCfg = Release|Any CPU {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5}.Release|x86.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|ARM.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|ARM.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|ARM64.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|iPhone.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|x64.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|x64.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|x86.ActiveCfg = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Debug|x86.Build.0 = Debug|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|Any CPU.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|ARM.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|ARM.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|ARM64.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|ARM64.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|iPhone.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|iPhone.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|x64.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|x64.Build.0 = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|x86.ActiveCfg = Release|Any CPU - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A}.Release|x86.Build.0 = Release|Any CPU {BC5F6313-435E-4748-99D5-BB6F3B109F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BC5F6313-435E-4748-99D5-BB6F3B109F91}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC5F6313-435E-4748-99D5-BB6F3B109F91}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -695,34 +523,6 @@ Global {6C907586-BC27-4BED-AD6D-52F0755172CB}.Release|x64.Build.0 = Release|Any CPU {6C907586-BC27-4BED-AD6D-52F0755172CB}.Release|x86.ActiveCfg = Release|Any CPU {6C907586-BC27-4BED-AD6D-52F0755172CB}.Release|x86.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|ARM.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|ARM.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|ARM64.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|iPhone.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|x64.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|x64.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|x86.ActiveCfg = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Debug|x86.Build.0 = Debug|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|Any CPU.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|ARM.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|ARM.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|ARM64.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|ARM64.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|iPhone.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|iPhone.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|x64.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|x64.Build.0 = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|x86.ActiveCfg = Release|Any CPU - {95DF567C-C766-4382-B8A7-C0D99EDC73B0}.Release|x86.Build.0 = Release|Any CPU {1D95FBB4-A43D-4805-B307-91C92D3E91C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {1D95FBB4-A43D-4805-B307-91C92D3E91C1}.Debug|Any CPU.Build.0 = Debug|Any CPU {1D95FBB4-A43D-4805-B307-91C92D3E91C1}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -835,90 +635,6 @@ Global {5597B34A-4337-4A17-B0B0-BB1438D435B0}.Release|x64.Build.0 = Release|Any CPU {5597B34A-4337-4A17-B0B0-BB1438D435B0}.Release|x86.ActiveCfg = Release|Any CPU {5597B34A-4337-4A17-B0B0-BB1438D435B0}.Release|x86.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|ARM.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|ARM.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|ARM64.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|iPhone.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|x64.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|x64.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|x86.ActiveCfg = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Debug|x86.Build.0 = Debug|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|Any CPU.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|ARM.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|ARM.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|ARM64.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|ARM64.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|iPhone.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|iPhone.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|x64.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|x64.Build.0 = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|x86.ActiveCfg = Release|Any CPU - {E5E808A7-32B9-4699-874D-B31AFF1246F6}.Release|x86.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|Any CPU.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|ARM.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|ARM.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|ARM64.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|iPhone.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|x64.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|x64.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|x86.ActiveCfg = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Debug|x86.Build.0 = Debug|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|Any CPU.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|Any CPU.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|ARM.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|ARM.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|ARM64.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|ARM64.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|iPhone.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|iPhone.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|x64.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|x64.Build.0 = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|x86.ActiveCfg = Release|Any CPU - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D}.Release|x86.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|ARM.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|ARM.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|ARM64.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|iPhone.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|x64.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|x64.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|x86.ActiveCfg = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Debug|x86.Build.0 = Debug|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|Any CPU.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|ARM.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|ARM.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|ARM64.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|ARM64.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|iPhone.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|iPhone.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|x64.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|x64.Build.0 = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|x86.ActiveCfg = Release|Any CPU - {3BFEFB3F-3D91-4271-BEA7-780879D464C1}.Release|x86.Build.0 = Release|Any CPU {F08C0D0F-2399-439B-9C62-A249141A7F7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F08C0D0F-2399-439B-9C62-A249141A7F7E}.Debug|Any CPU.Build.0 = Debug|Any CPU {F08C0D0F-2399-439B-9C62-A249141A7F7E}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -1199,48 +915,6 @@ Global {1CB40DC8-8FBC-4278-A19A-D872CFA353C0}.Release|x64.Build.0 = Release|Any CPU {1CB40DC8-8FBC-4278-A19A-D872CFA353C0}.Release|x86.ActiveCfg = Release|Any CPU {1CB40DC8-8FBC-4278-A19A-D872CFA353C0}.Release|x86.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM64.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|ARM64.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhone.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhone.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|x64.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|x64.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|x64.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|x86.ActiveCfg = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|x86.Build.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Debug|x86.Deploy.0 = Debug|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|Any CPU.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|Any CPU.Deploy.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|ARM.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|ARM.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|ARM.Deploy.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|ARM64.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|ARM64.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|ARM64.Deploy.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|iPhone.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|iPhone.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|iPhone.Deploy.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|x64.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|x64.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|x64.Deploy.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|x86.ActiveCfg = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|x86.Build.0 = Release|Any CPU - {B355E372-27D2-4217-A129-D3355573681F}.Release|x86.Deploy.0 = Release|Any CPU {9A8D2254-9B2B-4B92-8498-43A73BB9A410}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {9A8D2254-9B2B-4B92-8498-43A73BB9A410}.Debug|Any CPU.Build.0 = Debug|Any CPU {9A8D2254-9B2B-4B92-8498-43A73BB9A410}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -1423,34 +1097,6 @@ Global {137690DF-A3CB-4817-ACB8-9EAF3A52B5B5}.Release|x64.Build.0 = Release|Any CPU {137690DF-A3CB-4817-ACB8-9EAF3A52B5B5}.Release|x86.ActiveCfg = Release|Any CPU {137690DF-A3CB-4817-ACB8-9EAF3A52B5B5}.Release|x86.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|ARM.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|ARM.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|ARM64.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|iPhone.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|x64.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|x64.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|x86.ActiveCfg = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Debug|x86.Build.0 = Debug|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|Any CPU.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|ARM.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|ARM.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|ARM64.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|ARM64.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|iPhone.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|iPhone.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|x64.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|x64.Build.0 = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|x86.ActiveCfg = Release|Any CPU - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF}.Release|x86.Build.0 = Release|Any CPU {42154590-445B-41CF-AAEB-AACD1B65FA2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {42154590-445B-41CF-AAEB-AACD1B65FA2C}.Debug|Any CPU.Build.0 = Debug|Any CPU {42154590-445B-41CF-AAEB-AACD1B65FA2C}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -1479,34 +1125,6 @@ Global {42154590-445B-41CF-AAEB-AACD1B65FA2C}.Release|x64.Build.0 = Release|Any CPU {42154590-445B-41CF-AAEB-AACD1B65FA2C}.Release|x86.ActiveCfg = Release|Any CPU {42154590-445B-41CF-AAEB-AACD1B65FA2C}.Release|x86.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|ARM.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|ARM.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|ARM64.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|iPhone.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|iPhone.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|x64.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|x64.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|x86.ActiveCfg = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Debug|x86.Build.0 = Debug|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|Any CPU.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|ARM.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|ARM.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|ARM64.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|ARM64.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|iPhone.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|iPhone.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|iPhoneSimulator.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|x64.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|x64.Build.0 = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|x86.ActiveCfg = Release|Any CPU - {D9AF058F-D954-439B-BD72-51C47F65E7BE}.Release|x86.Build.0 = Release|Any CPU {84AA1922-CB8D-4C6F-9117-10C611FD0FB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {84AA1922-CB8D-4C6F-9117-10C611FD0FB1}.Debug|Any CPU.Build.0 = Debug|Any CPU {84AA1922-CB8D-4C6F-9117-10C611FD0FB1}.Debug|ARM.ActiveCfg = Debug|Any CPU @@ -1627,8 +1245,6 @@ Global {AA6128E6-5B79-4EFF-88A3-FA60A5FCDD07} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {7A2A46B1-4202-46DA-AB78-F6CF32316BE5} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {371B4824-FA2D-415A-AD90-722B341F23F3} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} - {938BEBE3-67A9-4D90-A72C-C378F90FF164} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} - {FD6FF872-77D6-4E5D-8E75-0271352D3054} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {A203BA92-B3B6-411C-91E1-8F3FF7BF2163} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {FEB554A3-1CAD-4E77-A300-CD8CA520EED6} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138} {86505E07-1D61-450C-96ED-263E80349DE0} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138} @@ -1637,23 +1253,16 @@ Global {8D034553-3218-4B56-8B3D-00B96FCFF29A} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138} {41224EF6-1233-44BE-86F3-A3597E2598EB} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138} {3D74BDE9-847A-46F9-B6FA-6F445F217843} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B} - {DAEE295C-1C4B-4D64-B0FD-46FE6C139841} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B} - {AD7B78B0-AE51-4FB7-9B11-4E22A2B538CA} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B} {EC9EA203-42F9-4D71-9DBF-9DAC12EFCCF5} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B} - {931C8F51-0350-4CFC-92B4-E2D89CC41C9A} = {CC46B486-00D7-49E6-ABA3-FDF8F4868D2B} {BC5F6313-435E-4748-99D5-BB6F3B109F91} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} {6C907586-BC27-4BED-AD6D-52F0755172CB} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {95DF567C-C766-4382-B8A7-C0D99EDC73B0} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {1D95FBB4-A43D-4805-B307-91C92D3E91C1} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {E1005888-262E-4477-858B-497FF2DBFCFF} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {0AE2FEC7-BE21-48DA-8D74-B932DEE1B4DE} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {5597B34A-4337-4A17-B0B0-BB1438D435B0} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {E5E808A7-32B9-4699-874D-B31AFF1246F6} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {FB829D3F-CA33-4413-A84C-C0C80E28AA2D} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {3BFEFB3F-3D91-4271-BEA7-780879D464C1} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {F08C0D0F-2399-439B-9C62-A249141A7F7E} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {24CA2205-3581-4449-91B7-4C4FA4A3E032} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} - {1C19FB76-5997-42FF-8F1A-E073C558FBC8} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} + {1D95FBB4-A43D-4805-B307-91C92D3E91C1} = {8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029} + {E1005888-262E-4477-858B-497FF2DBFCFF} = {E50441E8-75F3-406E-9921-30BFC211B5CE} + {0AE2FEC7-BE21-48DA-8D74-B932DEE1B4DE} = {E50441E8-75F3-406E-9921-30BFC211B5CE} + {5597B34A-4337-4A17-B0B0-BB1438D435B0} = {E50441E8-75F3-406E-9921-30BFC211B5CE} + {F08C0D0F-2399-439B-9C62-A249141A7F7E} = {4E7DF449-F136-4B90-82CE-D1418CD5123C} + {24CA2205-3581-4449-91B7-4C4FA4A3E032} = {4E7DF449-F136-4B90-82CE-D1418CD5123C} + {1C19FB76-5997-42FF-8F1A-E073C558FBC8} = {4E7DF449-F136-4B90-82CE-D1418CD5123C} {E9B49DD4-D60E-4C7F-A632-0849A0C36C7D} = {E448F863-4C9D-47A4-BC4A-4A1381B54DA4} {D26D2FB8-7F76-4A60-91E1-E539CE466470} = {E448F863-4C9D-47A4-BC4A-4A1381B54DA4} {452CBEB4-95B6-4D9A-B95F-0F09CA28A45A} = {E448F863-4C9D-47A4-BC4A-4A1381B54DA4} @@ -1666,12 +1275,14 @@ Global {B1F221F6-E19B-45D8-959D-A9CDA471C2D4} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138} {2A66B796-7BC2-4BE0-A920-1A457BBCCC67} = {1B889C56-157A-4493-85F2-76366282B002} {137690DF-A3CB-4817-ACB8-9EAF3A52B5B5} = {E448F863-4C9D-47A4-BC4A-4A1381B54DA4} - {9252AA73-9CF7-4B09-89CB-7FCB65A5DCFF} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} {42154590-445B-41CF-AAEB-AACD1B65FA2C} = {673FF8CD-9E85-4FA1-ABFC-D1149675E138} {84AA1922-CB8D-4C6F-9117-10C611FD0FB1} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {5C97EE6C-3E87-4FF8-A3F9-19A4459F5427} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {279C7FA4-089C-478D-B392-7E38C8781ACB} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} {D30203AC-97AB-4A51-BFA5-826251C9A28E} = {83186945-EC14-4B3F-8C6F-B205AA184CA4} + {E50441E8-75F3-406E-9921-30BFC211B5CE} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} + {8E38AAF2-8C7D-4B0D-AB25-AB37EECB4029} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} + {4E7DF449-F136-4B90-82CE-D1418CD5123C} = {327FDEE7-C4C8-4AA4-A7B0-8BCE3D75346F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9313F2B4-10DA-43AA-A481-CAA7571C740C} diff --git a/packaging/build-osx-app.sh b/packaging/build-osx-app.sh index 6f7230059..241fa4bb0 100644 --- a/packaging/build-osx-app.sh +++ b/packaging/build-osx-app.sh @@ -33,9 +33,9 @@ emit_plist() { CFBundleIdentifier net.steampp.app CFBundleShortVersionString - 2.4.13 + 2.4.14 CFBundleVersion - 2.4.13.0 + 2.4.14.0 LSMinimumSystemVersion 10.14 CFBundleDevelopmentRegion diff --git a/references/Microsoft.Windows.SDK.NET.dll b/references/Microsoft.Windows.SDK.NET.dll index e97912203..2506ef3d9 100644 Binary files a/references/Microsoft.Windows.SDK.NET.dll and b/references/Microsoft.Windows.SDK.NET.dll differ diff --git a/src/AboutAppInfoPopup.cs b/src/AboutAppInfoPopup.cs index 352ad9f3d..372c9ecf5 100644 --- a/src/AboutAppInfoPopup.cs +++ b/src/AboutAppInfoPopup.cs @@ -56,13 +56,13 @@ namespace System.Application.UI #else if (OperatingSystem2.IsWindows) { - var dps = IDesktopPlatformService.Instance; + var platformService = IPlatformService.Instance; #pragma warning disable CA1416 // 验证平台兼容性 - var productName = dps.WindowsProductName; + var productName = platformService.WindowsProductName; var major = Environment.OSVersion.Version.Major; var minor = Environment.OSVersion.Version.Minor; var build = Environment.OSVersion.Version.Build; - var revision = dps.WindowsVersionRevision; + var revision = platformService.WindowsVersionRevision; b.AppendFormat("{0} {1}.{2}.{3}.{4}", productName, major, minor, build, revision); var servicePack = Environment.OSVersion.ServicePack; if (!string.IsNullOrEmpty(servicePack)) @@ -70,7 +70,7 @@ namespace System.Application.UI b.Append(' '); b.Append(servicePack); } - var releaseId = dps.WindowsReleaseIdOrDisplayVersion; + var releaseId = platformService.WindowsReleaseIdOrDisplayVersion; #pragma warning restore CA1416 // 验证平台兼容性 if (!string.IsNullOrWhiteSpace(releaseId)) { @@ -375,7 +375,7 @@ namespace System.Application.UI b.AppendLine(); var b_str = b.ToString(); - MessageBoxCompat.Show(b_str, ""); + MessageBox.Show(b_str, ""); } } } diff --git a/src/Common.ClientLib.Droid/Application/Services/IAppUpdateService.cs b/src/Common.ClientLib.Droid/Application/Services/IApplicationUpdateService.cs similarity index 67% rename from src/Common.ClientLib.Droid/Application/Services/IAppUpdateService.cs rename to src/Common.ClientLib.Droid/Application/Services/IApplicationUpdateService.cs index ebc58609c..636917d4f 100644 --- a/src/Common.ClientLib.Droid/Application/Services/IAppUpdateService.cs +++ b/src/Common.ClientLib.Droid/Application/Services/IApplicationUpdateService.cs @@ -1,6 +1,6 @@ namespace System.Application.Services { - public interface IAppUpdateService + public interface IApplicationUpdateService { const float MaxProgressValue = 100f; } diff --git a/src/Common.ClientLib.Droid/Application/Services/Implementation/PlatformToastImpl.cs b/src/Common.ClientLib.Droid/Application/Services/Implementation/PlatformToastImpl.cs index df2fb0a31..1cd354ec3 100644 --- a/src/Common.ClientLib.Droid/Application/Services/Implementation/PlatformToastImpl.cs +++ b/src/Common.ClientLib.Droid/Application/Services/Implementation/PlatformToastImpl.cs @@ -10,7 +10,7 @@ namespace System.Application.Services.Implementation /// /// https://developer.android.google.cn/guide/topics/ui/notifiers/toasts /// - internal sealed class PlatformToastImpl : ToastImpl + internal sealed class PlatformToastImpl : ToastBaseImpl { public PlatformToastImpl(IToastIntercept intercept) : base(intercept) { diff --git a/src/Common.ClientLib/Application/Essentials/Clipboard2.cs b/src/Common.ClientLib/Application/Essentials/Clipboard2.cs index a1a200616..62d165e98 100644 --- a/src/Common.ClientLib/Application/Essentials/Clipboard2.cs +++ b/src/Common.ClientLib/Application/Essentials/Clipboard2.cs @@ -1,6 +1,6 @@ using System.Threading.Tasks; using Xamarin.Essentials; -using static System.Application.Services.IClipboardPlatformService; +using System.Application.Services; namespace System.Application { @@ -19,7 +19,7 @@ namespace System.Application } else { - await Instance.PlatformSetTextAsync(text ?? string.Empty); + await IClipboardPlatformService.Instance.PlatformSetTextAsync(text ?? string.Empty); } } @@ -33,7 +33,7 @@ namespace System.Application } else { - return await Instance.PlatformGetTextAsync(); + return await IClipboardPlatformService.Instance.PlatformGetTextAsync(); } } @@ -47,7 +47,7 @@ namespace System.Application } else { - return Instance.PlatformHasText; + return IClipboardPlatformService.Instance.PlatformHasText; } } } diff --git a/src/Common.ClientLib/Application/Essentials/FilePicker2.cs b/src/Common.ClientLib/Application/Essentials/FilePicker2.cs index 7131a96d0..200565269 100644 --- a/src/Common.ClientLib/Application/Essentials/FilePicker2.cs +++ b/src/Common.ClientLib/Application/Essentials/FilePicker2.cs @@ -35,6 +35,17 @@ namespace System.Application /// public static bool IsSupportedFileExtensionFilter => mIsSupportedFileExtensionFilter.Value; + static readonly Lazy mIsSupportedSaveFileDialog = new(() => + { + var s = ISaveFileDialogService.Instance; + return s != null; + }); + + /// + /// 是否支持保存文件对话框 + /// + public static bool IsSupportedSaveFileDialog => mIsSupportedSaveFileDialog.Value; + public static async Task PickAsync(PickOptions? options = null) { if (XamarinEssentials.IsSupported) diff --git a/src/Common.ClientLib/Application/Essentials/MainThread2.cs b/src/Common.ClientLib/Application/Essentials/MainThread2.cs index bc224c5bb..a8ad9f44b 100644 --- a/src/Common.ClientLib/Application/Essentials/MainThread2.cs +++ b/src/Common.ClientLib/Application/Essentials/MainThread2.cs @@ -1,7 +1,7 @@ using System.Threading.Tasks; using System.Windows.Threading; using Xamarin.Essentials; -using static System.Application.Services.IMainThreadPlatformService; +using System.Application.Services; namespace System.Application { @@ -22,7 +22,7 @@ namespace System.Application } else { - return Instance.PlatformIsMainThread; + return IMainThreadPlatformService.Instance.PlatformIsMainThread; } } } @@ -41,7 +41,7 @@ namespace System.Application } else { - Instance.PlatformBeginInvokeOnMainThread(action, priority); + IMainThreadPlatformService.Instance.PlatformBeginInvokeOnMainThread(action, priority); } } } diff --git a/src/Common.ClientLib/Application/Services/IClipboardPlatformService.cs b/src/Common.ClientLib/Application/Services/IClipboardPlatformService.cs index 86411ff38..1c8b5631c 100644 --- a/src/Common.ClientLib/Application/Services/IClipboardPlatformService.cs +++ b/src/Common.ClientLib/Application/Services/IClipboardPlatformService.cs @@ -2,14 +2,12 @@ using System.Threading.Tasks; namespace System.Application.Services { - public interface IClipboardPlatformService + public interface IClipboardPlatformService : IService { Task PlatformSetTextAsync(string text); Task PlatformGetTextAsync(); bool PlatformHasText { get; } - - static IClipboardPlatformService Instance => DI.Get(); } } \ No newline at end of file diff --git a/src/Common.ClientLib/Application/Services/IEmailPlatformService.cs b/src/Common.ClientLib/Application/Services/IEmailPlatformService.cs index c1d3688ef..1bacea681 100644 --- a/src/Common.ClientLib/Application/Services/IEmailPlatformService.cs +++ b/src/Common.ClientLib/Application/Services/IEmailPlatformService.cs @@ -3,10 +3,8 @@ using Xamarin.Essentials; namespace System.Application.Services { - public interface IEmailPlatformService + public interface IEmailPlatformService : IService { Task PlatformComposeAsync(EmailMessage? message); - - static IEmailPlatformService? Instance => DI.Get_Nullable(); } } \ No newline at end of file diff --git a/src/Common.ClientLib/Application/Services/IFilePickerPlatformService.cs b/src/Common.ClientLib/Application/Services/IFilePickerPlatformService.cs index 335dbc80f..11fc0ab9f 100644 --- a/src/Common.ClientLib/Application/Services/IFilePickerPlatformService.cs +++ b/src/Common.ClientLib/Application/Services/IFilePickerPlatformService.cs @@ -42,20 +42,16 @@ namespace System.Application.Services } } - public interface IOpenFileDialogService : IServiceBase + public interface IOpenFileDialogService : IServiceBase, IOptionalService { Task> PlatformPickAsync(PickOptions? options, bool allowMultiple = false); - static IOpenFileDialogService? Instance => DI.Get_Nullable(); - bool IsSupportedFileExtensionFilter { get; } } - public interface ISaveFileDialogService : IServiceBase + public interface ISaveFileDialogService : IServiceBase, IOptionalService { Task PlatformSaveAsync(SaveOptions? options); - - static ISaveFileDialogService? Instance => DI.Get_Nullable(); } } } \ No newline at end of file diff --git a/src/Common.ClientLib/Application/Services/IMainThreadPlatformService.cs b/src/Common.ClientLib/Application/Services/IMainThreadPlatformService.cs index c74731baa..7519868dc 100644 --- a/src/Common.ClientLib/Application/Services/IMainThreadPlatformService.cs +++ b/src/Common.ClientLib/Application/Services/IMainThreadPlatformService.cs @@ -5,12 +5,10 @@ namespace System.Application.Services /// /// 由平台实现的主线程帮助类 /// - public interface IMainThreadPlatformService + public interface IMainThreadPlatformService : IService { bool PlatformIsMainThread { get; } void PlatformBeginInvokeOnMainThread(Action action, DispatcherPriorityCompat priority = DispatcherPriorityCompat.Normal); - - static IMainThreadPlatformService Instance => DI.Get(); } } \ No newline at end of file diff --git a/src/Common.ClientLib/Application/Services/INotificationService.cs b/src/Common.ClientLib/Application/Services/INotificationService.cs index a997c4a3a..c75e9bb0d 100644 --- a/src/Common.ClientLib/Application/Services/INotificationService.cs +++ b/src/Common.ClientLib/Application/Services/INotificationService.cs @@ -5,13 +5,11 @@ namespace System.Application.Services /// /// /// - public interface INotificationService + public interface INotificationService : IService where TNotificationType : notnull, Enum where TEntrance : notnull, Enum where TNotificationService : INotificationService { - static TNotificationService Instance => DI.Get(); - /// /// 获取是否有通知权限 /// diff --git a/src/Common.ClientLib/Application/Services/IPermissions.cs b/src/Common.ClientLib/Application/Services/IPermissions.cs index 3c11a9daf..6f2ae38d3 100644 --- a/src/Common.ClientLib/Application/Services/IPermissions.cs +++ b/src/Common.ClientLib/Application/Services/IPermissions.cs @@ -7,10 +7,8 @@ namespace System.Application.Services /// /// 运行时权限 /// - public interface IPermissions + public interface IPermissions : IService { - static IPermissions Instance => DI.Get(); - interface IPermission { BasePermission Permission { get; } diff --git a/src/Common.ClientLib/Application/Services/ITelephonyService.cs b/src/Common.ClientLib/Application/Services/ITelephonyService.cs index 54139cf21..66a4ac697 100644 --- a/src/Common.ClientLib/Application/Services/ITelephonyService.cs +++ b/src/Common.ClientLib/Application/Services/ITelephonyService.cs @@ -5,10 +5,8 @@ namespace System.Application.Services /// /// 电话服务 /// - public interface ITelephonyService + public interface ITelephonyService : IService { - public static ITelephonyService Instance => DI.Get(); - /// /// 获取当前设备的手机号码(Only Android) /// diff --git a/src/Common.ClientLib/Application/Services/Implementation/ToastImpl.cs b/src/Common.ClientLib/Application/Services/Implementation/ToastBaseImpl.cs similarity index 95% rename from src/Common.ClientLib/Application/Services/Implementation/ToastImpl.cs rename to src/Common.ClientLib/Application/Services/Implementation/ToastBaseImpl.cs index 7f3b9e1fe..c1f695a14 100644 --- a/src/Common.ClientLib/Application/Services/Implementation/ToastImpl.cs +++ b/src/Common.ClientLib/Application/Services/Implementation/ToastBaseImpl.cs @@ -4,13 +4,13 @@ using Xamarin.Essentials; namespace System.Application.Services.Implementation { - public abstract class ToastImpl : IToast + public abstract class ToastBaseImpl : IToast { protected readonly IToastIntercept intercept; protected const string TAG = "Toast"; - public ToastImpl(IToastIntercept intercept) + public ToastBaseImpl(IToastIntercept intercept) { this.intercept = intercept; } diff --git a/src/Common.ClientLib/Application/Services/Mvvm/MvvmService.cs b/src/Common.ClientLib/Application/Services/Mvvm/MvvmService.cs index e8c946a03..3b3aff219 100644 --- a/src/Common.ClientLib/Application/Services/Mvvm/MvvmService.cs +++ b/src/Common.ClientLib/Application/Services/Mvvm/MvvmService.cs @@ -2,11 +2,10 @@ using ReactiveUI; namespace System.Application.Services { - public abstract class MvvmService : ReactiveObject where TService : MvvmService + public abstract class MvvmService : ReactiveObject where TService : MvvmService, new() { static TService? mCurrent; - public static TService Current => mCurrent ?? - throw new NullReferenceException($"{typeof(TService).Name} not initialized."); + public static TService Current => mCurrent ?? new TService(); public MvvmService() { diff --git a/src/Common.ClientLib/Extensions/HttpPlatformHelperExtensions.cs b/src/Common.ClientLib/Extensions/HttpPlatformHelperExtensions.cs deleted file mode 100644 index f0b5bd03a..000000000 --- a/src/Common.ClientLib/Extensions/HttpPlatformHelperExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Application; -using System.Net.Http; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System -{ - public static class HttpPlatformHelperExtensions - { - /// - /// 是否有网络链接 - /// - /// - /// - public static Task IsConnectedAsync(this IHttpPlatformHelper helper) => - MainThread2.InvokeOnMainThreadAsync(() => - { -#pragma warning disable CS0618 // 类型或成员已过时 - return helper.IsConnected; -#pragma warning restore CS0618 // 类型或成员已过时 - }); - } -} \ No newline at end of file diff --git a/src/Common.ClientLib/Net/Http/ClientHttpPlatformHelperService.cs b/src/Common.ClientLib/Net/Http/ClientHttpPlatformHelperService.cs new file mode 100644 index 000000000..ab1ceba94 --- /dev/null +++ b/src/Common.ClientLib/Net/Http/ClientHttpPlatformHelperService.cs @@ -0,0 +1,11 @@ +using System.Application; +using System.Threading.Tasks; + +namespace System.Net.Http +{ + /// + public abstract class ClientHttpPlatformHelperService : HttpPlatformHelperService + { + public override Task IsConnectedAsync() => MainThread2.InvokeOnMainThreadAsync(() => IsConnected); + } +} diff --git a/src/Common.CoreLib/Application/Services/IOptionalService.cs b/src/Common.CoreLib/Application/Services/IOptionalService.cs new file mode 100644 index 000000000..04cbf60bf --- /dev/null +++ b/src/Common.CoreLib/Application/Services/IOptionalService.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace System.Application.Services +{ + public interface IOptionalService where T : notnull, IOptionalService + { + static T? Instance => DI.Get_Nullable(); + } +} diff --git a/src/Common.CoreLib/Application/Services/IService.cs b/src/Common.CoreLib/Application/Services/IService.cs new file mode 100644 index 000000000..2e98e44d6 --- /dev/null +++ b/src/Common.CoreLib/Application/Services/IService.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace System.Application.Services +{ + public interface IService where T : notnull, IService + { + static T Instance => DI.Get(); + } +} diff --git a/src/Common.CoreLib/Common.CoreLib.csproj b/src/Common.CoreLib/Common.CoreLib.csproj index f39f6bdc5..45e8a81a3 100644 --- a/src/Common.CoreLib/Common.CoreLib.csproj +++ b/src/Common.CoreLib/Common.CoreLib.csproj @@ -1,7 +1,7 @@ - netstandard2.1;netcoreapp3.1 + netstandard2.1;netcoreapp3.1;net5.0 System System.Common.CoreLib diff --git a/src/Common.CoreLib/Enum2.cs b/src/Common.CoreLib/Enum2.cs index 3b8abc215..1ad514b0d 100644 --- a/src/Common.CoreLib/Enum2.cs +++ b/src/Common.CoreLib/Enum2.cs @@ -13,9 +13,14 @@ namespace System /// /// /// - public static TEnum[] GetAll() where TEnum : Enum => (TEnum[])Enum.GetValues(typeof(TEnum)); + public static TEnum[] GetAll() where TEnum : struct, Enum => +#if !NET5_0_OR_GREATER + (TEnum[])Enum.GetValues(typeof(TEnum)); +#else + Enum.GetValues(); +#endif - public static string[] GetAllStrings() where TEnum : Enum => GetAll().Select(x => x.ToString()).ToArray(); + public static string[] GetAllStrings() where TEnum : struct, Enum => GetAll().Select(x => x.ToString()).ToArray(); /// /// 将 Flags 枚举进行拆分 @@ -23,7 +28,7 @@ namespace System /// /// /// - public static IEnumerable FlagsSplit(TEnum resultant) where TEnum : Enum + public static IEnumerable FlagsSplit(TEnum resultant) where TEnum : struct, Enum => GetAll().Where(x => resultant.HasFlag(x)).ToArray(); internal static TEnum ConvertToEnum(this TStruct value) @@ -39,7 +44,7 @@ namespace System /// /// 返回指定枚举值的描述(通过 - /// 指定)。 + /// 指定)。 /// 如果没有指定描述,则返回枚举常数的名称,没有找到枚举常数则返回枚举值。 /// /// 要获取描述的枚举值。 @@ -48,11 +53,11 @@ namespace System { Type enumType = value.GetType(); // 获取枚举常数名称。 - string name = Enum.GetName(enumType, value); + var name = Enum.GetName(enumType, value); if (name != null) { // 获取枚举字段。 - FieldInfo fieldInfo = enumType.GetField(name); + var fieldInfo = enumType.GetField(name); if (fieldInfo != null) { if (Attribute.GetCustomAttribute(fieldInfo, diff --git a/src/Common.CoreLib/Net/Http/GeneralHttpClientFactory.cs b/src/Common.CoreLib/Net/Http/GeneralHttpClientFactory.cs index aaafff856..0d748d34a 100644 --- a/src/Common.CoreLib/Net/Http/GeneralHttpClientFactory.cs +++ b/src/Common.CoreLib/Net/Http/GeneralHttpClientFactory.cs @@ -8,12 +8,12 @@ namespace System.Net.Http public abstract class GeneralHttpClientFactory { protected readonly ILogger logger; - protected readonly IHttpPlatformHelper http_helper; + protected readonly IHttpPlatformHelperService http_helper; protected readonly IHttpClientFactory _clientFactory; public GeneralHttpClientFactory( ILogger logger, - IHttpPlatformHelper http_helper, + IHttpPlatformHelperService http_helper, IHttpClientFactory clientFactory) { this.logger = logger; diff --git a/src/Common.CoreLib/Net/Http/HttpPlatformHelper.cs b/src/Common.CoreLib/Net/Http/HttpPlatformHelperService.cs similarity index 81% rename from src/Common.CoreLib/Net/Http/HttpPlatformHelper.cs rename to src/Common.CoreLib/Net/Http/HttpPlatformHelperService.cs index 307444307..adcc62afc 100644 --- a/src/Common.CoreLib/Net/Http/HttpPlatformHelper.cs +++ b/src/Common.CoreLib/Net/Http/HttpPlatformHelperService.cs @@ -1,12 +1,13 @@ using System.Globalization; using System.IO; using System.IO.FileFormats; +using System.Threading.Tasks; using Xamarin.Essentials; namespace System.Net.Http { - /// - public abstract class HttpPlatformHelper : IHttpPlatformHelper + /// + public abstract class HttpPlatformHelperService : IHttpPlatformHelperService { protected const string DefaultUserAgent = "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263"; @@ -27,7 +28,7 @@ namespace System.Net.Http public virtual (string filePath, string mime)? TryHandleUploadFile(Stream fileStream) => null; - public virtual bool IsConnected + protected virtual bool IsConnected { get { @@ -39,5 +40,7 @@ namespace System.Net.Http return true; } } + + public virtual Task IsConnectedAsync() => Task.FromResult(IsConnected); } -} \ No newline at end of file +} diff --git a/src/Common.CoreLib/Net/Http/IHttpPlatformHelper.cs b/src/Common.CoreLib/Net/Http/IHttpPlatformHelperService.cs similarity index 78% rename from src/Common.CoreLib/Net/Http/IHttpPlatformHelper.cs rename to src/Common.CoreLib/Net/Http/IHttpPlatformHelperService.cs index b39edc794..8edb5e56e 100644 --- a/src/Common.CoreLib/Net/Http/IHttpPlatformHelper.cs +++ b/src/Common.CoreLib/Net/Http/IHttpPlatformHelperService.cs @@ -1,13 +1,16 @@ using System.IO; using System.IO.FileFormats; +using System.Threading.Tasks; namespace System.Net.Http { /// - /// 由平台实现的HTTP工具助手 + /// 由平台实现的HTTP工具助手服务 /// - public interface IHttpPlatformHelper + public interface IHttpPlatformHelperService { + static IHttpPlatformHelperService Instance => DI.Get(); + /// /// 用户代理 /// https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/User-Agent @@ -33,7 +36,7 @@ namespace System.Net.Http /// /// 是否有网络链接 /// - [Obsolete("use IsConnectedAsync")] - bool IsConnected { get; } + /// + Task IsConnectedAsync(); } } \ No newline at end of file diff --git a/src/Common.CoreLib/Properties/ThisAssembly.Version.cs b/src/Common.CoreLib/Properties/ThisAssembly.Version.cs index ac796fa0f..adfb6aa95 100644 --- a/src/Common.CoreLib/Properties/ThisAssembly.Version.cs +++ b/src/Common.CoreLib/Properties/ThisAssembly.Version.cs @@ -12,7 +12,7 @@ namespace System.Properties /// macOS:\packaging\build-osx-app.sh <CFBundleVersion> <CFBundleShortVersionString> /// /// - public const string Version = "2.4.13"; + public const string Version = "2.4.14"; //public const string InfoVersion = Version + "-beta"; } diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge.Package/Package.appxmanifest b/src/ST.Client.Desktop.Avalonia.App.Bridge.Package/Package.appxmanifest index 206ad2946..67c7c9c44 100644 --- a/src/ST.Client.Desktop.Avalonia.App.Bridge.Package/Package.appxmanifest +++ b/src/ST.Client.Desktop.Avalonia.App.Bridge.Package/Package.appxmanifest @@ -10,7 +10,7 @@ + Version="2.4.14.0" /> Steam++ diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge.Package/ST.Client.Desktop.Avalonia.App.Bridge.Package.wapproj b/src/ST.Client.Desktop.Avalonia.App.Bridge.Package/ST.Client.Avalonia.App.Bridge.Package.wapproj similarity index 100% rename from src/ST.Client.Desktop.Avalonia.App.Bridge.Package/ST.Client.Desktop.Avalonia.App.Bridge.Package.wapproj rename to src/ST.Client.Desktop.Avalonia.App.Bridge.Package/ST.Client.Avalonia.App.Bridge.Package.wapproj diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs b/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs index 408e0b772..0a15fb9bf 100644 --- a/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs +++ b/src/ST.Client.Desktop.Avalonia.App.Bridge/DesktopBridgeHelper2.cs @@ -38,7 +38,7 @@ namespace System.Application if (args.Kind == ActivationKind.StartupTask) { // 静默启动(不弹窗口) - main_args = IDesktopPlatformService.SystemBootRunArguments.Split(' '); + main_args = IPlatformService.SystemBootRunArguments.Split(' '); } } } diff --git a/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj b/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj index bfecdc9d5..f536ff441 100644 --- a/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj +++ b/src/ST.Client.Desktop.Avalonia.App.Bridge/Steam++.csproj @@ -68,10 +68,9 @@ - - + - + ..\..\references\Microsoft.Windows.SDK.NET.dll diff --git a/src/ST.Client.Desktop.Avalonia.App/App.axaml b/src/ST.Client.Desktop.Avalonia.App/App.axaml index 9d29996e4..520e851c9 100644 --- a/src/ST.Client.Desktop.Avalonia.App/App.axaml +++ b/src/ST.Client.Desktop.Avalonia.App/App.axaml @@ -1,7 +1,7 @@ diff --git a/src/ST.Client.Desktop.Avalonia.App/App.axaml.cs b/src/ST.Client.Desktop.Avalonia.App/App.axaml.cs index 3c9d823d6..84d6f75e1 100644 --- a/src/ST.Client.Desktop.Avalonia.App/App.axaml.cs +++ b/src/ST.Client.Desktop.Avalonia.App/App.axaml.cs @@ -18,7 +18,7 @@ using Avalonia.Markup.Xaml.Styling; using System.Application.Services; using System.Windows.Input; using System.Linq; -using System.Application.Models.Settings; +using System.Application.Settings; using System.Application.UI.Resx; using System.Application.Models; using System.Reflection; @@ -39,8 +39,10 @@ using System.Reactive.Disposables; [assembly: Guid("82cda250-48a2-48ad-ab03-5cda873ef80c")] namespace System.Application.UI { - public partial class App : AvaloniaApplication, IDisposableHolder, IDesktopApplication, IDesktopAvaloniaAppService + public partial class App : AvaloniaApplication, IDisposableHolder, IApplication, IAvaloniaApplication, IClipboardPlatformService { + IApplication.AppType IApplication.GetType() => IApplication.AppType.Avalonia; + public static App Instance => Current is App app ? app : throw new Exception("Impossible"); //public static DirectoryInfo RootDirectory => new(IOPath.BaseDirectory); @@ -62,7 +64,7 @@ namespace System.Application.UI if (value == AppTheme.FollowingSystem) { - var dps = DI.Get(); + var dps = IPlatformService.Instance; var isLightOrDarkTheme = dps.IsLightOrDarkTheme; if (isLightOrDarkTheme.HasValue) { @@ -75,7 +77,7 @@ namespace System.Application.UI } else if (mTheme == AppTheme.FollowingSystem) { - var dps = DI.Get(); + var dps = IPlatformService.Instance; #if DEBUG dps.SetLightOrDarkThemeFollowingSystem(false); #endif @@ -97,7 +99,7 @@ namespace System.Application.UI AppTheme IApplication.GetActualThemeByFollowingSystem() { - var dps = DI.Get(); + var dps = IPlatformService.Instance; var isLightOrDarkTheme = dps.IsLightOrDarkTheme; if (isLightOrDarkTheme.HasValue) { @@ -188,14 +190,14 @@ namespace System.Application.UI #if StartupTrace StartupTrace.Restart("App.LoadXAML"); #endif - Name = ThisAssembly.AssemblyTrademark; + Name = Constants.HARDCODED_APP_NAME; #if StartupTrace StartupTrace.Restart("App.SetP"); #endif //SettingsHost.Load(); - var windowService = IDesktopWindowViewModelManager.Instance; - windowService.InitViewModels(); - DI.Get().SetSystemSessionEnding(() => Shutdown()); + var vmService = IViewModelManager.Instance; + vmService.InitViewModels(); + IPlatformService.Instance.SetSystemSessionEnding(() => Shutdown()); #if StartupTrace StartupTrace.Restart("WindowService.Init"); #endif @@ -219,13 +221,13 @@ namespace System.Application.UI #if StartupTrace StartupTrace.Restart("UISettings.Subscribe"); #endif - switch (windowService.MainWindow) + switch (vmService.MainWindow) { case AchievementWindowViewModel window: Program.IsMinimize = false; MainWindow = new AchievementWindow { - DataContext = windowService.MainWindow, + DataContext = vmService.MainWindow, }; break; @@ -246,7 +248,7 @@ namespace System.Application.UI #endregion MainWindow = new MainWindow { - DataContext = windowService.MainWindow, + DataContext = vmService.MainWindow, }; break; } @@ -293,12 +295,12 @@ namespace System.Application.UI } #if WINDOWS #pragma warning disable CA1416 // 验证平台兼容性 - JumpLists.Init(); + IJumpListService.Instance.InitJumpList(); #pragma warning restore CA1416 // 验证平台兼容性 #endif } - IDesktopWindowViewModelManager.Instance.MainWindow.Initialize(); + IViewModelManager.Instance.MainWindow.Initialize(); desktop.MainWindow = #if !UI_DEMO @@ -324,7 +326,7 @@ namespace System.Application.UI /// public override void RegisterServices() { - ViewModelBase.IsInDesignMode = ApplicationLifetime == null; + IViewModelBase.IsInDesignMode = ApplicationLifetime == null; if (ViewModelBase.IsInDesignMode) Startup.Init(DILevel.MainProcess | DILevel.GUI); AvaloniaLocator.CurrentMutable.Bind().ToConstant(DI.Get()); @@ -415,7 +417,7 @@ namespace System.Application.UI set => mMainWindow = value; } - AvaloniaApplication IDesktopAvaloniaAppService.Current => Current; + AvaloniaApplication IAvaloniaApplication.Current => Current; /// /// Restores the app's main window by setting its WindowState to @@ -483,7 +485,7 @@ namespace System.Application.UI if (OperatingSystem2.IsWindows && Instance.MainWindow is MainWindow window) { #pragma warning disable CA1416 // 验证平台兼容性 - DI.Get().SetDesktopBackgroundToWindow(window.BackHandle, Convert.ToInt32(window.Width), Convert.ToInt32(window.Height)); + INativeWindowApiService.Instance.SetDesktopBackgroundToWindow(window.BackHandle, Convert.ToInt32(window.Width), Convert.ToInt32(window.Height)); #pragma warning restore CA1416 // 验证平台兼容性 } } @@ -505,7 +507,7 @@ namespace System.Application.UI return false; } - void IDesktopApplication.Shutdown() => Shutdown(); + void IApplication.Shutdown() => Shutdown(); //bool IDesktopAppService.IsCefInitComplete => false; //CefNetApp.InitState == CefNetAppInitState.Complete; @@ -514,7 +516,7 @@ namespace System.Application.UI public readonly CompositeDisposable compositeDisposable = new(); - CompositeDisposable IDesktopApplication.CompositeDisposable => compositeDisposable; + CompositeDisposable IApplication.CompositeDisposable => compositeDisposable; ICollection IDisposableHolder.CompositeDisposable => compositeDisposable; @@ -526,6 +528,6 @@ namespace System.Application.UI #endregion - string IDesktopApplication.RenderingSubsystemName => Program.RenderingSubsystemName; + string IAvaloniaApplication.RenderingSubsystemName => Program.RenderingSubsystemName; } } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Avalonia.App/CommandLineTools.cs b/src/ST.Client.Desktop.Avalonia.App/CommandLineTools.cs index 2c631369a..e6debf34d 100644 --- a/src/ST.Client.Desktop.Avalonia.App/CommandLineTools.cs +++ b/src/ST.Client.Desktop.Avalonia.App/CommandLineTools.cs @@ -11,7 +11,7 @@ namespace System.Application.UI partial class Program { const string command_main = "main"; - static ApplicationInstance? appInstance; + static IApplication.SingletonInstance? appInstance; /// /// 命令行工具(Command Line Tools/CLT) @@ -39,18 +39,18 @@ namespace System.Application.UI if (IsMainProcess) { var isInitAppInstanceReset = false; - initAppInstance: appInstance = new ApplicationInstance(); + initAppInstance: appInstance = new(); if (!appInstance.IsFirst) { //Console.WriteLine("ApplicationInstance.SendMessage(string.Empty);"); - if (ApplicationInstance.SendMessage(string.Empty)) + if (IApplication.SingletonInstance.SendMessage(string.Empty)) { return; } else { if (!isInitAppInstanceReset && - ApplicationInstance.TryKillCurrentAllProcess()) + IApplication.SingletonInstance.TryKillCurrentAllProcess()) { isInitAppInstanceReset = true; appInstance.Dispose(); @@ -126,12 +126,12 @@ namespace System.Application.UI devtools.AddOption(new Option("-use_opengl", () => false, "使用 OpenGL(仅 Windows)")); devtools.Handler = CommandHandler.Create((bool disable_gpu, bool use_opengl) => { - AppHelper.EnableDevtools = true; - AppHelper.DisableGPU = disable_gpu; - AppHelper.UseOpenGL = use_opengl; + IApplication.EnableDevtools = true; + IApplication.DisableGPU = disable_gpu; + IApplication.UseOpenGL = use_opengl; MainHandlerByCLT_(onInitStartuped: () => { - AppHelper.LoggerMinLevel = LogLevel.Debug; + IApplication.LoggerMinLevel = LogLevel.Debug; }); }); rootCommand.AddCommand(devtools); @@ -173,7 +173,7 @@ namespace System.Application.UI if (!silence) { Startup.Init(DILevel.GUI | DILevel.Steam | DILevel.HttpClientFactory); - IDesktopWindowViewModelManager.Instance.InitUnlockAchievement(id); + IViewModelManager.Instance.InitUnlockAchievement(id); BuildAvaloniaAppAndStartWithClassicDesktopLifetime(args); } else diff --git a/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs b/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs index c652633f6..bb9e0e50f 100644 --- a/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs +++ b/src/ST.Client.Desktop.Avalonia.App/NotifyIconHelper.cs @@ -72,7 +72,7 @@ namespace System.Application.UI #if WINDOWS notifyIcon.RightClick += (_, e) => { - IDesktopWindowViewModelManager.Instance.ShowTaskBarWindow(e.X, e.Y); + IViewModelManager.Instance.ShowTaskBarWindow(e.X, e.Y); }; #else menuItemDisposable = InitMenuItems(notifyIcon); @@ -107,7 +107,7 @@ namespace System.Application.UI static IDisposable? InitMenuItems(NotifyIcon notifyIcon) { #if !TRAY_INDEPENDENT_PROGRAM - if (IDesktopWindowViewModelManager.Instance.MainWindow is not MainWindowViewModel main) return null; + if (IViewModelManager.Instance.MainWindow is not MainWindowViewModel main) return null; #else MainWindowViewModel main = new(); #endif @@ -245,11 +245,11 @@ namespace System.Application.UI protected override void OnStartCore() { if (!OperatingSystem.IsLinux()) return; - var fileName = AppHelper.ProgramPath + "_LinuxTrayIcon"; + var fileName = IApplication.ProgramPath + "_LinuxTrayIcon"; - var unixSetFileAccessResult = IDesktopPlatformService.Instance.UnixSetFileAccess(fileName, IDesktopPlatformService.UnixPermission.Combined755); + var unixSetFileAccessResult = IPlatformService.Instance.UnixSetFileAccess(fileName, IPlatformService.UnixPermission.Combined755); - if (unixSetFileAccessResult != IDesktopPlatformService.UnixSetFileAccessResult.Success) + if (unixSetFileAccessResult != IPlatformService.UnixSetFileAccessResult.Success) return; Process pipeClient = new(); diff --git a/src/ST.Client.Desktop.Avalonia.App/Program.BuildAvaloniaApp.cs b/src/ST.Client.Desktop.Avalonia.App/Program.BuildAvaloniaApp.cs index 1a894f4af..6f3218ed5 100644 --- a/src/ST.Client.Desktop.Avalonia.App/Program.BuildAvaloniaApp.cs +++ b/src/ST.Client.Desktop.Avalonia.App/Program.BuildAvaloniaApp.cs @@ -1,7 +1,8 @@ using Avalonia; using Avalonia.ReactiveUI; -using System.Application.Models.Settings; +using System.Application.Settings; using System.Application.Services; +using System.Reflection; namespace System.Application.UI { @@ -14,8 +15,10 @@ namespace System.Application.UI static AppBuilder BuildAvaloniaApp() { #if DEBUG - if (Reflection.Assembly.GetCallingAssembly() != Reflection.Assembly.GetExecutingAssembly()) + if (Assembly.GetCallingAssembly() != Assembly.GetExecutingAssembly()) + { FileSystemDesktop.InitFileSystem(); + } #endif SettingsHost.Load(); var builder = AppBuilder.Configure() @@ -26,12 +29,12 @@ namespace System.Application.UI { builder.With(new AvaloniaNativePlatformOptions { - UseGpu = !AppHelper.DisableGPU && GeneralSettings.UseGPURendering.Value + UseGpu = !IApplication.DisableGPU && GeneralSettings.UseGPURendering.Value }); } else if (OperatingSystem2.IsWindows) { - var useOpenGL = AppHelper.UseOpenGL || GeneralSettings.UseOpenGL.Value; + var useOpenGL = IApplication.UseOpenGL || GeneralSettings.UseOpenGL.Value; var options = new Win32PlatformOptions { UseWindowsUIComposition = true, diff --git a/src/ST.Client.Desktop.Avalonia.App/Program.cs b/src/ST.Client.Desktop.Avalonia.App/Program.cs index ff4bcc9fb..498bbddd0 100644 --- a/src/ST.Client.Desktop.Avalonia.App/Program.cs +++ b/src/ST.Client.Desktop.Avalonia.App/Program.cs @@ -36,7 +36,7 @@ namespace System.Application.UI IsMainProcess = args.Length == 0; IsCLTProcess = !IsMainProcess && args.FirstOrDefault() == "-clt"; - AppHelper.InitLogDir(); + IApplication.InitLogDir(); #if StartupTrace StartupTrace.Restart("InitLogDir"); #endif diff --git a/src/ST.Client.Desktop.Avalonia.App/ST.Client.Desktop.Avalonia.App.csproj b/src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj similarity index 97% rename from src/ST.Client.Desktop.Avalonia.App/ST.Client.Desktop.Avalonia.App.csproj rename to src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj index eec88153c..e6493f211 100644 --- a/src/ST.Client.Desktop.Avalonia.App/ST.Client.Desktop.Avalonia.App.csproj +++ b/src/ST.Client.Desktop.Avalonia.App/ST.Client.Avalonia.App.csproj @@ -79,8 +79,7 @@ - - + @@ -89,7 +88,7 @@ --> - + PreserveNewest @@ -100,11 +99,11 @@ --> - + - + - net6.0 + net6.0 System.Application System.Application.SteamTools.Client.Desktop.Mac @@ -76,11 +76,6 @@ - - - - - @@ -88,4 +83,7 @@ + + + \ No newline at end of file diff --git a/src/ST.Client.Desktop.Mac/ServiceCollectionExtensions.cs b/src/ST.Client.Desktop.Mac/ServiceCollectionExtensions.cs index bb63ce9de..d4bc6c232 100644 --- a/src/ST.Client.Desktop.Mac/ServiceCollectionExtensions.cs +++ b/src/ST.Client.Desktop.Mac/ServiceCollectionExtensions.cs @@ -10,17 +10,15 @@ namespace Microsoft.Extensions.DependencyInjection { public static partial class ServiceCollectionExtensions { - public static IServiceCollection AddDesktopPlatformService(this IServiceCollection services, bool hasSteam, bool hasGUI, bool hasNotifyIcon) + public static IServiceCollection AddPlatformService(this IServiceCollection services, bool hasSteam, bool hasGUI, bool hasNotifyIcon) { if (OperatingSystem2.IsMacOS) { - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(AppDelegate.Instance!); - services.AddSingleton(); - services.AddSingleton(s => s.GetRequiredService()); - services.AddSingleton(s => s.GetRequiredService()); - services.AddSingleton(s => s.GetRequiredService()); - //services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(s => s.GetRequiredService()); + services.AddSingleton(s => s.GetRequiredService()); if (hasNotifyIcon) services.AddNotifyIcon(); } else diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/PlatformHttpPlatformHelper.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacClientHttpPlatformHelperServiceImpl.cs similarity index 99% rename from src/ST.Client.Desktop.Mac/Services/Implementation/PlatformHttpPlatformHelper.cs rename to src/ST.Client.Desktop.Mac/Services/Implementation/MacClientHttpPlatformHelperServiceImpl.cs index 5adc46231..7be9f6c0a 100644 --- a/src/ST.Client.Desktop.Mac/Services/Implementation/PlatformHttpPlatformHelper.cs +++ b/src/ST.Client.Desktop.Mac/Services/Implementation/MacClientHttpPlatformHelperServiceImpl.cs @@ -11,7 +11,7 @@ using SystemConfiguration; namespace System.Application.Services.Implementation { - internal sealed class PlatformHttpPlatformHelper : DesktopHttpPlatformHelper + internal sealed class MacClientHttpPlatformHelperServiceImpl : ClientHttpPlatformHelperServiceImpl { static readonly Lazy mUserAgent = new(() => { diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.OpenDesktopIconsSettings.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.OpenDesktopIconsSettings.cs deleted file mode 100644 index 14938e8c0..000000000 --- a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.OpenDesktopIconsSettings.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace System.Application.Services.Implementation -{ - partial class MacDesktopPlatformServiceImpl - { - public void OpenDesktopIconsSettings() - { - } - - public void OpenGameControllers() - { - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.IEmailPlatformService.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IEmailPlatformService.cs similarity index 93% rename from src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.IEmailPlatformService.cs rename to src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IEmailPlatformService.cs index a2a836053..b1c1b2833 100644 --- a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.IEmailPlatformService.cs +++ b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IEmailPlatformService.cs @@ -10,7 +10,7 @@ using Xamarin.Essentials; namespace System.Application.Services.Implementation { - partial class MacDesktopPlatformServiceImpl : IEmailPlatformService + partial class MacPlatformServiceImpl : IEmailPlatformService { // https://github.com/xamarin/Essentials/blob/main/Xamarin.Essentials/Email/Email.macos.cs diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.IFilePickerPlatformService.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IFilePickerPlatformService.cs similarity index 96% rename from src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.IFilePickerPlatformService.cs rename to src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IFilePickerPlatformService.cs index a8ef2ffe8..a81d495cb 100644 --- a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.IFilePickerPlatformService.cs +++ b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IFilePickerPlatformService.cs @@ -7,7 +7,7 @@ //namespace System.Application.Services.Implementation //{ -// partial class MacDesktopPlatformServiceImpl : IOpenFileDialogService +// partial class MacPlatformServiceImpl : IOpenFileDialogService // { // // https://github.com/xamarin/Essentials/blob/main/Xamarin.Essentials/FilePicker/FilePicker.macos.cs diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IsAdministrator.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IsAdministrator.cs new file mode 100644 index 000000000..ff38d85a7 --- /dev/null +++ b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.IsAdministrator.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace System.Application.Services.Implementation +{ + partial class MacPlatformServiceImpl + { + static readonly Lazy mIsAdministrator = new(IsAdministrator_); + + static bool IsAdministrator_() => string.Equals(Environment.UserName, "root", StringComparison.OrdinalIgnoreCase); + + /// + /// 是否是管理员权限 + /// + /// + public static bool IsAdministrator => mIsAdministrator.Value; + + bool IPlatformService.IsAdministrator => IsAdministrator; + } +} diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.cs similarity index 96% rename from src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs rename to src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.cs index 3e7ac94fe..7bd448103 100644 --- a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs +++ b/src/ST.Client.Desktop.Mac/Services/Implementation/MacPlatformServiceImpl.cs @@ -12,16 +12,16 @@ using System.IO; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; -using System.Windows; namespace System.Application.Services.Implementation { - internal sealed partial class MacDesktopPlatformServiceImpl : IDesktopPlatformService + internal sealed partial class MacPlatformServiceImpl : IPlatformService { + const string TAG = "MacPlatformS"; public const string TextEdit = "TextEdit"; public const string VSC = "Visual Studio Code"; - public void SetResizeMode(IntPtr hWnd, ResizeModeCompat value) + public void SetResizeMode(IntPtr hWnd, ResizeMode value) { } @@ -178,7 +178,7 @@ namespace System.Application.Services.Implementation #endregion - static readonly Lazy<(byte[] key, byte[] iv)> mMachineSecretKey = IDesktopPlatformService.GetMachineSecretKey(GetMachineSecretKey); + static readonly Lazy<(byte[] key, byte[] iv)> mMachineSecretKey = IPlatformService.GetMachineSecretKey(GetMachineSecretKey); public (byte[] key, byte[] iv) MachineSecretKey => mMachineSecretKey.Value; @@ -218,8 +218,6 @@ namespace System.Application.Services.Implementation return null; } - public bool IsAdministrator => false; - public void UnelevatedProcessStart(string cmdArgs) { throw new PlatformNotSupportedException(); diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/SystemJumpListServiceImpl.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/SystemJumpListServiceImpl.cs deleted file mode 100644 index 3fb2ef10b..000000000 --- a/src/ST.Client.Desktop.Mac/Services/Implementation/SystemJumpListServiceImpl.cs +++ /dev/null @@ -1,13 +0,0 @@ -//namespace System.Application.Services.Implementation -//{ -// internal sealed class SystemJumpListServiceImpl : ISystemJumpListService -// { -// public void InitJumpList() -// { -// } - -// public void AddJumpTask(string title, string applicationPath, string iconResourcePath, string arguments = "", string description = "", string customCategory = "") -// { -// } -// } -//} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Extensions/RegistryKeyExtensions.cs b/src/ST.Client.Desktop.Windows/Extensions/RegistryKeyExtensions.cs index fe8c67102..36eccd2e4 100644 --- a/src/ST.Client.Desktop.Windows/Extensions/RegistryKeyExtensions.cs +++ b/src/ST.Client.Desktop.Windows/Extensions/RegistryKeyExtensions.cs @@ -1,4 +1,4 @@ -using Microsoft.Win32; +using Microsoft.Win32; using System.Runtime.Versioning; // ReSharper disable once CheckNamespace @@ -46,23 +46,4 @@ namespace System } } } - -#if DEBUG - - [Obsolete("use RegistryKeyExtensions", true)] - public class RegistryKeyService - { - [Obsolete("use registryKey.Read", true)] - public string ReadRegistryKey(RegistryKey registryKey, string path, string key) - { - return string.Empty; - } - - [Obsolete("use registryKey.AddOrUpdate", true)] - public void AddOrUpdateRegistryKey(RegistryKey registryKey, string path, string key, string value, RegistryValueKind registryValueKind) - { - } - } - -#endif } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/DWMApi.cs b/src/ST.Client.Desktop.Windows/Internals/DWMApi.cs index 3909654eb..bc1e75eee 100644 --- a/src/ST.Client.Desktop.Windows/Internals/DWMApi.cs +++ b/src/ST.Client.Desktop.Windows/Internals/DWMApi.cs @@ -1,47 +1,40 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -namespace System +static class DWMApi { - static class DWMApi - { - public const int DWM_TNP_VISIBLE = 0x8, - DWM_TNP_OPACITY = 0x4, - DWM_TNP_RECTDESTINATION = 0x1; + public const int DWM_TNP_VISIBLE = 0x8, + DWM_TNP_OPACITY = 0x4, + DWM_TNP_RECTDESTINATION = 0x1; - const string DllName = "dwmapi"; - [DllImport(DllName, CharSet = CharSet.Auto)] - public static extern int DwmRegisterThumbnail(IntPtr dest, IntPtr src, out IntPtr thumb); + const string DllName = "dwmapi"; + [DllImport(DllName, CharSet = CharSet.Auto)] + public static extern int DwmRegisterThumbnail(IntPtr dest, IntPtr src, out IntPtr thumb); - [DllImport(DllName, CharSet = CharSet.Auto)] - public static extern int DwmUnregisterThumbnail(IntPtr thumb); + [DllImport(DllName, CharSet = CharSet.Auto)] + public static extern int DwmUnregisterThumbnail(IntPtr thumb); - [DllImport(DllName, CharSet = CharSet.Auto)] - public static extern int DwmQueryThumbnailSourceSize(IntPtr thumb, out PSIZE size); + [DllImport(DllName, CharSet = CharSet.Auto)] + public static extern int DwmQueryThumbnailSourceSize(IntPtr thumb, out PSIZE size); - [DllImport(DllName, CharSet = CharSet.Auto)] - public static extern int DwmUpdateThumbnailProperties(IntPtr hThumb, ref DWM_THUMBNAIL_PROPERTIES props); - } + [DllImport(DllName, CharSet = CharSet.Auto)] + public static extern int DwmUpdateThumbnailProperties(IntPtr hThumb, ref DWM_THUMBNAIL_PROPERTIES props); +} - [StructLayout(LayoutKind.Sequential)] - struct DWM_THUMBNAIL_PROPERTIES - { - public int dwFlags; - public RECT rcDestination; - public RECT rcSource; - public byte opacity; - public bool fVisible; - public bool fSourceClientAreaOnly; - } +[StructLayout(LayoutKind.Sequential)] +struct DWM_THUMBNAIL_PROPERTIES +{ + public int dwFlags; + public RECT rcDestination; + public RECT rcSource; + public byte opacity; + public bool fVisible; + public bool fSourceClientAreaOnly; +} - [StructLayout(LayoutKind.Sequential)] - struct PSIZE - { - public int x; - public int y; - } +[StructLayout(LayoutKind.Sequential)] +struct PSIZE +{ + public int x; + public int y; } diff --git a/src/ST.Client.Desktop.Windows/Internals/Models/Enum/WindowLongFlags.cs b/src/ST.Client.Desktop.Windows/Internals/Models/Enum/WindowLongFlags.cs deleted file mode 100644 index 26c408694..000000000 --- a/src/ST.Client.Desktop.Windows/Internals/Models/Enum/WindowLongFlags.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System -{ - [Flags] - public enum WindowLongFlags - { - GWL_STYLE = -16, - GWL_EXSTYLE = -20, - WS_EX_NOACTIVATE = 0x8000000, - } -} diff --git a/src/ST.Client.Desktop.Windows/Internals/MouseHook.cs b/src/ST.Client.Desktop.Windows/Internals/MouseHook.cs index b55c52908..c060837b0 100644 --- a/src/ST.Client.Desktop.Windows/Internals/MouseHook.cs +++ b/src/ST.Client.Desktop.Windows/Internals/MouseHook.cs @@ -1,168 +1,166 @@ -using System.ComponentModel; +using System.ComponentModel; using System.Diagnostics; using System.Runtime.InteropServices; -using System.Windows; +using System; +using PointDouble = System.Windows.Point; +using PointInt32 = System.Drawing.Point; -// ReSharper disable once CheckNamespace -namespace System +static class MouseHook { - internal static class MouseHook + delegate int HookProc(int nCode, int wParam, IntPtr lParam); + + static int _mouseHookHandle; + static HookProc? _mouseDelegate; + + static event MouseUpEventHandler? MouseUp; + + public static event MouseUpEventHandler OnMouseUp { - delegate int HookProc(int nCode, int wParam, IntPtr lParam); - - static int _mouseHookHandle; - static HookProc? _mouseDelegate; - - static event MouseUpEventHandler? MouseUp; - - public static event MouseUpEventHandler OnMouseUp + add { - add - { - Subscribe(); - MouseUp += value; - } - remove - { - MouseUp -= value; - Unsubscribe(); - } + Subscribe(); + MouseUp += value; } - - static void Unsubscribe() + remove { - if (_mouseHookHandle != 0) - { - int result = UnhookWindowsHookEx(_mouseHookHandle); - _mouseHookHandle = 0; - _mouseDelegate = null; - if (result == 0) - { - int errorCode = Marshal.GetLastWin32Error(); - throw new Win32Exception(errorCode); - } - } + MouseUp -= value; + Unsubscribe(); } - - static void Subscribe() - { - if (_mouseHookHandle == 0) - { - var currentProcessMainModuleName = Process.GetCurrentProcess().MainModule?.ModuleName; - if (string.IsNullOrWhiteSpace(currentProcessMainModuleName)) throw new ArgumentNullException(nameof(currentProcessMainModuleName)); - _mouseDelegate = MouseHookProc; - _mouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, - _mouseDelegate, - GetModuleHandle(currentProcessMainModuleName), - 0); - if (_mouseHookHandle == 0) - { - int errorCode = Marshal.GetLastWin32Error(); - throw new Win32Exception(errorCode); - } - } - } - - static int MouseHookProc(int nCode, int wParam, IntPtr lParam) - { - if (nCode >= 0) - { - var mouseHookStructObj = Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)); - if (mouseHookStructObj == null) throw new ArgumentNullException(nameof(mouseHookStructObj)); - var mouseHookStruct = (MSLLHOOKSTRUCT)mouseHookStructObj; - if (wParam == WM_LBUTTONUP) - { - if (MouseUp != null) - { - MouseUp.Invoke(null, new PointDouble(mouseHookStruct.pt.X, mouseHookStruct.pt.Y)); - } - } - } - return CallNextHookEx(_mouseHookHandle, nCode, wParam, lParam); - } - - const int WH_MOUSE_LL = 14; - const int WM_LBUTTONUP = 0x0202; - - [StructLayout(LayoutKind.Sequential)] - struct MSLLHOOKSTRUCT - { - public PointInt32 pt; - public uint mouseData; - public uint flags; - public uint time; - public IntPtr dwExtraInfo; - } - - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr GetModuleHandle(string name); - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, - CallingConvention = CallingConvention.StdCall, SetLastError = true)] - static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId); - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, - CallingConvention = CallingConvention.StdCall, SetLastError = true)] - static extern int UnhookWindowsHookEx(int idHook); - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, - CallingConvention = CallingConvention.StdCall)] - static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto)] - public static extern IntPtr LoadCursor(IntPtr hInstance, uint lpCursorName); - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto)] - public static extern bool SetSystemCursor(IntPtr hcur, uint id); - - public const uint OCR_NORMAL = 32512; - public const uint OCR_IBEAM = 32513; - public const uint OCR_CROSS = 32515; - public const uint OCR_HAND = 32649; - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto)] - public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, - IntPtr pvParam, uint fWinIni); - - public enum SystemParametersDesktopInfo : uint - { - SPIF_SENDWININICHANGE = 2, - SPI_SETDESKWALLPAPER = 20, - SPI_SETDESKPATTERN = 21, - SPI_SETWORKAREA = 47, - SPI_GETWORKAREA = 48, - SPI_GETFONTSMOOTHING = 74, - SPI_SETFONTSMOOTHING = 75, - SPI_SETCURSORS = 87, - SPI_GETDESKWALLPAPER = 115, - SPI_GETFLATMENU = 4130, - SPI_SETFLATMENU = 4131, - SPI_GETDROPSHADOW = 4132, - SPI_SETDROPSHADOW = 4133, - SPI_GETCLEARTYPE = 4168, - SPI_SETCLEARTYPE = 4169, - SPI_GETFONTSMOOTHINGTYPE = 8202, - SPI_SETFONTSMOOTHINGTYPE = 8203, - SPI_GETFONTSMOOTHINGCONTRAST = 8204, - SPI_SETFONTSMOOTHINGCONTRAST = 8205, - SPI_GETFONTSMOOTHINGORIENTATION = 8210, - SPI_SETFONTSMOOTHINGORIENTATION = 8211 - } - [Flags] - public enum SystemParamtersInfoFlags : uint - { - None = 0, - SPIF_UPDATEINIFILE = 1, - SPIF_SENDCHANGE = 2, - SPIF_SENDWININICHANGE = 2 - } - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, EntryPoint = "GetCursorPos")] - public static extern bool GetCursorPos(out PointInt32 pt); - - [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, EntryPoint = "WindowFromPoint")] - public static extern IntPtr WindowFromPoint(PointInt32 pt); } - internal delegate void MouseUpEventHandler(object? sender, PointDouble p); -} \ No newline at end of file + static void Unsubscribe() + { + if (_mouseHookHandle != 0) + { + int result = UnhookWindowsHookEx(_mouseHookHandle); + _mouseHookHandle = 0; + _mouseDelegate = null; + if (result == 0) + { + int errorCode = Marshal.GetLastWin32Error(); + throw new Win32Exception(errorCode); + } + } + } + + static void Subscribe() + { + if (_mouseHookHandle == 0) + { + var currentProcessMainModuleName = Process.GetCurrentProcess().MainModule?.ModuleName; + if (string.IsNullOrWhiteSpace(currentProcessMainModuleName)) throw new ArgumentNullException(nameof(currentProcessMainModuleName)); + _mouseDelegate = MouseHookProc; + _mouseHookHandle = SetWindowsHookEx(WH_MOUSE_LL, + _mouseDelegate, + GetModuleHandle(currentProcessMainModuleName), + 0); + if (_mouseHookHandle == 0) + { + int errorCode = Marshal.GetLastWin32Error(); + throw new Win32Exception(errorCode); + } + } + } + + static int MouseHookProc(int nCode, int wParam, IntPtr lParam) + { + if (nCode >= 0) + { + var mouseHookStructObj = Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT)); + if (mouseHookStructObj == null) throw new ArgumentNullException(nameof(mouseHookStructObj)); + var mouseHookStruct = (MSLLHOOKSTRUCT)mouseHookStructObj; + if (wParam == WM_LBUTTONUP) + { + if (MouseUp != null) + { + MouseUp.Invoke(null, new PointDouble(mouseHookStruct.pt.X, mouseHookStruct.pt.Y)); + } + } + } + return CallNextHookEx(_mouseHookHandle, nCode, wParam, lParam); + } + + const int WH_MOUSE_LL = 14; + const int WM_LBUTTONUP = 0x0202; + + [StructLayout(LayoutKind.Sequential)] + struct MSLLHOOKSTRUCT + { + public PointInt32 pt; + public uint mouseData; + public uint flags; + public uint time; + public IntPtr dwExtraInfo; + } + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr GetModuleHandle(string name); + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall, SetLastError = true)] + static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, int dwThreadId); + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall, SetLastError = true)] + static extern int UnhookWindowsHookEx(int idHook); + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, + CallingConvention = CallingConvention.StdCall)] + static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam); + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto)] + public static extern IntPtr LoadCursor(IntPtr hInstance, uint lpCursorName); + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto)] + public static extern bool SetSystemCursor(IntPtr hcur, uint id); + + public const uint OCR_NORMAL = 32512; + public const uint OCR_IBEAM = 32513; + public const uint OCR_CROSS = 32515; + public const uint OCR_HAND = 32649; + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto)] + public static extern bool SystemParametersInfo(uint uiAction, uint uiParam, + IntPtr pvParam, uint fWinIni); + + public enum SystemParametersDesktopInfo : uint + { + SPIF_SENDWININICHANGE = 2, + SPI_SETDESKWALLPAPER = 20, + SPI_SETDESKPATTERN = 21, + SPI_SETWORKAREA = 47, + SPI_GETWORKAREA = 48, + SPI_GETFONTSMOOTHING = 74, + SPI_SETFONTSMOOTHING = 75, + SPI_SETCURSORS = 87, + SPI_GETDESKWALLPAPER = 115, + SPI_GETFLATMENU = 4130, + SPI_SETFLATMENU = 4131, + SPI_GETDROPSHADOW = 4132, + SPI_SETDROPSHADOW = 4133, + SPI_GETCLEARTYPE = 4168, + SPI_SETCLEARTYPE = 4169, + SPI_GETFONTSMOOTHINGTYPE = 8202, + SPI_SETFONTSMOOTHINGTYPE = 8203, + SPI_GETFONTSMOOTHINGCONTRAST = 8204, + SPI_SETFONTSMOOTHINGCONTRAST = 8205, + SPI_GETFONTSMOOTHINGORIENTATION = 8210, + SPI_SETFONTSMOOTHINGORIENTATION = 8211 + } + [Flags] + public enum SystemParamtersInfoFlags : uint + { + None = 0, + SPIF_UPDATEINIFILE = 1, + SPIF_SENDCHANGE = 2, + SPIF_SENDWININICHANGE = 2 + } + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, EntryPoint = "GetCursorPos")] + public static extern bool GetCursorPos(out PointInt32 pt); + + [DllImport(User32Window.LibraryName, CharSet = CharSet.Auto, EntryPoint = "WindowFromPoint")] + public static extern IntPtr WindowFromPoint(PointInt32 pt); +} + +delegate void MouseUpEventHandler(object? sender, PointDouble p); \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs b/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs index fd13d601e..f5442fc11 100644 --- a/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs +++ b/src/ST.Client.Desktop.Windows/Internals/NativeMethods.cs @@ -1,67 +1,64 @@ +using System; using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; -// ReSharper disable once CheckNamespace -namespace System +static partial class NativeMethods { - internal static partial class NativeMethods + [DllImport("Avrt.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr AvSetMmThreadCharacteristics(string taskName, ref uint taskIndex); + + [DllImport("psapi.dll", CharSet = CharSet.Unicode)] + public static extern uint GetProcessImageFileName( + IntPtr hProcess, + [Out] StringBuilder lpImageFileName, + [In][MarshalAs(UnmanagedType.U4)] int nSize + ); + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] int dwFlags, [Out] StringBuilder lpExeName, ref int lpdwSize); + + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr OpenProcess( + uint processAccess, + bool bInheritHandle, + int processId + ); + public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags) { - [DllImport("Avrt.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr AvSetMmThreadCharacteristics(string taskName, ref uint taskIndex); - - [DllImport("psapi.dll", CharSet = CharSet.Unicode)] - public static extern uint GetProcessImageFileName( - IntPtr hProcess, - [Out] StringBuilder lpImageFileName, - [In][MarshalAs(UnmanagedType.U4)] int nSize - ); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] int dwFlags, [Out] StringBuilder lpExeName, ref int lpdwSize); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr OpenProcess( - uint processAccess, - bool bInheritHandle, - int processId - ); - public static IntPtr OpenProcess(Process proc, ProcessAccessFlags flags) - { - return OpenProcess((uint)flags, false, proc.Id); - } - - public static string QueryFullProcessImageName(Process process) - { - int capacity = 1024; - StringBuilder sb = new StringBuilder(capacity); - IntPtr handle = OpenProcess(process, ProcessAccessFlags.QueryLimitedInformation); - QueryFullProcessImageName(handle, 0, sb, ref capacity); - string fullPath = sb.ToString(0, capacity); - return fullPath; - } - - [Flags] - public enum ProcessAccessFlags : uint - { - All = 0x001F0FFF, - Terminate = 0x00000001, - CreateThread = 0x00000002, - VirtualMemoryOperation = 0x00000008, - VirtualMemoryRead = 0x00000010, - VirtualMemoryWrite = 0x00000020, - DuplicateHandle = 0x00000040, - CreateProcess = 0x000000080, - SetQuota = 0x00000100, - SetInformation = 0x00000200, - QueryInformation = 0x00000400, - QueryLimitedInformation = 0x00001000, - Synchronize = 0x00100000 - } - - [DllImport("kernel32.dll")] - [ResourceExposure(ResourceScope.None)] - public static extern int GetACP(); + return OpenProcess((uint)flags, false, proc.Id); } + + public static string QueryFullProcessImageName(Process process) + { + int capacity = 1024; + StringBuilder sb = new StringBuilder(capacity); + IntPtr handle = OpenProcess(process, ProcessAccessFlags.QueryLimitedInformation); + QueryFullProcessImageName(handle, 0, sb, ref capacity); + string fullPath = sb.ToString(0, capacity); + return fullPath; + } + + [Flags] + public enum ProcessAccessFlags : uint + { + All = 0x001F0FFF, + Terminate = 0x00000001, + CreateThread = 0x00000002, + VirtualMemoryOperation = 0x00000008, + VirtualMemoryRead = 0x00000010, + VirtualMemoryWrite = 0x00000020, + DuplicateHandle = 0x00000040, + CreateProcess = 0x000000080, + SetQuota = 0x00000100, + SetInformation = 0x00000200, + QueryInformation = 0x00000400, + QueryLimitedInformation = 0x00001000, + Synchronize = 0x00100000 + } + + [DllImport("kernel32.dll")] + [ResourceExposure(ResourceScope.None)] + public static extern int GetACP(); } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/NativeWindow.cs b/src/ST.Client.Desktop.Windows/Internals/NativeWindow.cs index dd75dc2a9..35d30b2e1 100644 --- a/src/ST.Client.Desktop.Windows/Internals/NativeWindow.cs +++ b/src/ST.Client.Desktop.Windows/Internals/NativeWindow.cs @@ -1,82 +1,79 @@ +using System; using System.ComponentModel; using System.Runtime.InteropServices; -// ReSharper disable once CheckNamespace -namespace System +/// +/// A native Win32 window encapsulation for receiving window messages. +/// +class NativeWindow { + readonly UnmanagedMethods.WndProc _wndProc; + readonly string _className = "NativeHelperWindow" + Guid.NewGuid(); + /// - /// A native Win32 window encapsulation for receiving window messages. + /// The window handle of the underlying native window. /// - internal class NativeWindow + public IntPtr Handle { get; set; } + + /// + /// Creates a new native (Win32) helper window for receiving window messages. + /// + public NativeWindow() { - readonly UnmanagedMethods.WndProc _wndProc; - readonly string _className = "NativeHelperWindow" + Guid.NewGuid(); + // We need to store the window proc as a field so that + // it doesn't get garbage collected away. + _wndProc = new UnmanagedMethods.WndProc(WndProc); - /// - /// The window handle of the underlying native window. - /// - public IntPtr Handle { get; set; } - - /// - /// Creates a new native (Win32) helper window for receiving window messages. - /// - public NativeWindow() + UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX { - // We need to store the window proc as a field so that - // it doesn't get garbage collected away. - _wndProc = new UnmanagedMethods.WndProc(WndProc); + cbSize = Marshal.SizeOf(), + lpfnWndProc = _wndProc, + hInstance = UnmanagedMethods.GetModuleHandle(null), + lpszClassName = _className + }; - UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX - { - cbSize = Marshal.SizeOf(), - lpfnWndProc = _wndProc, - hInstance = UnmanagedMethods.GetModuleHandle(null), - lpszClassName = _className - }; + ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx); - ushort atom = UnmanagedMethods.RegisterClassEx(ref wndClassEx); - - if (atom == 0) - { - throw new Win32Exception(); - } - - Handle = UnmanagedMethods.CreateWindowEx(0, atom, null, UnmanagedMethods.WS_POPUP, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); - - if (Handle == IntPtr.Zero) - { - throw new Win32Exception(); - } + if (atom == 0) + { + throw new Win32Exception(); } - /// - /// Destructs the object and destroys the native window. - /// - ~NativeWindow() - { - if (Handle != IntPtr.Zero) - { - UnmanagedMethods.PostMessage(Handle, (uint)UnmanagedMethods.WindowsMessage.WM_DESTROY, IntPtr.Zero, IntPtr.Zero); - } - } + Handle = UnmanagedMethods.CreateWindowEx(0, atom, null, UnmanagedMethods.WS_POPUP, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); - /// - /// This function will receive all the system window messages relevant to our window. - /// - protected virtual IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + if (Handle == IntPtr.Zero) { - switch (msg) - { - case (uint)UnmanagedMethods.WindowsMessage.WM_CLOSE: - UnmanagedMethods.DestroyWindow(hWnd); - break; - case (uint)UnmanagedMethods.WindowsMessage.WM_DESTROY: - UnmanagedMethods.PostQuitMessage(0); - break; - default: - return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); - } - return IntPtr.Zero; + throw new Win32Exception(); } } + + /// + /// Destructs the object and destroys the native window. + /// + ~NativeWindow() + { + if (Handle != IntPtr.Zero) + { + UnmanagedMethods.PostMessage(Handle, (uint)UnmanagedMethods.WindowsMessage.WM_DESTROY, IntPtr.Zero, IntPtr.Zero); + } + } + + /// + /// This function will receive all the system window messages relevant to our window. + /// + protected virtual IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + { + switch (msg) + { + case (uint)UnmanagedMethods.WindowsMessage.WM_CLOSE: + UnmanagedMethods.DestroyWindow(hWnd); + break; + case (uint)UnmanagedMethods.WindowsMessage.WM_DESTROY: + UnmanagedMethods.PostQuitMessage(0); + break; + default: + return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); + } + return IntPtr.Zero; + } } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/Point.cs b/src/ST.Client.Desktop.Windows/Internals/Point.cs deleted file mode 100644 index ed4d3bca7..000000000 --- a/src/ST.Client.Desktop.Windows/Internals/Point.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Runtime.InteropServices; - -// ReSharper disable once CheckNamespace -namespace System -{ - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct PointInt32 - { - public int X; - public int Y; - - public PointInt32(int x, int y) - { - X = x; - Y = y; - } - } - - [Serializable] - public struct PointDouble - { - public double X { get; set; } - - public double Y { get; set; } - - public PointDouble(double x, double y) - { - X = x; - Y = y; - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/RECT.cs b/src/ST.Client.Desktop.Windows/Internals/RECT.cs index 345e603df..f0f30843d 100644 --- a/src/ST.Client.Desktop.Windows/Internals/RECT.cs +++ b/src/ST.Client.Desktop.Windows/Internals/RECT.cs @@ -1,26 +1,22 @@ using System.Runtime.InteropServices; -// ReSharper disable once CheckNamespace -namespace System +[StructLayout(LayoutKind.Sequential)] +internal struct RECT { - [StructLayout(LayoutKind.Sequential)] - struct RECT + public RECT(int left, int top, int right, int bottom) { - public RECT(int left, int top, int right, int bottom) - { - Left = left; - Top = top; - Right = right; - Bottom = bottom; - } - - public int Left; - public int Top; - public int Right; - public int Bottom; - - public int Width => Right - Left; - - public int Height => Bottom - Top; + Left = left; + Top = top; + Right = right; + Bottom = bottom; } + + public int Left; + public int Top; + public int Right; + public int Bottom; + + public int Width => Right - Left; + + public int Height => Bottom - Top; } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/TokenizerHelper.cs b/src/ST.Client.Desktop.Windows/Internals/TokenizerHelper.cs new file mode 100644 index 000000000..acaa56585 --- /dev/null +++ b/src/ST.Client.Desktop.Windows/Internals/TokenizerHelper.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// https://github.com/dotnet/wpf/blob/v6.0.0-rc.2.21501.7/src/Microsoft.DotNet.Wpf/src/Shared/MS/Internal/TokenizerHelper.cs +// +// Description: This file contains the implementation of TokenizerHelper. +// This class should be used by most - if not all - MIL parsers. +// + +using System; +using System.Diagnostics; +using System.Globalization; + +// ReSharper disable once CheckNamespace +namespace MS.Internal +{ + static class TokenizerHelper + { + // Helper to get the numeric list separator for a given IFormatProvider. + // Separator is a comma [,] if the decimal separator is not a comma, or a semicolon [;] otherwise. + static internal char GetNumericListSeparator(IFormatProvider provider) + { + char numericSeparator = ','; + + // Get the NumberFormatInfo out of the provider, if possible + // If the IFormatProvider doesn't not contain a NumberFormatInfo, then + // this method returns the current culture's NumberFormatInfo. + NumberFormatInfo numberFormat = NumberFormatInfo.GetInstance(provider); + + Debug.Assert(null != numberFormat); + + // Is the decimal separator is the same as the list separator? + // If so, we use the ";". + if ((numberFormat.NumberDecimalSeparator.Length > 0) && (numericSeparator == numberFormat.NumberDecimalSeparator[0])) + { + numericSeparator = ';'; + } + + return numericSeparator; + } + } +} diff --git a/src/ST.Client.Desktop.Windows/Internals/UnmanagedMethods.cs b/src/ST.Client.Desktop.Windows/Internals/UnmanagedMethods.cs index 52cdba278..c0950b196 100644 --- a/src/ST.Client.Desktop.Windows/Internals/UnmanagedMethods.cs +++ b/src/ST.Client.Desktop.Windows/Internals/UnmanagedMethods.cs @@ -3,2181 +3,2174 @@ // Slightly modified and extended version for the use in SQRLDotNetClientUI +using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; -#nullable disable - -// ReSharper disable once CheckNamespace -namespace System +internal static class UnmanagedMethods { - internal static class UnmanagedMethods + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad); + + /// + /// Creates, updates or deletes the taskbar icon. + /// + [DllImport("shell32", CharSet = CharSet.Unicode)] + public static extern bool Shell_NotifyIcon(NIM cmd, NOTIFYICONDATA data); + + [DllImport("user32.dll")] + public static extern void PostQuitMessage(int nExitCode); + + [DllImport("user32.dll", ExactSpelling = true)] + public static extern bool SetForegroundWindow(IntPtr hWnd); + + [DllImport("user32.dll")] + public static extern IntPtr CreatePopupMenu(); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + public static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition, [In] ref MENUITEMINFO lpmii); + + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + public static extern bool AppendMenu(IntPtr hMenu, MenuFlags uFlags, uint uIDNewItem, string lpNewItem); + + [DllImport("user32.dll")] + public static extern uint TrackPopupMenuEx(IntPtr hmenu, UFLAGS uFlags, int x, int y, IntPtr hwnd, IntPtr lptpm); + + [DllImport("wtsapi32.dll", SetLastError = true)] + public static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] int dwFlags); + + [DllImport("wtsapi32.dll", SetLastError = true)] + public static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd); + + [DllImport("user32.dll", CharSet = CharSet.Auto)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool SystemParametersInfo(uint uAction, uint uParam, ref bool lpvParam, int fWinIni); + + [DllImport("user32.dll")] + public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); + + // constants that can be passed for the WTSRegisterSessionNotification + // dwFlags parameter + public const int NOTIFY_FOR_THIS_SESSION = 0; + public const int NOTIFY_FOR_ALL_SESSIONS = 1; + + // lParam values for WM_ENDSESSION message + public const int ENDSESSION_CLOSEAPP = 0x1; + public const int ENDSESSION_CRITICAL = 0x40000000; + public const int ENDSESSION_LOGOFF = unchecked((int)0x80000000); + + public const uint IMAGE_BITMAP = 0; + public const uint IMAGE_ICON = 1; + public const uint IMAGE_CURSOR = 2; + + public const uint LR_DEFAULTSIZE = 0x00000040; + public const uint LR_LOADFROMFILE = 0x00000010; + + public static IntPtr HWND_BROADCAST = new IntPtr(0xffff); + public static IntPtr HWND_TOP = new IntPtr(0); + public static IntPtr HWND_BOTTOM = new IntPtr(1); + public static IntPtr HWND_TOPMOST = new IntPtr(-1); + public static IntPtr HWND_NOTOPMOST = new IntPtr(-2); + public static IntPtr HWND_MESSAGE = new IntPtr(-3); + + public const uint WS_POPUP = 0x80000000; + public const uint WS_VISIBLE = 0x10000000; + + public const int WTS_CONSOLE_CONNECT = 0x1; // A session was connected to the console terminal. + public const int WTS_CONSOLE_DISCONNECT = 0x2; // A session was disconnected from the console terminal. + public const int WTS_REMOTE_CONNECT = 0x3; // A session was connected to the remote terminal. + public const int WTS_REMOTE_DISCONNECT = 0x4; // A session was disconnected from the remote terminal. + public const int WTS_SESSION_LOGON = 0x5; // A user has logged on to the session. + public const int WTS_SESSION_LOGOFF = 0x6; // A user has logged off the session. + public const int WTS_SESSION_LOCK = 0x7; // A session has been locked. + public const int WTS_SESSION_UNLOCK = 0x8; // A session has been unlocked. + public const int WTS_SESSION_REMOTE_CONTROL = 0x9; // A session has changed its remote controlled status. + + public const int PBT_APMQUERYSUSPEND = 0x0000; + public const int PBT_APMQUERYSTANDBY = 0x0001; + public const int PBT_APMQUERYSUSPENDFAILED = 0x0002; + public const int PBT_APMQUERYSTANDBYFAILED = 0x0003; + public const int PBT_APMSUSPEND = 0x0004; + public const int PBT_APMSTANDBY = 0x0005; + public const int PBT_APMRESUMECRITICAL = 0x0006; + public const int PBT_APMRESUMESUSPEND = 0x0007; + public const int PBT_APMRESUMESTANDBY = 0x0008; + public const int PBT_APMBATTERYLOW = 0x0009; + public const int PBT_APMPOWERSTATUSCHANGE = 0x000A; + public const int PBT_APMOEMEVENT = 0x000B; + + [StructLayout(LayoutKind.Sequential)] + public struct LASTINPUTINFO { - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr LoadImage(IntPtr hinst, string lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad); + public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO)); + + [MarshalAs(UnmanagedType.U4)] + public uint cbSize; + [MarshalAs(UnmanagedType.U4)] + public uint dwTime; + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public class NOTIFYICONDATA + { + public int cbSize = Marshal.SizeOf(); + public IntPtr hWnd; + public int uID; + public NIF uFlags; + public int uCallbackMessage; + public IntPtr hIcon; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + public string szTip; + public int dwState = 0; + public int dwStateMask = 0; + /// + /// String with the text for a balloon ToolTip. It can have a maximum of 255 characters. + /// To remove the ToolTip, set the NIF_INFO flag in uFlags and set szInfo to an empty string. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] + public string szInfo; + public int uTimeoutOrVersion; + /// + /// String containing a title for a balloon ToolTip. This title appears in boldface + /// above the text. It can have a maximum of 63 characters. + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] + public string szInfoTitle; + public NIIF dwInfoFlags; /// - /// Creates, updates or deletes the taskbar icon. + /// Windows Vista (Shell32.dll version 6.0.6) and later. The handle of a customized + /// balloon icon provided by the application that should be used independently + /// of the tray icon. If this member is non-NULL and the + /// flag is set, this icon is used as the balloon icon.
+ /// If this member is NULL, the legacy behavior is carried out. ///
- [DllImport("shell32", CharSet = CharSet.Unicode)] - public static extern bool Shell_NotifyIcon(NIM cmd, NOTIFYICONDATA data); + //public IntPtr CustomBalloonIconHandle; + } - [DllImport("user32.dll")] - public static extern void PostQuitMessage(int nExitCode); + public enum NIM : uint + { + ADD = 0x00000000, + MODIFY = 0x00000001, + DELETE = 0x00000002, + SETFOCUS = 0x00000003, + SETVERSION = 0x00000004 + } - [DllImport("user32.dll", ExactSpelling = true)] - public static extern bool SetForegroundWindow(IntPtr hWnd); + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public class MENUITEMINFO + { + public int cbSize = Marshal.SizeOf(typeof(MENUITEMINFO)); + public MIIM fMask; + public uint fType; + public uint fState; + public uint wID; + public IntPtr hSubMenu; + public IntPtr hbmpChecked; + public IntPtr hbmpUnchecked; + public IntPtr dwItemData; + public string dwTypeData = null; + public uint cch; // length of dwTypeData + public IntPtr hbmpItem; - [DllImport("user32.dll")] - public static extern IntPtr CreatePopupMenu(); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - public static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition, [In] ref MENUITEMINFO lpmii); - - [DllImport("user32.dll", CharSet = CharSet.Unicode)] - public static extern bool AppendMenu(IntPtr hMenu, MenuFlags uFlags, uint uIDNewItem, string lpNewItem); - - [DllImport("user32.dll")] - public static extern uint TrackPopupMenuEx(IntPtr hmenu, UFLAGS uFlags, int x, int y, IntPtr hwnd, IntPtr lptpm); - - [DllImport("wtsapi32.dll", SetLastError = true)] - public static extern bool WTSRegisterSessionNotification(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] int dwFlags); - - [DllImport("wtsapi32.dll", SetLastError = true)] - public static extern bool WTSUnRegisterSessionNotification(IntPtr hWnd); - - [DllImport("user32.dll", CharSet = CharSet.Auto)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool SystemParametersInfo(uint uAction, uint uParam, ref bool lpvParam, int fWinIni); - - [DllImport("user32.dll")] - public static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); - - // constants that can be passed for the WTSRegisterSessionNotification - // dwFlags parameter - public const int NOTIFY_FOR_THIS_SESSION = 0; - public const int NOTIFY_FOR_ALL_SESSIONS = 1; - - // lParam values for WM_ENDSESSION message - public const int ENDSESSION_CLOSEAPP = 0x1; - public const int ENDSESSION_CRITICAL = 0x40000000; - public const int ENDSESSION_LOGOFF = unchecked((int)0x80000000); - - public const uint IMAGE_BITMAP = 0; - public const uint IMAGE_ICON = 1; - public const uint IMAGE_CURSOR = 2; - - public const uint LR_DEFAULTSIZE = 0x00000040; - public const uint LR_LOADFROMFILE = 0x00000010; - - public static IntPtr HWND_BROADCAST = new IntPtr(0xffff); - public static IntPtr HWND_TOP = new IntPtr(0); - public static IntPtr HWND_BOTTOM = new IntPtr(1); - public static IntPtr HWND_TOPMOST = new IntPtr(-1); - public static IntPtr HWND_NOTOPMOST = new IntPtr(-2); - public static IntPtr HWND_MESSAGE = new IntPtr(-3); - - public const uint WS_POPUP = 0x80000000; - public const uint WS_VISIBLE = 0x10000000; - - public const int WTS_CONSOLE_CONNECT = 0x1; // A session was connected to the console terminal. - public const int WTS_CONSOLE_DISCONNECT = 0x2; // A session was disconnected from the console terminal. - public const int WTS_REMOTE_CONNECT = 0x3; // A session was connected to the remote terminal. - public const int WTS_REMOTE_DISCONNECT = 0x4; // A session was disconnected from the remote terminal. - public const int WTS_SESSION_LOGON = 0x5; // A user has logged on to the session. - public const int WTS_SESSION_LOGOFF = 0x6; // A user has logged off the session. - public const int WTS_SESSION_LOCK = 0x7; // A session has been locked. - public const int WTS_SESSION_UNLOCK = 0x8; // A session has been unlocked. - public const int WTS_SESSION_REMOTE_CONTROL = 0x9; // A session has changed its remote controlled status. - - public const int PBT_APMQUERYSUSPEND = 0x0000; - public const int PBT_APMQUERYSTANDBY = 0x0001; - public const int PBT_APMQUERYSUSPENDFAILED = 0x0002; - public const int PBT_APMQUERYSTANDBYFAILED = 0x0003; - public const int PBT_APMSUSPEND = 0x0004; - public const int PBT_APMSTANDBY = 0x0005; - public const int PBT_APMRESUMECRITICAL = 0x0006; - public const int PBT_APMRESUMESUSPEND = 0x0007; - public const int PBT_APMRESUMESTANDBY = 0x0008; - public const int PBT_APMBATTERYLOW = 0x0009; - public const int PBT_APMPOWERSTATUSCHANGE = 0x000A; - public const int PBT_APMOEMEVENT = 0x000B; - - [StructLayout(LayoutKind.Sequential)] - public struct LASTINPUTINFO + public MENUITEMINFO() { - public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO)); - - [MarshalAs(UnmanagedType.U4)] - public uint cbSize; - [MarshalAs(UnmanagedType.U4)] - public uint dwTime; } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public class NOTIFYICONDATA + public MENUITEMINFO(MIIM pfMask) { - public int cbSize = Marshal.SizeOf(); - public IntPtr hWnd; - public int uID; - public NIF uFlags; - public int uCallbackMessage; - public IntPtr hIcon; - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - public string szTip; - public int dwState = 0; - public int dwStateMask = 0; - /// - /// String with the text for a balloon ToolTip. It can have a maximum of 255 characters. - /// To remove the ToolTip, set the NIF_INFO flag in uFlags and set szInfo to an empty string. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] - public string szInfo; - public int uTimeoutOrVersion; - /// - /// String containing a title for a balloon ToolTip. This title appears in boldface - /// above the text. It can have a maximum of 63 characters. - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] - public string szInfoTitle; - public NIIF dwInfoFlags; - - /// - /// Windows Vista (Shell32.dll version 6.0.6) and later. The handle of a customized - /// balloon icon provided by the application that should be used independently - /// of the tray icon. If this member is non-NULL and the - /// flag is set, this icon is used as the balloon icon.
- /// If this member is NULL, the legacy behavior is carried out. - ///
- //public IntPtr CustomBalloonIconHandle; + fMask = pfMask; } + } - public enum NIM : uint + /// + /// Custom Win32 window messages for the NotifyIcon + /// + public enum CustomWindowsMessage : uint + { + WM_TRAYICON = (uint)WindowsMessage.WM_APP + 1024, + WM_TRAYMOUSE = (uint)WindowsMessage.WM_USER + 1024 + } + + public enum SysCommands : int + { + SC_SIZE = 0xF000, + SC_MOVE = 0xF010, + SC_MINIMIZE = 0xF020, + SC_MAXIMIZE = 0xF030, + SC_NEXTWINDOW = 0xF040, + SC_PREVWINDOW = 0xF050, + SC_CLOSE = 0xF060, + SC_VSCROLL = 0xF070, + SC_HSCROLL = 0xF080, + SC_MOUSEMENU = 0xF090, + SC_KEYMENU = 0xF100, + SC_ARRANGE = 0xF110, + SC_RESTORE = 0xF120, + SC_TASKLIST = 0xF130, + SC_SCREENSAVE = 0xF140, + SC_HOTKEY = 0xF150, + //#if(WINVER >= 0x0400) //Win95 + SC_DEFAULT = 0xF160, + SC_MONITORPOWER = 0xF170, + SC_CONTEXTHELP = 0xF180, + SC_SEPARATOR = 0xF00F, + //#endif /* WINVER >= 0x0400 */ + + //#if(WINVER >= 0x0600) //Vista + SCF_ISSECURE = 0x00000001, + //#endif /* WINVER >= 0x0600 */ + + /* + * Obsolete names + */ + SC_ICON = SC_MINIMIZE, + SC_ZOOM = SC_MAXIMIZE, + } + + [Flags] + public enum MIIM + { + BITMAP = 0x00000080, + CHECKMARKS = 0x00000008, + DATA = 0x00000020, + FTYPE = 0x00000100, + ID = 0x00000002, + STATE = 0x00000001, + STRING = 0x00000040, + SUBMENU = 0x00000004, + TYPE = 0x00000010 + } + + [Flags] + public enum MenuFlags : uint + { + MF_STRING = 0, + MF_BYPOSITION = 0x400, + MF_SEPARATOR = 0x800, + MF_REMOVE = 0x1000, + } + + [Flags] + public enum UFLAGS : uint + { + TPM_LEFTALIGN = 0x0000, + TPM_CENTERALIGN = 0x0004, + TPM_RIGHTALIGN = 0x0008, + TPM_TOPALIGN = 0x0000, + TPM_VCENTERALIGN = 0x0010, + TPM_BOTTOMALIGN = 0x0020, + TPM_HORIZONTAL = 0x0000, + TPM_VERTICAL = 0x0040, + TPM_NONOTIFY = 0x0080, + TPM_RETURNCMD = 0x0100 + } + + // End extensions for SQRLDotNetClientUI + + public const int CW_USEDEFAULT = unchecked((int)0x80000000); + + public delegate void TimerProc(IntPtr hWnd, uint uMsg, IntPtr nIDEvent, uint dwTime); + + public delegate void TimeCallback(uint uTimerID, uint uMsg, UIntPtr dwUser, UIntPtr dw1, UIntPtr dw2); + + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + public delegate void WaitOrTimerCallback(IntPtr lpParameter, bool timerOrWaitFired); + + public delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + public static readonly IntPtr DPI_AWARENESS_CONTEXT_UNAWARE = new IntPtr(-1); + public static readonly IntPtr DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = new IntPtr(-2); + public static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = new IntPtr(-3); + public static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4); + + public enum Cursor + { + IDC_ARROW = 32512, + IDC_IBEAM = 32513, + IDC_WAIT = 32514, + IDC_CROSS = 32515, + IDC_UPARROW = 32516, + IDC_SIZE = 32640, + IDC_ICON = 32641, + IDC_SIZENWSE = 32642, + IDC_SIZENESW = 32643, + IDC_SIZEWE = 32644, + IDC_SIZENS = 32645, + IDC_SIZEALL = 32646, + IDC_NO = 32648, + IDC_HAND = 32649, + IDC_APPSTARTING = 32650, + IDC_HELP = 32651 + } + + public enum MouseActivate : int + { + MA_ACTIVATE = 1, + MA_ACTIVATEANDEAT = 2, + MA_NOACTIVATE = 3, + MA_NOACTIVATEANDEAT = 4 + } + + [Flags] + public enum SetWindowPosFlags : uint + { + SWP_ASYNCWINDOWPOS = 0x4000, + SWP_DEFERERASE = 0x2000, + SWP_DRAWFRAME = 0x0020, + SWP_FRAMECHANGED = 0x0020, + SWP_HIDEWINDOW = 0x0080, + SWP_NOACTIVATE = 0x0010, + SWP_NOCOPYBITS = 0x0100, + SWP_NOMOVE = 0x0002, + SWP_NOOWNERZORDER = 0x0200, + SWP_NOREDRAW = 0x0008, + SWP_NOREPOSITION = 0x0200, + SWP_NOSENDCHANGING = 0x0400, + SWP_NOSIZE = 0x0001, + SWP_NOZORDER = 0x0004, + SWP_SHOWWINDOW = 0x0040, + + SWP_RESIZE = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER + } + + public static class WindowPosZOrder + { + public static readonly IntPtr HWND_BOTTOM = new IntPtr(1); + public static readonly IntPtr HWND_TOP = new IntPtr(0); + public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); + public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); + } + + public enum SizeCommand + { + Restored, + Minimized, + Maximized, + MaxShow, + MaxHide, + } + + public enum ShowWindowCommand + { + Hide = 0, + Normal = 1, + ShowMinimized = 2, + Maximize = 3, + ShowMaximized = 3, + ShowNoActivate = 4, + Show = 5, + Minimize = 6, + ShowMinNoActive = 7, + ShowNA = 8, + Restore = 9, + ShowDefault = 10, + ForceMinimize = 11 + } + + public enum SystemMetric + { + SM_CXSCREEN = 0, // 0x00 + SM_CYSCREEN = 1, // 0x01 + SM_CXVSCROLL = 2, // 0x02 + SM_CYHSCROLL = 3, // 0x03 + SM_CYCAPTION = 4, // 0x04 + SM_CXBORDER = 5, // 0x05 + SM_CYBORDER = 6, // 0x06 + SM_CXDLGFRAME = 7, // 0x07 + SM_CXFIXEDFRAME = 7, // 0x07 + SM_CYDLGFRAME = 8, // 0x08 + SM_CYFIXEDFRAME = 8, // 0x08 + SM_CYVTHUMB = 9, // 0x09 + SM_CXHTHUMB = 10, // 0x0A + SM_CXICON = 11, // 0x0B + SM_CYICON = 12, // 0x0C + SM_CXCURSOR = 13, // 0x0D + SM_CYCURSOR = 14, // 0x0E + SM_CYMENU = 15, // 0x0F + SM_CXFULLSCREEN = 16, // 0x10 + SM_CYFULLSCREEN = 17, // 0x11 + SM_CYKANJIWINDOW = 18, // 0x12 + SM_MOUSEPRESENT = 19, // 0x13 + SM_CYVSCROLL = 20, // 0x14 + SM_CXHSCROLL = 21, // 0x15 + SM_DEBUG = 22, // 0x16 + SM_SWAPBUTTON = 23, // 0x17 + SM_CXMIN = 28, // 0x1C + SM_CYMIN = 29, // 0x1D + SM_CXSIZE = 30, // 0x1E + SM_CYSIZE = 31, // 0x1F + SM_CXSIZEFRAME = 32, // 0x20 + SM_CXFRAME = 32, // 0x20 + SM_CYSIZEFRAME = 33, // 0x21 + SM_CYFRAME = 33, // 0x21 + SM_CXMINTRACK = 34, // 0x22 + SM_CYMINTRACK = 35, // 0x23 + SM_CXDOUBLECLK = 36, // 0x24 + SM_CYDOUBLECLK = 37, // 0x25 + SM_CXICONSPACING = 38, // 0x26 + SM_CYICONSPACING = 39, // 0x27 + SM_MENUDROPALIGNMENT = 40, // 0x28 + SM_PENWINDOWS = 41, // 0x29 + SM_DBCSENABLED = 42, // 0x2A + SM_CMOUSEBUTTONS = 43, // 0x2B + SM_SECURE = 44, // 0x2C + SM_CXEDGE = 45, // 0x2D + SM_CYEDGE = 46, // 0x2E + SM_CXMINSPACING = 47, // 0x2F + SM_CYMINSPACING = 48, // 0x30 + SM_CXSMICON = 49, // 0x31 + SM_CYSMICON = 50, // 0x32 + SM_CYSMCAPTION = 51, // 0x33 + SM_CXSMSIZE = 52, // 0x34 + SM_CYSMSIZE = 53, // 0x35 + SM_CXMENUSIZE = 54, // 0x36 + SM_CYMENUSIZE = 55, // 0x37 + SM_ARRANGE = 56, // 0x38 + SM_CXMINIMIZED = 57, // 0x39 + SM_CYMINIMIZED = 58, // 0x3A + SM_CXMAXTRACK = 59, // 0x3B + SM_CYMAXTRACK = 60, // 0x3C + SM_CXMAXIMIZED = 61, // 0x3D + SM_CYMAXIMIZED = 62, // 0x3E + SM_NETWORK = 63, // 0x3F + SM_CLEANBOOT = 67, // 0x43 + SM_CXDRAG = 68, // 0x44 + SM_CYDRAG = 69, // 0x45 + SM_SHOWSOUNDS = 70, // 0x46 + SM_CXMENUCHECK = 71, // 0x47 + SM_CYMENUCHECK = 72, // 0x48 + SM_SLOWMACHINE = 73, // 0x49 + SM_MIDEASTENABLED = 74, // 0x4A + SM_MOUSEWHEELPRESENT = 75, // 0x4B + SM_XVIRTUALSCREEN = 76, // 0x4C + SM_YVIRTUALSCREEN = 77, // 0x4D + SM_CXVIRTUALSCREEN = 78, // 0x4E + SM_CYVIRTUALSCREEN = 79, // 0x4F + SM_CMONITORS = 80, // 0x50 + SM_SAMEDISPLAYFORMAT = 81, // 0x51 + SM_IMMENABLED = 82, // 0x52 + SM_CXFOCUSBORDER = 83, // 0x53 + SM_CYFOCUSBORDER = 84, // 0x54 + SM_TABLETPC = 86, // 0x56 + SM_MEDIACENTER = 87, // 0x57 + SM_STARTER = 88, // 0x58 + SM_SERVERR2 = 89, // 0x59 + SM_MOUSEHORIZONTALWHEELPRESENT = 91, // 0x5B + SM_CXPADDEDBORDER = 92, // 0x5C + SM_DIGITIZER = 94, // 0x5E + SM_MAXIMUMTOUCHES = 95, // 0x5F + + SM_REMOTESESSION = 0x1000, // 0x1000 + SM_SHUTTINGDOWN = 0x2000, // 0x2000 + SM_REMOTECONTROL = 0x2001, // 0x2001 + + SM_CONVERTABLESLATEMODE = 0x2003, + SM_SYSTEMDOCKED = 0x2004, + } + + [Flags] + public enum ModifierKeys + { + MK_CONTROL = 0x0008, + + MK_LBUTTON = 0x0001, + + MK_MBUTTON = 0x0010, + + MK_RBUTTON = 0x0002, + + MK_SHIFT = 0x0004, + + MK_ALT = 0x0020, + + MK_XBUTTON1 = 0x0020, + + MK_XBUTTON2 = 0x0040 + } + + public enum VirtualKeyStates : int + { + VK_LBUTTON = 0x01, + VK_RBUTTON = 0x02, + VK_CANCEL = 0x03, + VK_MBUTTON = 0x04, + VK_XBUTTON1 = 0x05, + VK_XBUTTON2 = 0x06, + VK_BACK = 0x08, + VK_TAB = 0x09, + VK_CLEAR = 0x0C, + VK_RETURN = 0x0D, + VK_SHIFT = 0x10, + VK_CONTROL = 0x11, + VK_MENU = 0x12, + VK_PAUSE = 0x13, + VK_CAPITAL = 0x14, + VK_KANA = 0x15, + VK_HANGEUL = 0x15, + VK_HANGUL = 0x15, + VK_JUNJA = 0x17, + VK_FINAL = 0x18, + VK_HANJA = 0x19, + VK_KANJI = 0x19, + VK_ESCAPE = 0x1B, + VK_CONVERT = 0x1C, + VK_NONCONVERT = 0x1D, + VK_ACCEPT = 0x1E, + VK_MODECHANGE = 0x1F, + VK_SPACE = 0x20, + VK_PRIOR = 0x21, + VK_NEXT = 0x22, + VK_END = 0x23, + VK_HOME = 0x24, + VK_LEFT = 0x25, + VK_UP = 0x26, + VK_RIGHT = 0x27, + VK_DOWN = 0x28, + VK_SELECT = 0x29, + VK_PRINT = 0x2A, + VK_EXECUTE = 0x2B, + VK_SNAPSHOT = 0x2C, + VK_INSERT = 0x2D, + VK_DELETE = 0x2E, + VK_HELP = 0x2F, + VK_LWIN = 0x5B, + VK_RWIN = 0x5C, + VK_APPS = 0x5D, + VK_SLEEP = 0x5F, + VK_NUMPAD0 = 0x60, + VK_NUMPAD1 = 0x61, + VK_NUMPAD2 = 0x62, + VK_NUMPAD3 = 0x63, + VK_NUMPAD4 = 0x64, + VK_NUMPAD5 = 0x65, + VK_NUMPAD6 = 0x66, + VK_NUMPAD7 = 0x67, + VK_NUMPAD8 = 0x68, + VK_NUMPAD9 = 0x69, + VK_MULTIPLY = 0x6A, + VK_ADD = 0x6B, + VK_SEPARATOR = 0x6C, + VK_SUBTRACT = 0x6D, + VK_DECIMAL = 0x6E, + VK_DIVIDE = 0x6F, + VK_F1 = 0x70, + VK_F2 = 0x71, + VK_F3 = 0x72, + VK_F4 = 0x73, + VK_F5 = 0x74, + VK_F6 = 0x75, + VK_F7 = 0x76, + VK_F8 = 0x77, + VK_F9 = 0x78, + VK_F10 = 0x79, + VK_F11 = 0x7A, + VK_F12 = 0x7B, + VK_F13 = 0x7C, + VK_F14 = 0x7D, + VK_F15 = 0x7E, + VK_F16 = 0x7F, + VK_F17 = 0x80, + VK_F18 = 0x81, + VK_F19 = 0x82, + VK_F20 = 0x83, + VK_F21 = 0x84, + VK_F22 = 0x85, + VK_F23 = 0x86, + VK_F24 = 0x87, + VK_NUMLOCK = 0x90, + VK_SCROLL = 0x91, + VK_OEM_NEC_EQUAL = 0x92, + VK_OEM_FJ_JISHO = 0x92, + VK_OEM_FJ_MASSHOU = 0x93, + VK_OEM_FJ_TOUROKU = 0x94, + VK_OEM_FJ_LOYA = 0x95, + VK_OEM_FJ_ROYA = 0x96, + VK_LSHIFT = 0xA0, + VK_RSHIFT = 0xA1, + VK_LCONTROL = 0xA2, + VK_RCONTROL = 0xA3, + VK_LMENU = 0xA4, + VK_RMENU = 0xA5, + VK_BROWSER_BACK = 0xA6, + VK_BROWSER_FORWARD = 0xA7, + VK_BROWSER_REFRESH = 0xA8, + VK_BROWSER_STOP = 0xA9, + VK_BROWSER_SEARCH = 0xAA, + VK_BROWSER_FAVORITES = 0xAB, + VK_BROWSER_HOME = 0xAC, + VK_VOLUME_MUTE = 0xAD, + VK_VOLUME_DOWN = 0xAE, + VK_VOLUME_UP = 0xAF, + VK_MEDIA_NEXT_TRACK = 0xB0, + VK_MEDIA_PREV_TRACK = 0xB1, + VK_MEDIA_STOP = 0xB2, + VK_MEDIA_PLAY_PAUSE = 0xB3, + VK_LAUNCH_MAIL = 0xB4, + VK_LAUNCH_MEDIA_SELECT = 0xB5, + VK_LAUNCH_APP1 = 0xB6, + VK_LAUNCH_APP2 = 0xB7, + VK_OEM_1 = 0xBA, + VK_OEM_PLUS = 0xBB, + VK_OEM_COMMA = 0xBC, + VK_OEM_MINUS = 0xBD, + VK_OEM_PERIOD = 0xBE, + VK_OEM_2 = 0xBF, + VK_OEM_3 = 0xC0, + VK_OEM_4 = 0xDB, + VK_OEM_5 = 0xDC, + VK_OEM_6 = 0xDD, + VK_OEM_7 = 0xDE, + VK_OEM_8 = 0xDF, + VK_OEM_AX = 0xE1, + VK_OEM_102 = 0xE2, + VK_ICO_HELP = 0xE3, + VK_ICO_00 = 0xE4, + VK_PROCESSKEY = 0xE5, + VK_ICO_CLEAR = 0xE6, + VK_PACKET = 0xE7, + VK_OEM_RESET = 0xE9, + VK_OEM_JUMP = 0xEA, + VK_OEM_PA1 = 0xEB, + VK_OEM_PA2 = 0xEC, + VK_OEM_PA3 = 0xED, + VK_OEM_WSCTRL = 0xEE, + VK_OEM_CUSEL = 0xEF, + VK_OEM_ATTN = 0xF0, + VK_OEM_FINISH = 0xF1, + VK_OEM_COPY = 0xF2, + VK_OEM_AUTO = 0xF3, + VK_OEM_ENLW = 0xF4, + VK_OEM_BACKTAB = 0xF5, + VK_ATTN = 0xF6, + VK_CRSEL = 0xF7, + VK_EXSEL = 0xF8, + VK_EREOF = 0xF9, + VK_PLAY = 0xFA, + VK_ZOOM = 0xFB, + VK_NONAME = 0xFC, + VK_PA1 = 0xFD, + VK_OEM_CLEAR = 0xFE + } + + public enum WindowActivate + { + WA_INACTIVE, + WA_ACTIVE, + WA_CLICKACTIVE, + } + + public enum HitTestValues + { + HTERROR = -2, + HTTRANSPARENT = -1, + HTNOWHERE = 0, + HTCLIENT = 1, + HTCAPTION = 2, + HTSYSMENU = 3, + HTGROWBOX = 4, + HTMENU = 5, + HTHSCROLL = 6, + HTVSCROLL = 7, + HTMINBUTTON = 8, + HTMAXBUTTON = 9, + HTLEFT = 10, + HTRIGHT = 11, + HTTOP = 12, + HTTOPLEFT = 13, + HTTOPRIGHT = 14, + HTBOTTOM = 15, + HTBOTTOMLEFT = 16, + HTBOTTOMRIGHT = 17, + HTBORDER = 18, + HTOBJECT = 19, + HTCLOSE = 20, + HTHELP = 21 + } + + [Flags] + public enum WindowStyles : uint + { + WS_BORDER = 0x800000, + WS_CAPTION = 0xc00000, + WS_CHILD = 0x40000000, + WS_CLIPCHILDREN = 0x2000000, + WS_CLIPSIBLINGS = 0x4000000, + WS_DISABLED = 0x8000000, + WS_DLGFRAME = 0x400000, + WS_GROUP = 0x20000, + WS_HSCROLL = 0x100000, + WS_MAXIMIZE = 0x1000000, + WS_MAXIMIZEBOX = 0x10000, + WS_MINIMIZE = 0x20000000, + WS_MINIMIZEBOX = 0x20000, + WS_OVERLAPPED = 0x0, + WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, + WS_POPUP = 0x80000000u, + WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU, + WS_SIZEFRAME = 0x40000, + WS_SYSMENU = 0x80000, + WS_TABSTOP = 0x10000, + WS_VISIBLE = 0x10000000, + WS_VSCROLL = 0x200000, + WS_EX_DLGMODALFRAME = 0x00000001, + WS_EX_NOPARENTNOTIFY = 0x00000004, + WS_EX_TOPMOST = 0x00000008, + WS_EX_ACCEPTFILES = 0x00000010, + WS_EX_TRANSPARENT = 0x00000020, + WS_EX_MDICHILD = 0x00000040, + WS_EX_TOOLWINDOW = 0x00000080, + WS_EX_WINDOWEDGE = 0x00000100, + WS_EX_CLIENTEDGE = 0x00000200, + WS_EX_CONTEXTHELP = 0x00000400, + WS_EX_RIGHT = 0x00001000, + WS_EX_LEFT = 0x00000000, + WS_EX_RTLREADING = 0x00002000, + WS_EX_LTRREADING = 0x00000000, + WS_EX_LEFTSCROLLBAR = 0x00004000, + WS_EX_RIGHTSCROLLBAR = 0x00000000, + WS_EX_CONTROLPARENT = 0x00010000, + WS_EX_STATICEDGE = 0x00020000, + WS_EX_APPWINDOW = 0x00040000, + WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, + WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, + WS_EX_LAYERED = 0x00080000, + WS_EX_NOINHERITLAYOUT = 0x00100000, + WS_EX_LAYOUTRTL = 0x00400000, + WS_EX_COMPOSITED = 0x02000000, + WS_EX_NOACTIVATE = 0x08000000 + } + + [Flags] + public enum ClassStyles : uint + { + CS_VREDRAW = 0x0001, + CS_HREDRAW = 0x0002, + CS_DBLCLKS = 0x0008, + CS_OWNDC = 0x0020, + CS_CLASSDC = 0x0040, + CS_PARENTDC = 0x0080, + CS_NOCLOSE = 0x0200, + CS_SAVEBITS = 0x0800, + CS_BYTEALIGNCLIENT = 0x1000, + CS_BYTEALIGNWINDOW = 0x2000, + CS_GLOBALCLASS = 0x4000, + CS_IME = 0x00010000, + CS_DROPSHADOW = 0x00020000 + } + + public enum WindowsMessage : uint + { + WM_NULL = 0x0000, + WM_CREATE = 0x0001, + WM_DESTROY = 0x0002, + WM_MOVE = 0x0003, + WM_SIZE = 0x0005, + WM_ACTIVATE = 0x0006, + WM_SETFOCUS = 0x0007, + WM_KILLFOCUS = 0x0008, + WM_ENABLE = 0x000A, + WM_SETREDRAW = 0x000B, + WM_SETTEXT = 0x000C, + WM_GETTEXT = 0x000D, + WM_GETTEXTLENGTH = 0x000E, + WM_PAINT = 0x000F, + WM_CLOSE = 0x0010, + WM_QUERYENDSESSION = 0x0011, + WM_QUERYOPEN = 0x0013, + WM_ENDSESSION = 0x0016, + WM_QUIT = 0x0012, + WM_ERASEBKGND = 0x0014, + WM_SYSCOLORCHANGE = 0x0015, + WM_SHOWWINDOW = 0x0018, + WM_WININICHANGE = 0x001A, + WM_SETTINGCHANGE = WM_WININICHANGE, + WM_DEVMODECHANGE = 0x001B, + WM_ACTIVATEAPP = 0x001C, + WM_FONTCHANGE = 0x001D, + WM_TIMECHANGE = 0x001E, + WM_CANCELMODE = 0x001F, + WM_SETCURSOR = 0x0020, + WM_MOUSEACTIVATE = 0x0021, + WM_CHILDACTIVATE = 0x0022, + WM_QUEUESYNC = 0x0023, + WM_GETMINMAXINFO = 0x0024, + WM_PAINTICON = 0x0026, + WM_ICONERASEBKGND = 0x0027, + WM_NEXTDLGCTL = 0x0028, + WM_SPOOLERSTATUS = 0x002A, + WM_DRAWITEM = 0x002B, + WM_MEASUREITEM = 0x002C, + WM_DELETEITEM = 0x002D, + WM_VKEYTOITEM = 0x002E, + WM_CHARTOITEM = 0x002F, + WM_SETFONT = 0x0030, + WM_GETFONT = 0x0031, + WM_SETHOTKEY = 0x0032, + WM_GETHOTKEY = 0x0033, + WM_QUERYDRAGICON = 0x0037, + WM_COMPAREITEM = 0x0039, + WM_GETOBJECT = 0x003D, + WM_COMPACTING = 0x0041, + WM_WINDOWPOSCHANGING = 0x0046, + WM_WINDOWPOSCHANGED = 0x0047, + WM_COPYDATA = 0x004A, + WM_CANCELJOURNAL = 0x004B, + WM_NOTIFY = 0x004E, + WM_INPUTLANGCHANGEREQUEST = 0x0050, + WM_INPUTLANGCHANGE = 0x0051, + WM_TCARD = 0x0052, + WM_HELP = 0x0053, + WM_USERCHANGED = 0x0054, + WM_NOTIFYFORMAT = 0x0055, + WM_CONTEXTMENU = 0x007B, + WM_STYLECHANGING = 0x007C, + WM_STYLECHANGED = 0x007D, + WM_DISPLAYCHANGE = 0x007E, + WM_GETICON = 0x007F, + WM_SETICON = 0x0080, + WM_NCCREATE = 0x0081, + WM_NCDESTROY = 0x0082, + WM_NCCALCSIZE = 0x0083, + WM_NCHITTEST = 0x0084, + WM_NCPAINT = 0x0085, + WM_NCACTIVATE = 0x0086, + WM_GETDLGCODE = 0x0087, + WM_SYNCPAINT = 0x0088, + WM_NCMOUSEMOVE = 0x00A0, + WM_NCLBUTTONDOWN = 0x00A1, + WM_NCLBUTTONUP = 0x00A2, + WM_NCLBUTTONDBLCLK = 0x00A3, + WM_NCRBUTTONDOWN = 0x00A4, + WM_NCRBUTTONUP = 0x00A5, + WM_NCRBUTTONDBLCLK = 0x00A6, + WM_NCMBUTTONDOWN = 0x00A7, + WM_NCMBUTTONUP = 0x00A8, + WM_NCMBUTTONDBLCLK = 0x00A9, + WM_NCXBUTTONDOWN = 0x00AB, + WM_NCXBUTTONUP = 0x00AC, + WM_NCXBUTTONDBLCLK = 0x00AD, + WM_INPUT_DEVICE_CHANGE = 0x00FE, + WM_INPUT = 0x00FF, + WM_KEYFIRST = 0x0100, + WM_KEYDOWN = 0x0100, + WM_KEYUP = 0x0101, + WM_CHAR = 0x0102, + WM_DEADCHAR = 0x0103, + WM_SYSKEYDOWN = 0x0104, + WM_SYSKEYUP = 0x0105, + WM_SYSCHAR = 0x0106, + WM_SYSDEADCHAR = 0x0107, + WM_UNICHAR = 0x0109, + WM_KEYLAST = 0x0109, + WM_IME_STARTCOMPOSITION = 0x010D, + WM_IME_ENDCOMPOSITION = 0x010E, + WM_IME_COMPOSITION = 0x010F, + WM_IME_KEYLAST = 0x010F, + WM_INITDIALOG = 0x0110, + WM_COMMAND = 0x0111, + WM_SYSCOMMAND = 0x0112, + WM_TIMER = 0x0113, + WM_HSCROLL = 0x0114, + WM_VSCROLL = 0x0115, + WM_INITMENU = 0x0116, + WM_INITMENUPOPUP = 0x0117, + WM_MENUSELECT = 0x011F, + WM_MENUCHAR = 0x0120, + WM_ENTERIDLE = 0x0121, + WM_MENURBUTTONUP = 0x0122, + WM_MENUDRAG = 0x0123, + WM_MENUGETOBJECT = 0x0124, + WM_UNINITMENUPOPUP = 0x0125, + WM_MENUCOMMAND = 0x0126, + WM_CHANGEUISTATE = 0x0127, + WM_UPDATEUISTATE = 0x0128, + WM_QUERYUISTATE = 0x0129, + WM_CTLCOLORMSGBOX = 0x0132, + WM_CTLCOLOREDIT = 0x0133, + WM_CTLCOLORLISTBOX = 0x0134, + WM_CTLCOLORBTN = 0x0135, + WM_CTLCOLORDLG = 0x0136, + WM_CTLCOLORSCROLLBAR = 0x0137, + WM_CTLCOLORSTATIC = 0x0138, + WM_MOUSEFIRST = 0x0200, + WM_MOUSEMOVE = 0x0200, + WM_LBUTTONDOWN = 0x0201, + WM_LBUTTONUP = 0x0202, + WM_LBUTTONDBLCLK = 0x0203, + WM_RBUTTONDOWN = 0x0204, + WM_RBUTTONUP = 0x0205, + WM_RBUTTONDBLCLK = 0x0206, + WM_MBUTTONDOWN = 0x0207, + WM_MBUTTONUP = 0x0208, + WM_MBUTTONDBLCLK = 0x0209, + WM_MOUSEWHEEL = 0x020A, + WM_XBUTTONDOWN = 0x020B, + WM_XBUTTONUP = 0x020C, + WM_XBUTTONDBLCLK = 0x020D, + WM_MOUSEHWHEEL = 0x020E, + WM_MOUSELAST = 0x020E, + WM_PARENTNOTIFY = 0x0210, + WM_ENTERMENULOOP = 0x0211, + WM_EXITMENULOOP = 0x0212, + WM_NEXTMENU = 0x0213, + WM_SIZING = 0x0214, + WM_CAPTURECHANGED = 0x0215, + WM_MOVING = 0x0216, + WM_POWERBROADCAST = 0x0218, + WM_DEVICECHANGE = 0x0219, + WM_MDICREATE = 0x0220, + WM_MDIDESTROY = 0x0221, + WM_MDIACTIVATE = 0x0222, + WM_MDIRESTORE = 0x0223, + WM_MDINEXT = 0x0224, + WM_MDIMAXIMIZE = 0x0225, + WM_MDITILE = 0x0226, + WM_MDICASCADE = 0x0227, + WM_MDIICONARRANGE = 0x0228, + WM_MDIGETACTIVE = 0x0229, + WM_MDISETMENU = 0x0230, + WM_ENTERSIZEMOVE = 0x0231, + WM_EXITSIZEMOVE = 0x0232, + WM_DROPFILES = 0x0233, + WM_MDIREFRESHMENU = 0x0234, + WM_IME_SETCONTEXT = 0x0281, + WM_IME_NOTIFY = 0x0282, + WM_IME_CONTROL = 0x0283, + WM_IME_COMPOSITIONFULL = 0x0284, + WM_IME_SELECT = 0x0285, + WM_IME_CHAR = 0x0286, + WM_IME_REQUEST = 0x0288, + WM_IME_KEYDOWN = 0x0290, + WM_IME_KEYUP = 0x0291, + WM_MOUSEHOVER = 0x02A1, + WM_MOUSELEAVE = 0x02A3, + WM_NCMOUSEHOVER = 0x02A0, + WM_NCMOUSELEAVE = 0x02A2, + WM_WTSSESSION_CHANGE = 0x02B1, + WM_TABLET_FIRST = 0x02c0, + WM_TABLET_LAST = 0x02df, + WM_DPICHANGED = 0x02E0, + WM_CUT = 0x0300, + WM_COPY = 0x0301, + WM_PASTE = 0x0302, + WM_CLEAR = 0x0303, + WM_UNDO = 0x0304, + WM_RENDERFORMAT = 0x0305, + WM_RENDERALLFORMATS = 0x0306, + WM_DESTROYCLIPBOARD = 0x0307, + WM_DRAWCLIPBOARD = 0x0308, + WM_PAINTCLIPBOARD = 0x0309, + WM_VSCROLLCLIPBOARD = 0x030A, + WM_SIZECLIPBOARD = 0x030B, + WM_ASKCBFORMATNAME = 0x030C, + WM_CHANGECBCHAIN = 0x030D, + WM_HSCROLLCLIPBOARD = 0x030E, + WM_QUERYNEWPALETTE = 0x030F, + WM_PALETTEISCHANGING = 0x0310, + WM_PALETTECHANGED = 0x0311, + WM_HOTKEY = 0x0312, + WM_PRINT = 0x0317, + WM_PRINTCLIENT = 0x0318, + WM_APPCOMMAND = 0x0319, + WM_THEMECHANGED = 0x031A, + WM_CLIPBOARDUPDATE = 0x031D, + WM_DWMCOMPOSITIONCHANGED = 0x031E, + WM_DWMNCRENDERINGCHANGED = 0x031F, + WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320, + WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321, + WM_GETTITLEBARINFOEX = 0x033F, + WM_HANDHELDFIRST = 0x0358, + WM_HANDHELDLAST = 0x035F, + WM_AFXFIRST = 0x0360, + WM_AFXLAST = 0x037F, + WM_PENWINFIRST = 0x0380, + WM_PENWINLAST = 0x038F, + WM_TOUCH = 0x0240, + WM_APP = 0x8000, + WM_USER = 0x0400, + + WM_DISPATCH_WORK_ITEM = WM_USER, + } + + public enum MapVirtualKeyMapTypes : uint + { + MAPVK_VK_TO_VSC = 0x00, + MAPVK_VSC_TO_VK = 0x01, + MAPVK_VK_TO_CHAR = 0x02, + MAPVK_VSC_TO_VK_EX = 0x03, + } + + public enum BitmapCompressionMode : uint + { + BI_RGB = 0, + BI_RLE8 = 1, + BI_RLE4 = 2, + BI_BITFIELDS = 3, + BI_JPEG = 4, + BI_PNG = 5 + } + + public enum DIBColorTable + { + DIB_RGB_COLORS = 0, /* color table in RGBs */ + DIB_PAL_COLORS /* color table in palette indices */ + } + + public enum WindowLongParam + { + GWL_WNDPROC = -4, + GWL_HINSTANCE = -6, + GWL_HWNDPARENT = -8, + GWL_ID = -12, + GWL_STYLE = -16, + GWL_EXSTYLE = -20, + GWL_USERDATA = -21 + } + + public enum MenuCharParam + { + MNC_IGNORE = 0, + MNC_CLOSE = 1, + MNC_EXECUTE = 2, + MNC_SELECT = 3 + } + + [StructLayout(LayoutKind.Sequential)] + public struct RGBQUAD + { + public byte rgbBlue; + public byte rgbGreen; + public byte rgbRed; + public byte rgbReserved; + } + + [StructLayout(LayoutKind.Sequential)] + public struct BITMAPINFOHEADER + { + public uint biSize; + public int biWidth; + public int biHeight; + public ushort biPlanes; + public ushort biBitCount; + public uint biCompression; + public uint biSizeImage; + public int biXPelsPerMeter; + public int biYPelsPerMeter; + public uint biClrUsed; + public uint biClrImportant; + + public void Init() { - ADD = 0x00000000, - MODIFY = 0x00000001, - DELETE = 0x00000002, - SETFOCUS = 0x00000003, - SETVERSION = 0x00000004 + biSize = (uint)Marshal.SizeOf(this); } + } - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public class MENUITEMINFO + [StructLayout(LayoutKind.Sequential)] + public struct BITMAPINFO + { + // C# cannot inlay structs in structs so must expand directly here + // + //[StructLayout(LayoutKind.Sequential)] + //public struct BITMAPINFOHEADER + //{ + public uint biSize; + public int biWidth; + public int biHeight; + public ushort biPlanes; + public ushort biBitCount; + public BitmapCompressionMode biCompression; + public uint biSizeImage; + public int biXPelsPerMeter; + public int biYPelsPerMeter; + public uint biClrUsed; + public uint biClrImportant; + //} + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] + public uint[] cols; + } + + [StructLayout(LayoutKind.Sequential)] + public struct MINMAXINFO + { + public POINT ptReserved; + public POINT ptMaxSize; + public POINT ptMaxPosition; + public POINT ptMinTrackSize; + public POINT ptMaxTrackSize; + } + + public const int SizeOf_BITMAPINFOHEADER = 40; + + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr GetDC(IntPtr hWnd); + + [DllImport("gdi32.dll")] + public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest, + uint dwWidth, uint dwHeight, + int XSrc, int YSrc, + uint uStartScan, uint cScanLines, + IntPtr lpvBits, [In] ref BITMAPINFO lpbmi, uint fuColorUse); + + [DllImport("user32.dll")] + public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool AdjustWindowRectEx(ref RECT lpRect, uint dwStyle, bool bMenu, uint dwExStyle); + + [DllImport("user32.dll")] + public static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint); + + [DllImport("user32.dll")] + public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr CreateWindowEx( + int dwExStyle, + uint lpClassName, + string lpWindowName, + uint dwStyle, + int x, + int y, + int nWidth, + int nHeight, + IntPtr hWndParent, + IntPtr hMenu, + IntPtr hInstance, + IntPtr lpParam); + + [DllImport("user32.dll", EntryPoint = "DefWindowProcW")] + public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", EntryPoint = "DispatchMessageW")] + public static extern IntPtr DispatchMessage(ref MSG lpmsg); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool DestroyWindow(IntPtr hwnd); + + [DllImport("user32.dll")] + public static extern bool EnableWindow(IntPtr hWnd, bool bEnable); + + [DllImport("user32.dll")] + public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint); + + [DllImport("user32.dll")] + public static extern uint GetCaretBlinkTime(); + + [DllImport("user32.dll")] + public static extern bool GetClientRect(IntPtr hwnd, out RECT lpRect); + + [DllImport("user32.dll")] + public static extern bool GetCursorPos(out POINT lpPoint); + + [DllImport("user32.dll")] + public static extern uint GetDoubleClickTime(); + + [DllImport("user32.dll")] + public static extern bool GetKeyboardState(byte[] lpKeyState); + + [DllImport("user32.dll", EntryPoint = "MapVirtualKeyW")] + public static extern uint MapVirtualKey(uint uCode, uint uMapType); + + [DllImport("user32.dll", EntryPoint = "GetMessageW")] + public static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); + + [DllImport("user32.dll")] + public static extern int GetMessageTime(); + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + public static extern IntPtr GetModuleHandle(string lpModuleName); + + [DllImport("user32.dll")] + public static extern int GetSystemMetrics(SystemMetric smIndex); + + [DllImport("user32.dll", SetLastError = true)] + public static extern uint GetWindowLongPtr(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetWindowLong")] + public static extern uint GetWindowLong32b(IntPtr hWnd, int nIndex); + + public static uint GetWindowLong(IntPtr hWnd, int nIndex) + { + if (IntPtr.Size == 4) { - public int cbSize = Marshal.SizeOf(typeof(MENUITEMINFO)); - public MIIM fMask; - public uint fType; - public uint fState; - public uint wID; - public IntPtr hSubMenu; - public IntPtr hbmpChecked; - public IntPtr hbmpUnchecked; - public IntPtr dwItemData; - public string dwTypeData = null; - public uint cch; // length of dwTypeData - public IntPtr hbmpItem; - - public MENUITEMINFO() - { - } - public MENUITEMINFO(MIIM pfMask) - { - fMask = pfMask; - } + return GetWindowLong32b(hWnd, nIndex); } - - /// - /// Custom Win32 window messages for the NotifyIcon - /// - public enum CustomWindowsMessage : uint + else { - WM_TRAYICON = (uint)WindowsMessage.WM_APP + 1024, - WM_TRAYMOUSE = (uint)WindowsMessage.WM_USER + 1024 + return GetWindowLongPtr(hWnd, nIndex); } + } - public enum SysCommands : int + [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLong")] + private static extern uint SetWindowLong32b(IntPtr hWnd, int nIndex, uint value); + + [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLongPtr")] + private static extern IntPtr SetWindowLong64b(IntPtr hWnd, int nIndex, IntPtr value); + + public static uint SetWindowLong(IntPtr hWnd, int nIndex, uint value) + { + if (IntPtr.Size == 4) { - SC_SIZE = 0xF000, - SC_MOVE = 0xF010, - SC_MINIMIZE = 0xF020, - SC_MAXIMIZE = 0xF030, - SC_NEXTWINDOW = 0xF040, - SC_PREVWINDOW = 0xF050, - SC_CLOSE = 0xF060, - SC_VSCROLL = 0xF070, - SC_HSCROLL = 0xF080, - SC_MOUSEMENU = 0xF090, - SC_KEYMENU = 0xF100, - SC_ARRANGE = 0xF110, - SC_RESTORE = 0xF120, - SC_TASKLIST = 0xF130, - SC_SCREENSAVE = 0xF140, - SC_HOTKEY = 0xF150, - //#if(WINVER >= 0x0400) //Win95 - SC_DEFAULT = 0xF160, - SC_MONITORPOWER = 0xF170, - SC_CONTEXTHELP = 0xF180, - SC_SEPARATOR = 0xF00F, - //#endif /* WINVER >= 0x0400 */ - - //#if(WINVER >= 0x0600) //Vista - SCF_ISSECURE = 0x00000001, - //#endif /* WINVER >= 0x0600 */ - - /* - * Obsolete names - */ - SC_ICON = SC_MINIMIZE, - SC_ZOOM = SC_MAXIMIZE, + return SetWindowLong32b(hWnd, nIndex, value); } - - [Flags] - public enum MIIM + else { - BITMAP = 0x00000080, - CHECKMARKS = 0x00000008, - DATA = 0x00000020, - FTYPE = 0x00000100, - ID = 0x00000002, - STATE = 0x00000001, - STRING = 0x00000040, - SUBMENU = 0x00000004, - TYPE = 0x00000010 + return (uint)SetWindowLong64b(hWnd, nIndex, new IntPtr((uint)value)).ToInt32(); } + } - [Flags] - public enum MenuFlags : uint + public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr handle) + { + if (IntPtr.Size == 4) { - MF_STRING = 0, - MF_BYPOSITION = 0x400, - MF_SEPARATOR = 0x800, - MF_REMOVE = 0x1000, + return new IntPtr(SetWindowLong32b(hWnd, nIndex, (uint)handle.ToInt32())); } - - [Flags] - public enum UFLAGS : uint + else { - TPM_LEFTALIGN = 0x0000, - TPM_CENTERALIGN = 0x0004, - TPM_RIGHTALIGN = 0x0008, - TPM_TOPALIGN = 0x0000, - TPM_VCENTERALIGN = 0x0010, - TPM_BOTTOMALIGN = 0x0020, - TPM_HORIZONTAL = 0x0000, - TPM_VERTICAL = 0x0040, - TPM_NONOTIFY = 0x0080, - TPM_RETURNCMD = 0x0100 + return SetWindowLong64b(hWnd, nIndex, handle); } + } - // End extensions for SQRLDotNetClientUI + [DllImport("user32.dll", SetLastError = true)] + public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); - public const int CW_USEDEFAULT = unchecked((int)0x80000000); + [DllImport("user32.dll")] + public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); - public delegate void TimerProc(IntPtr hWnd, uint uMsg, IntPtr nIDEvent, uint dwTime); + [DllImport("user32.dll")] + public static extern bool GetUpdateRect(IntPtr hwnd, out RECT lpRect, bool bErase); - public delegate void TimeCallback(uint uTimerID, uint uMsg, UIntPtr dwUser, UIntPtr dw1, UIntPtr dw2); + [DllImport("user32.dll")] + public static extern bool InvalidateRect(IntPtr hWnd, ref RECT lpRect, bool bErase); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - public delegate void WaitOrTimerCallback(IntPtr lpParameter, bool timerOrWaitFired); + [DllImport("user32.dll")] + public static extern bool IsWindowEnabled(IntPtr hWnd); - public delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll")] + public static extern bool IsWindowUnicode(IntPtr hWnd); - public static readonly IntPtr DPI_AWARENESS_CONTEXT_UNAWARE = new IntPtr(-1); - public static readonly IntPtr DPI_AWARENESS_CONTEXT_SYSTEM_AWARE = new IntPtr(-2); - public static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE = new IntPtr(-3); - public static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4); + [DllImport("user32.dll")] + public static extern bool IsWindowVisible(IntPtr hWnd); - public enum Cursor - { - IDC_ARROW = 32512, - IDC_IBEAM = 32513, - IDC_WAIT = 32514, - IDC_CROSS = 32515, - IDC_UPARROW = 32516, - IDC_SIZE = 32640, - IDC_ICON = 32641, - IDC_SIZENWSE = 32642, - IDC_SIZENESW = 32643, - IDC_SIZEWE = 32644, - IDC_SIZENS = 32645, - IDC_SIZEALL = 32646, - IDC_NO = 32648, - IDC_HAND = 32649, - IDC_APPSTARTING = 32650, - IDC_HELP = 32651 - } + [DllImport("user32.dll")] + public static extern bool KillTimer(IntPtr hWnd, IntPtr uIDEvent); - public enum MouseActivate : int - { - MA_ACTIVATE = 1, - MA_ACTIVATEANDEAT = 2, - MA_NOACTIVATE = 3, - MA_NOACTIVATEANDEAT = 4 - } + [DllImport("user32.dll")] + public static extern IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName); - [Flags] - public enum SetWindowPosFlags : uint - { - SWP_ASYNCWINDOWPOS = 0x4000, - SWP_DEFERERASE = 0x2000, - SWP_DRAWFRAME = 0x0020, - SWP_FRAMECHANGED = 0x0020, - SWP_HIDEWINDOW = 0x0080, - SWP_NOACTIVATE = 0x0010, - SWP_NOCOPYBITS = 0x0100, - SWP_NOMOVE = 0x0002, - SWP_NOOWNERZORDER = 0x0200, - SWP_NOREDRAW = 0x0008, - SWP_NOREPOSITION = 0x0200, - SWP_NOSENDCHANGING = 0x0400, - SWP_NOSIZE = 0x0001, - SWP_NOZORDER = 0x0004, - SWP_SHOWWINDOW = 0x0040, + [DllImport("user32.dll")] + public static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg); - SWP_RESIZE = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER - } + [DllImport("user32")] + public static extern IntPtr GetMessageExtraInfo(); - public static class WindowPosZOrder - { - public static readonly IntPtr HWND_BOTTOM = new IntPtr(1); - public static readonly IntPtr HWND_TOP = new IntPtr(0); - public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); - } + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "RegisterClassExW")] + public static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx); - public enum SizeCommand - { - Restored, - Minimized, - Maximized, - MaxShow, - MaxHide, - } + [DllImport("user32.dll")] + public static extern void RegisterTouchWindow(IntPtr hWnd, int flags); - public enum ShowWindowCommand - { - Hide = 0, - Normal = 1, - ShowMinimized = 2, - Maximize = 3, - ShowMaximized = 3, - ShowNoActivate = 4, - Show = 5, - Minimize = 6, - ShowMinNoActive = 7, - ShowNA = 8, - Restore = 9, - ShowDefault = 10, - ForceMinimize = 11 - } + [DllImport("user32.dll")] + public static extern bool ReleaseCapture(); - public enum SystemMetric - { - SM_CXSCREEN = 0, // 0x00 - SM_CYSCREEN = 1, // 0x01 - SM_CXVSCROLL = 2, // 0x02 - SM_CYHSCROLL = 3, // 0x03 - SM_CYCAPTION = 4, // 0x04 - SM_CXBORDER = 5, // 0x05 - SM_CYBORDER = 6, // 0x06 - SM_CXDLGFRAME = 7, // 0x07 - SM_CXFIXEDFRAME = 7, // 0x07 - SM_CYDLGFRAME = 8, // 0x08 - SM_CYFIXEDFRAME = 8, // 0x08 - SM_CYVTHUMB = 9, // 0x09 - SM_CXHTHUMB = 10, // 0x0A - SM_CXICON = 11, // 0x0B - SM_CYICON = 12, // 0x0C - SM_CXCURSOR = 13, // 0x0D - SM_CYCURSOR = 14, // 0x0E - SM_CYMENU = 15, // 0x0F - SM_CXFULLSCREEN = 16, // 0x10 - SM_CYFULLSCREEN = 17, // 0x11 - SM_CYKANJIWINDOW = 18, // 0x12 - SM_MOUSEPRESENT = 19, // 0x13 - SM_CYVSCROLL = 20, // 0x14 - SM_CXHSCROLL = 21, // 0x15 - SM_DEBUG = 22, // 0x16 - SM_SWAPBUTTON = 23, // 0x17 - SM_CXMIN = 28, // 0x1C - SM_CYMIN = 29, // 0x1D - SM_CXSIZE = 30, // 0x1E - SM_CYSIZE = 31, // 0x1F - SM_CXSIZEFRAME = 32, // 0x20 - SM_CXFRAME = 32, // 0x20 - SM_CYSIZEFRAME = 33, // 0x21 - SM_CYFRAME = 33, // 0x21 - SM_CXMINTRACK = 34, // 0x22 - SM_CYMINTRACK = 35, // 0x23 - SM_CXDOUBLECLK = 36, // 0x24 - SM_CYDOUBLECLK = 37, // 0x25 - SM_CXICONSPACING = 38, // 0x26 - SM_CYICONSPACING = 39, // 0x27 - SM_MENUDROPALIGNMENT = 40, // 0x28 - SM_PENWINDOWS = 41, // 0x29 - SM_DBCSENABLED = 42, // 0x2A - SM_CMOUSEBUTTONS = 43, // 0x2B - SM_SECURE = 44, // 0x2C - SM_CXEDGE = 45, // 0x2D - SM_CYEDGE = 46, // 0x2E - SM_CXMINSPACING = 47, // 0x2F - SM_CYMINSPACING = 48, // 0x30 - SM_CXSMICON = 49, // 0x31 - SM_CYSMICON = 50, // 0x32 - SM_CYSMCAPTION = 51, // 0x33 - SM_CXSMSIZE = 52, // 0x34 - SM_CYSMSIZE = 53, // 0x35 - SM_CXMENUSIZE = 54, // 0x36 - SM_CYMENUSIZE = 55, // 0x37 - SM_ARRANGE = 56, // 0x38 - SM_CXMINIMIZED = 57, // 0x39 - SM_CYMINIMIZED = 58, // 0x3A - SM_CXMAXTRACK = 59, // 0x3B - SM_CYMAXTRACK = 60, // 0x3C - SM_CXMAXIMIZED = 61, // 0x3D - SM_CYMAXIMIZED = 62, // 0x3E - SM_NETWORK = 63, // 0x3F - SM_CLEANBOOT = 67, // 0x43 - SM_CXDRAG = 68, // 0x44 - SM_CYDRAG = 69, // 0x45 - SM_SHOWSOUNDS = 70, // 0x46 - SM_CXMENUCHECK = 71, // 0x47 - SM_CYMENUCHECK = 72, // 0x48 - SM_SLOWMACHINE = 73, // 0x49 - SM_MIDEASTENABLED = 74, // 0x4A - SM_MOUSEWHEELPRESENT = 75, // 0x4B - SM_XVIRTUALSCREEN = 76, // 0x4C - SM_YVIRTUALSCREEN = 77, // 0x4D - SM_CXVIRTUALSCREEN = 78, // 0x4E - SM_CYVIRTUALSCREEN = 79, // 0x4F - SM_CMONITORS = 80, // 0x50 - SM_SAMEDISPLAYFORMAT = 81, // 0x51 - SM_IMMENABLED = 82, // 0x52 - SM_CXFOCUSBORDER = 83, // 0x53 - SM_CYFOCUSBORDER = 84, // 0x54 - SM_TABLETPC = 86, // 0x56 - SM_MEDIACENTER = 87, // 0x57 - SM_STARTER = 88, // 0x58 - SM_SERVERR2 = 89, // 0x59 - SM_MOUSEHORIZONTALWHEELPRESENT = 91, // 0x5B - SM_CXPADDEDBORDER = 92, // 0x5C - SM_DIGITIZER = 94, // 0x5E - SM_MAXIMUMTOUCHES = 95, // 0x5F + [DllImport("user32.dll")] + public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint); - SM_REMOTESESSION = 0x1000, // 0x1000 - SM_SHUTTINGDOWN = 0x2000, // 0x2000 - SM_REMOTECONTROL = 0x2001, // 0x2001 + [DllImport("user32.dll", SetLastError = true)] + public static extern IntPtr SetActiveWindow(IntPtr hWnd); - SM_CONVERTABLESLATEMODE = 0x2003, - SM_SYSTEMDOCKED = 0x2004, - } + [DllImport("user32.dll")] + public static extern IntPtr SetCapture(IntPtr hWnd); - [Flags] - public enum ModifierKeys - { - MK_CONTROL = 0x0008, + [DllImport("user32.dll")] + public static extern IntPtr SetTimer(IntPtr hWnd, IntPtr nIDEvent, uint uElapse, TimerProc lpTimerFunc); + [DllImport("user32.dll", SetLastError = true)] + public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); + [DllImport("user32.dll")] + public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags uFlags); + [DllImport("user32.dll")] + public static extern bool SetFocus(IntPtr hWnd); + [DllImport("user32.dll")] + public static extern bool SetParent(IntPtr hWnd, IntPtr hWndNewParent); + [DllImport("user32.dll")] + public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow); - MK_LBUTTON = 0x0001, + [DllImport("kernel32.dll", SetLastError = true)] + public static extern IntPtr CreateTimerQueue(); - MK_MBUTTON = 0x0010, + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool DeleteTimerQueueEx(IntPtr TimerQueue, IntPtr CompletionEvent); - MK_RBUTTON = 0x0002, + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CreateTimerQueueTimer( + out IntPtr phNewTimer, + IntPtr TimerQueue, + WaitOrTimerCallback Callback, + IntPtr Parameter, + uint DueTime, + uint Period, + uint Flags); - MK_SHIFT = 0x0004, + [DllImport("kernel32.dll", SetLastError = true)] + public static extern bool DeleteTimerQueueTimer(IntPtr TimerQueue, IntPtr Timer, IntPtr CompletionEvent); - MK_ALT = 0x0020, - - MK_XBUTTON1 = 0x0020, - - MK_XBUTTON2 = 0x0040 - } - - public enum VirtualKeyStates : int - { - VK_LBUTTON = 0x01, - VK_RBUTTON = 0x02, - VK_CANCEL = 0x03, - VK_MBUTTON = 0x04, - VK_XBUTTON1 = 0x05, - VK_XBUTTON2 = 0x06, - VK_BACK = 0x08, - VK_TAB = 0x09, - VK_CLEAR = 0x0C, - VK_RETURN = 0x0D, - VK_SHIFT = 0x10, - VK_CONTROL = 0x11, - VK_MENU = 0x12, - VK_PAUSE = 0x13, - VK_CAPITAL = 0x14, - VK_KANA = 0x15, - VK_HANGEUL = 0x15, - VK_HANGUL = 0x15, - VK_JUNJA = 0x17, - VK_FINAL = 0x18, - VK_HANJA = 0x19, - VK_KANJI = 0x19, - VK_ESCAPE = 0x1B, - VK_CONVERT = 0x1C, - VK_NONCONVERT = 0x1D, - VK_ACCEPT = 0x1E, - VK_MODECHANGE = 0x1F, - VK_SPACE = 0x20, - VK_PRIOR = 0x21, - VK_NEXT = 0x22, - VK_END = 0x23, - VK_HOME = 0x24, - VK_LEFT = 0x25, - VK_UP = 0x26, - VK_RIGHT = 0x27, - VK_DOWN = 0x28, - VK_SELECT = 0x29, - VK_PRINT = 0x2A, - VK_EXECUTE = 0x2B, - VK_SNAPSHOT = 0x2C, - VK_INSERT = 0x2D, - VK_DELETE = 0x2E, - VK_HELP = 0x2F, - VK_LWIN = 0x5B, - VK_RWIN = 0x5C, - VK_APPS = 0x5D, - VK_SLEEP = 0x5F, - VK_NUMPAD0 = 0x60, - VK_NUMPAD1 = 0x61, - VK_NUMPAD2 = 0x62, - VK_NUMPAD3 = 0x63, - VK_NUMPAD4 = 0x64, - VK_NUMPAD5 = 0x65, - VK_NUMPAD6 = 0x66, - VK_NUMPAD7 = 0x67, - VK_NUMPAD8 = 0x68, - VK_NUMPAD9 = 0x69, - VK_MULTIPLY = 0x6A, - VK_ADD = 0x6B, - VK_SEPARATOR = 0x6C, - VK_SUBTRACT = 0x6D, - VK_DECIMAL = 0x6E, - VK_DIVIDE = 0x6F, - VK_F1 = 0x70, - VK_F2 = 0x71, - VK_F3 = 0x72, - VK_F4 = 0x73, - VK_F5 = 0x74, - VK_F6 = 0x75, - VK_F7 = 0x76, - VK_F8 = 0x77, - VK_F9 = 0x78, - VK_F10 = 0x79, - VK_F11 = 0x7A, - VK_F12 = 0x7B, - VK_F13 = 0x7C, - VK_F14 = 0x7D, - VK_F15 = 0x7E, - VK_F16 = 0x7F, - VK_F17 = 0x80, - VK_F18 = 0x81, - VK_F19 = 0x82, - VK_F20 = 0x83, - VK_F21 = 0x84, - VK_F22 = 0x85, - VK_F23 = 0x86, - VK_F24 = 0x87, - VK_NUMLOCK = 0x90, - VK_SCROLL = 0x91, - VK_OEM_NEC_EQUAL = 0x92, - VK_OEM_FJ_JISHO = 0x92, - VK_OEM_FJ_MASSHOU = 0x93, - VK_OEM_FJ_TOUROKU = 0x94, - VK_OEM_FJ_LOYA = 0x95, - VK_OEM_FJ_ROYA = 0x96, - VK_LSHIFT = 0xA0, - VK_RSHIFT = 0xA1, - VK_LCONTROL = 0xA2, - VK_RCONTROL = 0xA3, - VK_LMENU = 0xA4, - VK_RMENU = 0xA5, - VK_BROWSER_BACK = 0xA6, - VK_BROWSER_FORWARD = 0xA7, - VK_BROWSER_REFRESH = 0xA8, - VK_BROWSER_STOP = 0xA9, - VK_BROWSER_SEARCH = 0xAA, - VK_BROWSER_FAVORITES = 0xAB, - VK_BROWSER_HOME = 0xAC, - VK_VOLUME_MUTE = 0xAD, - VK_VOLUME_DOWN = 0xAE, - VK_VOLUME_UP = 0xAF, - VK_MEDIA_NEXT_TRACK = 0xB0, - VK_MEDIA_PREV_TRACK = 0xB1, - VK_MEDIA_STOP = 0xB2, - VK_MEDIA_PLAY_PAUSE = 0xB3, - VK_LAUNCH_MAIL = 0xB4, - VK_LAUNCH_MEDIA_SELECT = 0xB5, - VK_LAUNCH_APP1 = 0xB6, - VK_LAUNCH_APP2 = 0xB7, - VK_OEM_1 = 0xBA, - VK_OEM_PLUS = 0xBB, - VK_OEM_COMMA = 0xBC, - VK_OEM_MINUS = 0xBD, - VK_OEM_PERIOD = 0xBE, - VK_OEM_2 = 0xBF, - VK_OEM_3 = 0xC0, - VK_OEM_4 = 0xDB, - VK_OEM_5 = 0xDC, - VK_OEM_6 = 0xDD, - VK_OEM_7 = 0xDE, - VK_OEM_8 = 0xDF, - VK_OEM_AX = 0xE1, - VK_OEM_102 = 0xE2, - VK_ICO_HELP = 0xE3, - VK_ICO_00 = 0xE4, - VK_PROCESSKEY = 0xE5, - VK_ICO_CLEAR = 0xE6, - VK_PACKET = 0xE7, - VK_OEM_RESET = 0xE9, - VK_OEM_JUMP = 0xEA, - VK_OEM_PA1 = 0xEB, - VK_OEM_PA2 = 0xEC, - VK_OEM_PA3 = 0xED, - VK_OEM_WSCTRL = 0xEE, - VK_OEM_CUSEL = 0xEF, - VK_OEM_ATTN = 0xF0, - VK_OEM_FINISH = 0xF1, - VK_OEM_COPY = 0xF2, - VK_OEM_AUTO = 0xF3, - VK_OEM_ENLW = 0xF4, - VK_OEM_BACKTAB = 0xF5, - VK_ATTN = 0xF6, - VK_CRSEL = 0xF7, - VK_EXSEL = 0xF8, - VK_EREOF = 0xF9, - VK_PLAY = 0xFA, - VK_ZOOM = 0xFB, - VK_NONAME = 0xFC, - VK_PA1 = 0xFD, - VK_OEM_CLEAR = 0xFE - } - - public enum WindowActivate - { - WA_INACTIVE, - WA_ACTIVE, - WA_CLICKACTIVE, - } - - public enum HitTestValues - { - HTERROR = -2, - HTTRANSPARENT = -1, - HTNOWHERE = 0, - HTCLIENT = 1, - HTCAPTION = 2, - HTSYSMENU = 3, - HTGROWBOX = 4, - HTMENU = 5, - HTHSCROLL = 6, - HTVSCROLL = 7, - HTMINBUTTON = 8, - HTMAXBUTTON = 9, - HTLEFT = 10, - HTRIGHT = 11, - HTTOP = 12, - HTTOPLEFT = 13, - HTTOPRIGHT = 14, - HTBOTTOM = 15, - HTBOTTOMLEFT = 16, - HTBOTTOMRIGHT = 17, - HTBORDER = 18, - HTOBJECT = 19, - HTCLOSE = 20, - HTHELP = 21 - } - - [Flags] - public enum WindowStyles : uint - { - WS_BORDER = 0x800000, - WS_CAPTION = 0xc00000, - WS_CHILD = 0x40000000, - WS_CLIPCHILDREN = 0x2000000, - WS_CLIPSIBLINGS = 0x4000000, - WS_DISABLED = 0x8000000, - WS_DLGFRAME = 0x400000, - WS_GROUP = 0x20000, - WS_HSCROLL = 0x100000, - WS_MAXIMIZE = 0x1000000, - WS_MAXIMIZEBOX = 0x10000, - WS_MINIMIZE = 0x20000000, - WS_MINIMIZEBOX = 0x20000, - WS_OVERLAPPED = 0x0, - WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_SIZEFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX, - WS_POPUP = 0x80000000u, - WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU, - WS_SIZEFRAME = 0x40000, - WS_SYSMENU = 0x80000, - WS_TABSTOP = 0x10000, - WS_VISIBLE = 0x10000000, - WS_VSCROLL = 0x200000, - WS_EX_DLGMODALFRAME = 0x00000001, - WS_EX_NOPARENTNOTIFY = 0x00000004, - WS_EX_TOPMOST = 0x00000008, - WS_EX_ACCEPTFILES = 0x00000010, - WS_EX_TRANSPARENT = 0x00000020, - WS_EX_MDICHILD = 0x00000040, - WS_EX_TOOLWINDOW = 0x00000080, - WS_EX_WINDOWEDGE = 0x00000100, - WS_EX_CLIENTEDGE = 0x00000200, - WS_EX_CONTEXTHELP = 0x00000400, - WS_EX_RIGHT = 0x00001000, - WS_EX_LEFT = 0x00000000, - WS_EX_RTLREADING = 0x00002000, - WS_EX_LTRREADING = 0x00000000, - WS_EX_LEFTSCROLLBAR = 0x00004000, - WS_EX_RIGHTSCROLLBAR = 0x00000000, - WS_EX_CONTROLPARENT = 0x00010000, - WS_EX_STATICEDGE = 0x00020000, - WS_EX_APPWINDOW = 0x00040000, - WS_EX_OVERLAPPEDWINDOW = WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE, - WS_EX_PALETTEWINDOW = WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST, - WS_EX_LAYERED = 0x00080000, - WS_EX_NOINHERITLAYOUT = 0x00100000, - WS_EX_LAYOUTRTL = 0x00400000, - WS_EX_COMPOSITED = 0x02000000, - WS_EX_NOACTIVATE = 0x08000000 - } - - [Flags] - public enum ClassStyles : uint - { - CS_VREDRAW = 0x0001, - CS_HREDRAW = 0x0002, - CS_DBLCLKS = 0x0008, - CS_OWNDC = 0x0020, - CS_CLASSDC = 0x0040, - CS_PARENTDC = 0x0080, - CS_NOCLOSE = 0x0200, - CS_SAVEBITS = 0x0800, - CS_BYTEALIGNCLIENT = 0x1000, - CS_BYTEALIGNWINDOW = 0x2000, - CS_GLOBALCLASS = 0x4000, - CS_IME = 0x00010000, - CS_DROPSHADOW = 0x00020000 - } - - public enum WindowsMessage : uint - { - WM_NULL = 0x0000, - WM_CREATE = 0x0001, - WM_DESTROY = 0x0002, - WM_MOVE = 0x0003, - WM_SIZE = 0x0005, - WM_ACTIVATE = 0x0006, - WM_SETFOCUS = 0x0007, - WM_KILLFOCUS = 0x0008, - WM_ENABLE = 0x000A, - WM_SETREDRAW = 0x000B, - WM_SETTEXT = 0x000C, - WM_GETTEXT = 0x000D, - WM_GETTEXTLENGTH = 0x000E, - WM_PAINT = 0x000F, - WM_CLOSE = 0x0010, - WM_QUERYENDSESSION = 0x0011, - WM_QUERYOPEN = 0x0013, - WM_ENDSESSION = 0x0016, - WM_QUIT = 0x0012, - WM_ERASEBKGND = 0x0014, - WM_SYSCOLORCHANGE = 0x0015, - WM_SHOWWINDOW = 0x0018, - WM_WININICHANGE = 0x001A, - WM_SETTINGCHANGE = WM_WININICHANGE, - WM_DEVMODECHANGE = 0x001B, - WM_ACTIVATEAPP = 0x001C, - WM_FONTCHANGE = 0x001D, - WM_TIMECHANGE = 0x001E, - WM_CANCELMODE = 0x001F, - WM_SETCURSOR = 0x0020, - WM_MOUSEACTIVATE = 0x0021, - WM_CHILDACTIVATE = 0x0022, - WM_QUEUESYNC = 0x0023, - WM_GETMINMAXINFO = 0x0024, - WM_PAINTICON = 0x0026, - WM_ICONERASEBKGND = 0x0027, - WM_NEXTDLGCTL = 0x0028, - WM_SPOOLERSTATUS = 0x002A, - WM_DRAWITEM = 0x002B, - WM_MEASUREITEM = 0x002C, - WM_DELETEITEM = 0x002D, - WM_VKEYTOITEM = 0x002E, - WM_CHARTOITEM = 0x002F, - WM_SETFONT = 0x0030, - WM_GETFONT = 0x0031, - WM_SETHOTKEY = 0x0032, - WM_GETHOTKEY = 0x0033, - WM_QUERYDRAGICON = 0x0037, - WM_COMPAREITEM = 0x0039, - WM_GETOBJECT = 0x003D, - WM_COMPACTING = 0x0041, - WM_WINDOWPOSCHANGING = 0x0046, - WM_WINDOWPOSCHANGED = 0x0047, - WM_COPYDATA = 0x004A, - WM_CANCELJOURNAL = 0x004B, - WM_NOTIFY = 0x004E, - WM_INPUTLANGCHANGEREQUEST = 0x0050, - WM_INPUTLANGCHANGE = 0x0051, - WM_TCARD = 0x0052, - WM_HELP = 0x0053, - WM_USERCHANGED = 0x0054, - WM_NOTIFYFORMAT = 0x0055, - WM_CONTEXTMENU = 0x007B, - WM_STYLECHANGING = 0x007C, - WM_STYLECHANGED = 0x007D, - WM_DISPLAYCHANGE = 0x007E, - WM_GETICON = 0x007F, - WM_SETICON = 0x0080, - WM_NCCREATE = 0x0081, - WM_NCDESTROY = 0x0082, - WM_NCCALCSIZE = 0x0083, - WM_NCHITTEST = 0x0084, - WM_NCPAINT = 0x0085, - WM_NCACTIVATE = 0x0086, - WM_GETDLGCODE = 0x0087, - WM_SYNCPAINT = 0x0088, - WM_NCMOUSEMOVE = 0x00A0, - WM_NCLBUTTONDOWN = 0x00A1, - WM_NCLBUTTONUP = 0x00A2, - WM_NCLBUTTONDBLCLK = 0x00A3, - WM_NCRBUTTONDOWN = 0x00A4, - WM_NCRBUTTONUP = 0x00A5, - WM_NCRBUTTONDBLCLK = 0x00A6, - WM_NCMBUTTONDOWN = 0x00A7, - WM_NCMBUTTONUP = 0x00A8, - WM_NCMBUTTONDBLCLK = 0x00A9, - WM_NCXBUTTONDOWN = 0x00AB, - WM_NCXBUTTONUP = 0x00AC, - WM_NCXBUTTONDBLCLK = 0x00AD, - WM_INPUT_DEVICE_CHANGE = 0x00FE, - WM_INPUT = 0x00FF, - WM_KEYFIRST = 0x0100, - WM_KEYDOWN = 0x0100, - WM_KEYUP = 0x0101, - WM_CHAR = 0x0102, - WM_DEADCHAR = 0x0103, - WM_SYSKEYDOWN = 0x0104, - WM_SYSKEYUP = 0x0105, - WM_SYSCHAR = 0x0106, - WM_SYSDEADCHAR = 0x0107, - WM_UNICHAR = 0x0109, - WM_KEYLAST = 0x0109, - WM_IME_STARTCOMPOSITION = 0x010D, - WM_IME_ENDCOMPOSITION = 0x010E, - WM_IME_COMPOSITION = 0x010F, - WM_IME_KEYLAST = 0x010F, - WM_INITDIALOG = 0x0110, - WM_COMMAND = 0x0111, - WM_SYSCOMMAND = 0x0112, - WM_TIMER = 0x0113, - WM_HSCROLL = 0x0114, - WM_VSCROLL = 0x0115, - WM_INITMENU = 0x0116, - WM_INITMENUPOPUP = 0x0117, - WM_MENUSELECT = 0x011F, - WM_MENUCHAR = 0x0120, - WM_ENTERIDLE = 0x0121, - WM_MENURBUTTONUP = 0x0122, - WM_MENUDRAG = 0x0123, - WM_MENUGETOBJECT = 0x0124, - WM_UNINITMENUPOPUP = 0x0125, - WM_MENUCOMMAND = 0x0126, - WM_CHANGEUISTATE = 0x0127, - WM_UPDATEUISTATE = 0x0128, - WM_QUERYUISTATE = 0x0129, - WM_CTLCOLORMSGBOX = 0x0132, - WM_CTLCOLOREDIT = 0x0133, - WM_CTLCOLORLISTBOX = 0x0134, - WM_CTLCOLORBTN = 0x0135, - WM_CTLCOLORDLG = 0x0136, - WM_CTLCOLORSCROLLBAR = 0x0137, - WM_CTLCOLORSTATIC = 0x0138, - WM_MOUSEFIRST = 0x0200, - WM_MOUSEMOVE = 0x0200, - WM_LBUTTONDOWN = 0x0201, - WM_LBUTTONUP = 0x0202, - WM_LBUTTONDBLCLK = 0x0203, - WM_RBUTTONDOWN = 0x0204, - WM_RBUTTONUP = 0x0205, - WM_RBUTTONDBLCLK = 0x0206, - WM_MBUTTONDOWN = 0x0207, - WM_MBUTTONUP = 0x0208, - WM_MBUTTONDBLCLK = 0x0209, - WM_MOUSEWHEEL = 0x020A, - WM_XBUTTONDOWN = 0x020B, - WM_XBUTTONUP = 0x020C, - WM_XBUTTONDBLCLK = 0x020D, - WM_MOUSEHWHEEL = 0x020E, - WM_MOUSELAST = 0x020E, - WM_PARENTNOTIFY = 0x0210, - WM_ENTERMENULOOP = 0x0211, - WM_EXITMENULOOP = 0x0212, - WM_NEXTMENU = 0x0213, - WM_SIZING = 0x0214, - WM_CAPTURECHANGED = 0x0215, - WM_MOVING = 0x0216, - WM_POWERBROADCAST = 0x0218, - WM_DEVICECHANGE = 0x0219, - WM_MDICREATE = 0x0220, - WM_MDIDESTROY = 0x0221, - WM_MDIACTIVATE = 0x0222, - WM_MDIRESTORE = 0x0223, - WM_MDINEXT = 0x0224, - WM_MDIMAXIMIZE = 0x0225, - WM_MDITILE = 0x0226, - WM_MDICASCADE = 0x0227, - WM_MDIICONARRANGE = 0x0228, - WM_MDIGETACTIVE = 0x0229, - WM_MDISETMENU = 0x0230, - WM_ENTERSIZEMOVE = 0x0231, - WM_EXITSIZEMOVE = 0x0232, - WM_DROPFILES = 0x0233, - WM_MDIREFRESHMENU = 0x0234, - WM_IME_SETCONTEXT = 0x0281, - WM_IME_NOTIFY = 0x0282, - WM_IME_CONTROL = 0x0283, - WM_IME_COMPOSITIONFULL = 0x0284, - WM_IME_SELECT = 0x0285, - WM_IME_CHAR = 0x0286, - WM_IME_REQUEST = 0x0288, - WM_IME_KEYDOWN = 0x0290, - WM_IME_KEYUP = 0x0291, - WM_MOUSEHOVER = 0x02A1, - WM_MOUSELEAVE = 0x02A3, - WM_NCMOUSEHOVER = 0x02A0, - WM_NCMOUSELEAVE = 0x02A2, - WM_WTSSESSION_CHANGE = 0x02B1, - WM_TABLET_FIRST = 0x02c0, - WM_TABLET_LAST = 0x02df, - WM_DPICHANGED = 0x02E0, - WM_CUT = 0x0300, - WM_COPY = 0x0301, - WM_PASTE = 0x0302, - WM_CLEAR = 0x0303, - WM_UNDO = 0x0304, - WM_RENDERFORMAT = 0x0305, - WM_RENDERALLFORMATS = 0x0306, - WM_DESTROYCLIPBOARD = 0x0307, - WM_DRAWCLIPBOARD = 0x0308, - WM_PAINTCLIPBOARD = 0x0309, - WM_VSCROLLCLIPBOARD = 0x030A, - WM_SIZECLIPBOARD = 0x030B, - WM_ASKCBFORMATNAME = 0x030C, - WM_CHANGECBCHAIN = 0x030D, - WM_HSCROLLCLIPBOARD = 0x030E, - WM_QUERYNEWPALETTE = 0x030F, - WM_PALETTEISCHANGING = 0x0310, - WM_PALETTECHANGED = 0x0311, - WM_HOTKEY = 0x0312, - WM_PRINT = 0x0317, - WM_PRINTCLIENT = 0x0318, - WM_APPCOMMAND = 0x0319, - WM_THEMECHANGED = 0x031A, - WM_CLIPBOARDUPDATE = 0x031D, - WM_DWMCOMPOSITIONCHANGED = 0x031E, - WM_DWMNCRENDERINGCHANGED = 0x031F, - WM_DWMCOLORIZATIONCOLORCHANGED = 0x0320, - WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321, - WM_GETTITLEBARINFOEX = 0x033F, - WM_HANDHELDFIRST = 0x0358, - WM_HANDHELDLAST = 0x035F, - WM_AFXFIRST = 0x0360, - WM_AFXLAST = 0x037F, - WM_PENWINFIRST = 0x0380, - WM_PENWINLAST = 0x038F, - WM_TOUCH = 0x0240, - WM_APP = 0x8000, - WM_USER = 0x0400, - - WM_DISPATCH_WORK_ITEM = WM_USER, - } - - public enum MapVirtualKeyMapTypes : uint - { - MAPVK_VK_TO_VSC = 0x00, - MAPVK_VSC_TO_VK = 0x01, - MAPVK_VK_TO_CHAR = 0x02, - MAPVK_VSC_TO_VK_EX = 0x03, - } - - public enum BitmapCompressionMode : uint - { - BI_RGB = 0, - BI_RLE8 = 1, - BI_RLE4 = 2, - BI_BITFIELDS = 3, - BI_JPEG = 4, - BI_PNG = 5 - } - - public enum DIBColorTable - { - DIB_RGB_COLORS = 0, /* color table in RGBs */ - DIB_PAL_COLORS /* color table in palette indices */ - } - - public enum WindowLongParam - { - GWL_WNDPROC = -4, - GWL_HINSTANCE = -6, - GWL_HWNDPARENT = -8, - GWL_ID = -12, - GWL_STYLE = -16, - GWL_EXSTYLE = -20, - GWL_USERDATA = -21 - } - - public enum MenuCharParam - { - MNC_IGNORE = 0, - MNC_CLOSE = 1, - MNC_EXECUTE = 2, - MNC_SELECT = 3 - } - - [StructLayout(LayoutKind.Sequential)] - public struct RGBQUAD - { - public byte rgbBlue; - public byte rgbGreen; - public byte rgbRed; - public byte rgbReserved; - } - - [StructLayout(LayoutKind.Sequential)] - public struct BITMAPINFOHEADER - { - public uint biSize; - public int biWidth; - public int biHeight; - public ushort biPlanes; - public ushort biBitCount; - public uint biCompression; - public uint biSizeImage; - public int biXPelsPerMeter; - public int biYPelsPerMeter; - public uint biClrUsed; - public uint biClrImportant; - - public void Init() - { - biSize = (uint)Marshal.SizeOf(this); - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct BITMAPINFO - { - // C# cannot inlay structs in structs so must expand directly here - // - //[StructLayout(LayoutKind.Sequential)] - //public struct BITMAPINFOHEADER - //{ - public uint biSize; - public int biWidth; - public int biHeight; - public ushort biPlanes; - public ushort biBitCount; - public BitmapCompressionMode biCompression; - public uint biSizeImage; - public int biXPelsPerMeter; - public int biYPelsPerMeter; - public uint biClrUsed; - public uint biClrImportant; - //} - - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] - public uint[] cols; - } - - [StructLayout(LayoutKind.Sequential)] - public struct MINMAXINFO - { - public POINT ptReserved; - public POINT ptMaxSize; - public POINT ptMaxPosition; - public POINT ptMinTrackSize; - public POINT ptMaxTrackSize; - } - - public const int SizeOf_BITMAPINFOHEADER = 40; - - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr GetDC(IntPtr hWnd); - - [DllImport("gdi32.dll")] - public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest, - uint dwWidth, uint dwHeight, - int XSrc, int YSrc, - uint uStartScan, uint cScanLines, - IntPtr lpvBits, [In] ref BITMAPINFO lpbmi, uint fuColorUse); - - [DllImport("user32.dll")] - public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC); - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool AdjustWindowRectEx(ref RECT lpRect, uint dwStyle, bool bMenu, uint dwExStyle); - - [DllImport("user32.dll")] - public static extern IntPtr BeginPaint(IntPtr hwnd, out PAINTSTRUCT lpPaint); - - [DllImport("user32.dll")] - public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint); - - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr CreateWindowEx( - int dwExStyle, - uint lpClassName, - string lpWindowName, - uint dwStyle, - int x, - int y, - int nWidth, - int nHeight, - IntPtr hWndParent, - IntPtr hMenu, - IntPtr hInstance, - IntPtr lpParam); - - [DllImport("user32.dll", EntryPoint = "DefWindowProcW")] - public static extern IntPtr DefWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); - - [DllImport("user32.dll", EntryPoint = "DispatchMessageW")] - public static extern IntPtr DispatchMessage(ref MSG lpmsg); - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool DestroyWindow(IntPtr hwnd); - - [DllImport("user32.dll")] - public static extern bool EnableWindow(IntPtr hWnd, bool bEnable); - - [DllImport("user32.dll")] - public static extern bool EndPaint(IntPtr hWnd, ref PAINTSTRUCT lpPaint); - - [DllImport("user32.dll")] - public static extern uint GetCaretBlinkTime(); - - [DllImport("user32.dll")] - public static extern bool GetClientRect(IntPtr hwnd, out RECT lpRect); - - [DllImport("user32.dll")] - public static extern bool GetCursorPos(out POINT lpPoint); - - [DllImport("user32.dll")] - public static extern uint GetDoubleClickTime(); - - [DllImport("user32.dll")] - public static extern bool GetKeyboardState(byte[] lpKeyState); - - [DllImport("user32.dll", EntryPoint = "MapVirtualKeyW")] - public static extern uint MapVirtualKey(uint uCode, uint uMapType); - - [DllImport("user32.dll", EntryPoint = "GetMessageW")] - public static extern sbyte GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); - - [DllImport("user32.dll")] - public static extern int GetMessageTime(); - - [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr GetModuleHandle(string lpModuleName); - - [DllImport("user32.dll")] - public static extern int GetSystemMetrics(SystemMetric smIndex); - - [DllImport("user32.dll", SetLastError = true)] - public static extern uint GetWindowLongPtr(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetWindowLong")] - public static extern uint GetWindowLong32b(IntPtr hWnd, int nIndex); - - public static uint GetWindowLong(IntPtr hWnd, int nIndex) - { - if (IntPtr.Size == 4) - { - return GetWindowLong32b(hWnd, nIndex); - } - else - { - return GetWindowLongPtr(hWnd, nIndex); - } - } - - [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLong")] - private static extern uint SetWindowLong32b(IntPtr hWnd, int nIndex, uint value); - - [DllImport("user32.dll", SetLastError = true, EntryPoint = "SetWindowLongPtr")] - private static extern IntPtr SetWindowLong64b(IntPtr hWnd, int nIndex, IntPtr value); - - public static uint SetWindowLong(IntPtr hWnd, int nIndex, uint value) - { - if (IntPtr.Size == 4) - { - return SetWindowLong32b(hWnd, nIndex, value); - } - else - { - return (uint)SetWindowLong64b(hWnd, nIndex, new IntPtr((uint)value)).ToInt32(); - } - } - - public static IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr handle) - { - if (IntPtr.Size == 4) - { - return new IntPtr(SetWindowLong32b(hWnd, nIndex, (uint)handle.ToInt32())); - } - else - { - return SetWindowLong64b(hWnd, nIndex, handle); - } - } - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl); - - [DllImport("user32.dll")] - public static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect); - - [DllImport("user32.dll")] - public static extern bool GetUpdateRect(IntPtr hwnd, out RECT lpRect, bool bErase); - - [DllImport("user32.dll")] - public static extern bool InvalidateRect(IntPtr hWnd, ref RECT lpRect, bool bErase); - - [DllImport("user32.dll")] - public static extern bool IsWindowEnabled(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern bool IsWindowUnicode(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern bool IsWindowVisible(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern bool KillTimer(IntPtr hWnd, IntPtr uIDEvent); - - [DllImport("user32.dll")] - public static extern IntPtr LoadCursor(IntPtr hInstance, IntPtr lpCursorName); - - [DllImport("user32.dll")] - public static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg); - - [DllImport("user32")] - public static extern IntPtr GetMessageExtraInfo(); - - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "RegisterClassExW")] - public static extern ushort RegisterClassEx(ref WNDCLASSEX lpwcx); - - [DllImport("user32.dll")] - public static extern void RegisterTouchWindow(IntPtr hWnd, int flags); - - [DllImport("user32.dll")] - public static extern bool ReleaseCapture(); - - [DllImport("user32.dll")] - public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint); - - [DllImport("user32.dll", SetLastError = true)] - public static extern IntPtr SetActiveWindow(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern IntPtr SetCapture(IntPtr hWnd); - - [DllImport("user32.dll")] - public static extern IntPtr SetTimer(IntPtr hWnd, IntPtr nIDEvent, uint uElapse, TimerProc lpTimerFunc); - [DllImport("user32.dll", SetLastError = true)] - public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); - [DllImport("user32.dll")] - public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, SetWindowPosFlags uFlags); - [DllImport("user32.dll")] - public static extern bool SetFocus(IntPtr hWnd); - [DllImport("user32.dll")] - public static extern bool SetParent(IntPtr hWnd, IntPtr hWndNewParent); - [DllImport("user32.dll")] - public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommand nCmdShow); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern IntPtr CreateTimerQueue(); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool DeleteTimerQueueEx(IntPtr TimerQueue, IntPtr CompletionEvent); - - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool CreateTimerQueueTimer( - out IntPtr phNewTimer, - IntPtr TimerQueue, - WaitOrTimerCallback Callback, - IntPtr Parameter, - uint DueTime, - uint Period, - uint Flags); - - [DllImport("kernel32.dll", SetLastError = true)] - public static extern bool DeleteTimerQueueTimer(IntPtr TimerQueue, IntPtr Timer, IntPtr CompletionEvent); - - [DllImport("user32.dll")] - public static extern int ToUnicode( - uint virtualKeyCode, - uint scanCode, - byte[] keyboardState, - [Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)] + [DllImport("user32.dll")] + public static extern int ToUnicode( + uint virtualKeyCode, + uint scanCode, + byte[] keyboardState, + [Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = 64)] StringBuilder receivingBuffer, - int bufferSize, - uint flags); + int bufferSize, + uint flags); - [DllImport("user32.dll", SetLastError = true)] - public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack); + [DllImport("user32.dll", SetLastError = true)] + public static extern bool TrackMouseEvent(ref TRACKMOUSEEVENT lpEventTrack); - [DllImport("user32.dll")] - public static extern bool TranslateMessage(ref MSG lpMsg); + [DllImport("user32.dll")] + public static extern bool TranslateMessage(ref MSG lpMsg); - [DllImport("user32.dll", CharSet = CharSet.Unicode)] - public static extern bool UnregisterClass(string lpClassName, IntPtr hInstance); + [DllImport("user32.dll", CharSet = CharSet.Unicode)] + public static extern bool UnregisterClass(string lpClassName, IntPtr hInstance); - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetWindowTextW")] - public static extern bool SetWindowText(IntPtr hwnd, string lpString); + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetWindowTextW")] + public static extern bool SetWindowText(IntPtr hwnd, string lpString); - public enum ClassLongIndex : int + public enum ClassLongIndex : int + { + GCLP_MENUNAME = -8, + GCLP_HBRBACKGROUND = -10, + GCLP_HCURSOR = -12, + GCLP_HICON = -14, + GCLP_HMODULE = -16, + GCL_CBWNDEXTRA = -18, + GCL_CBCLSEXTRA = -20, + GCLP_WNDPROC = -24, + GCL_STYLE = -26, + GCLP_HICONSM = -34, + GCW_ATOM = -32 + } + + [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")] + private static extern IntPtr SetClassLong64(IntPtr hWnd, ClassLongIndex nIndex, IntPtr dwNewLong); + + [DllImport("user32.dll", EntryPoint = "SetClassLong")] + private static extern IntPtr SetClassLong32(IntPtr hWnd, ClassLongIndex nIndex, IntPtr dwNewLong); + + public static IntPtr SetClassLong(IntPtr hWnd, ClassLongIndex nIndex, IntPtr dwNewLong) + { + if (IntPtr.Size == 4) { - GCLP_MENUNAME = -8, - GCLP_HBRBACKGROUND = -10, - GCLP_HCURSOR = -12, - GCLP_HICON = -14, - GCLP_HMODULE = -16, - GCL_CBWNDEXTRA = -18, - GCL_CBCLSEXTRA = -20, - GCLP_WNDPROC = -24, - GCL_STYLE = -26, - GCLP_HICONSM = -34, - GCW_ATOM = -32 + return SetClassLong32(hWnd, nIndex, dwNewLong); } - [DllImport("user32.dll", EntryPoint = "SetClassLongPtr")] - private static extern IntPtr SetClassLong64(IntPtr hWnd, ClassLongIndex nIndex, IntPtr dwNewLong); + return SetClassLong64(hWnd, nIndex, dwNewLong); + } - [DllImport("user32.dll", EntryPoint = "SetClassLong")] - private static extern IntPtr SetClassLong32(IntPtr hWnd, ClassLongIndex nIndex, IntPtr dwNewLong); + public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) + { + if (IntPtr.Size > 4) + return GetClassLongPtr64(hWnd, nIndex); + else + return new IntPtr(GetClassLongPtr32(hWnd, nIndex)); + } - public static IntPtr SetClassLong(IntPtr hWnd, ClassLongIndex nIndex, IntPtr dwNewLong) + [DllImport("user32.dll", EntryPoint = "GetClassLong")] + public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] + public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); + + [DllImport("user32.dll", EntryPoint = "SetCursor")] + internal static extern IntPtr SetCursor(IntPtr hCursor); + + [DllImport("ole32.dll", PreserveSig = true)] + internal static extern int CoCreateInstance(ref Guid clsid, + IntPtr ignore1, int ignore2, ref Guid iid, [MarshalAs(UnmanagedType.IUnknown), Out] out object pUnkOuter); + + [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool OpenClipboard(IntPtr hWndOwner); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool CloseClipboard(); + + [DllImport("user32.dll")] + public static extern bool EmptyClipboard(); + + [DllImport("user32.dll")] + public static extern IntPtr GetClipboardData(ClipboardFormat uFormat); + + [DllImport("user32.dll")] + public static extern IntPtr SetClipboardData(ClipboardFormat uFormat, IntPtr hMem); + + [DllImport("kernel32.dll", ExactSpelling = true)] + public static extern IntPtr GlobalLock(IntPtr handle); + + [DllImport("kernel32.dll", ExactSpelling = true)] + public static extern bool GlobalUnlock(IntPtr handle); + + [DllImport("kernel32.dll", ExactSpelling = true)] + public static extern IntPtr GlobalAlloc(int uFlags, int dwBytes); + + [DllImport("kernel32.dll", ExactSpelling = true)] + public static extern IntPtr GlobalFree(IntPtr hMem); + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr LoadLibrary(string fileName); + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); + + [DllImport("comdlg32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetSaveFileNameW")] + public static extern bool GetSaveFileName(IntPtr lpofn); + + [DllImport("comdlg32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetOpenFileNameW")] + public static extern bool GetOpenFileName(IntPtr lpofn); + + [DllImport("comdlg32.dll")] + public static extern int CommDlgExtendedError(); + + public static bool ShCoreAvailable => LoadLibrary("shcore.dll") != IntPtr.Zero; + + [DllImport("shcore.dll")] + public static extern void SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SetProcessDpiAwarenessContext(IntPtr dpiAWarenessContext); + + [DllImport("shcore.dll")] + public static extern long GetDpiForMonitor(IntPtr hmonitor, MONITOR_DPI_TYPE dpiType, out uint dpiX, out uint dpiY); + + [DllImport("gdi32.dll")] + public static extern int GetDeviceCaps(IntPtr hdc, DEVICECAP nIndex); + + [DllImport("shcore.dll")] + public static extern void GetScaleFactorForMonitor(IntPtr hMon, out uint pScale); + + [DllImport("user32.dll", SetLastError = true)] + public static extern bool SetProcessDPIAware(); + + [DllImport("user32.dll")] + public static extern IntPtr MonitorFromPoint(POINT pt, MONITOR dwFlags); + + [DllImport("user32.dll")] + public static extern IntPtr MonitorFromRect(RECT rect, MONITOR dwFlags); + + [DllImport("user32.dll")] + public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags); + + [DllImport("user32", EntryPoint = "GetMonitorInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetMonitorInfo([In] IntPtr hMonitor, ref MONITORINFO lpmi); + + [DllImport("user32")] + public static extern bool CloseTouchInputHandle(IntPtr hTouchInput); + + [return: MarshalAs(UnmanagedType.Bool)] + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PostMessageW")] + public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); + + [DllImport("gdi32.dll")] + public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest, uint + dwWidth, uint dwHeight, int XSrc, int YSrc, uint uStartScan, uint cScanLines, + IntPtr lpvBits, [In] ref BITMAPINFOHEADER lpbmi, uint fuColorUse); + + [DllImport("kernel32.dll", SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool CloseHandle(IntPtr hObject); + [DllImport("gdi32.dll", SetLastError = true)] + public static extern IntPtr CreateDIBSection(IntPtr hDC, ref BITMAPINFOHEADER pBitmapInfo, int un, out IntPtr lplpVoid, IntPtr handle, int dw); + [DllImport("gdi32.dll")] + public static extern int DeleteObject(IntPtr hObject); + [DllImport("gdi32.dll", SetLastError = true)] + public static extern IntPtr CreateCompatibleDC(IntPtr hdc); + [DllImport("gdi32.dll")] + public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); + + [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] + public static extern IntPtr CreateFileMapping(IntPtr hFile, + IntPtr lpFileMappingAttributes, + uint flProtect, + uint dwMaximumSizeHigh, + uint dwMaximumSizeLow, + string lpName); + + [DllImport("msvcrt.dll", EntryPoint = "memcpy", SetLastError = false, CallingConvention = CallingConvention.Cdecl)] + public static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, UIntPtr count); + + [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern HRESULT RegisterDragDrop(IntPtr hwnd, IDropTarget target); + + [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + public static extern HRESULT RevokeDragDrop(IntPtr hwnd); + + [DllImport("ole32.dll", EntryPoint = "OleInitialize")] + public static extern HRESULT OleInitialize(IntPtr val); + + [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] + internal static extern void ReleaseStgMedium(ref STGMEDIUM medium); + + [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)] + public static extern int GetClipboardFormatName(int format, StringBuilder lpString, int cchMax); + + [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)] + public static extern int RegisterClipboardFormat(string format); + + [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true, SetLastError = true)] + public static extern IntPtr GlobalSize(IntPtr hGlobal); + + [DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto)] + public static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder lpszFile, int cch); + + [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true, PreserveSig = false)] + internal static extern void DoDragDrop(IOleDataObject dataObject, IDropSource dropSource, int allowedEffects, out int finalEffect); + + public enum MONITOR + { + MONITOR_DEFAULTTONULL = 0x00000000, + MONITOR_DEFAULTTOPRIMARY = 0x00000001, + MONITOR_DEFAULTTONEAREST = 0x00000002, + } + + [StructLayout(LayoutKind.Sequential)] + internal struct MONITORINFO + { + public int cbSize; + public RECT rcMonitor; + public RECT rcWork; + public int dwFlags; + + public static MONITORINFO Create() { - if (IntPtr.Size == 4) - { - return SetClassLong32(hWnd, nIndex, dwNewLong); - } - - return SetClassLong64(hWnd, nIndex, dwNewLong); + return new MONITORINFO() { cbSize = Marshal.SizeOf() }; } - public static IntPtr GetClassLongPtr(IntPtr hWnd, int nIndex) - { - if (IntPtr.Size > 4) - return GetClassLongPtr64(hWnd, nIndex); - else - return new IntPtr(GetClassLongPtr32(hWnd, nIndex)); - } - - [DllImport("user32.dll", EntryPoint = "GetClassLong")] - public static extern uint GetClassLongPtr32(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll", EntryPoint = "GetClassLongPtr")] - public static extern IntPtr GetClassLongPtr64(IntPtr hWnd, int nIndex); - - [DllImport("user32.dll", EntryPoint = "SetCursor")] - internal static extern IntPtr SetCursor(IntPtr hCursor); - - [DllImport("ole32.dll", PreserveSig = true)] - internal static extern int CoCreateInstance(ref Guid clsid, - IntPtr ignore1, int ignore2, ref Guid iid, [MarshalAs(UnmanagedType.IUnknown), Out] out object pUnkOuter); - - [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv); - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool OpenClipboard(IntPtr hWndOwner); - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool CloseClipboard(); - - [DllImport("user32.dll")] - public static extern bool EmptyClipboard(); - - [DllImport("user32.dll")] - public static extern IntPtr GetClipboardData(ClipboardFormat uFormat); - - [DllImport("user32.dll")] - public static extern IntPtr SetClipboardData(ClipboardFormat uFormat, IntPtr hMem); - - [DllImport("kernel32.dll", ExactSpelling = true)] - public static extern IntPtr GlobalLock(IntPtr handle); - - [DllImport("kernel32.dll", ExactSpelling = true)] - public static extern bool GlobalUnlock(IntPtr handle); - - [DllImport("kernel32.dll", ExactSpelling = true)] - public static extern IntPtr GlobalAlloc(int uFlags, int dwBytes); - - [DllImport("kernel32.dll", ExactSpelling = true)] - public static extern IntPtr GlobalFree(IntPtr hMem); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr LoadLibrary(string fileName); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); - - [DllImport("comdlg32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetSaveFileNameW")] - public static extern bool GetSaveFileName(IntPtr lpofn); - - [DllImport("comdlg32.dll", CharSet = CharSet.Unicode, EntryPoint = "GetOpenFileNameW")] - public static extern bool GetOpenFileName(IntPtr lpofn); - - [DllImport("comdlg32.dll")] - public static extern int CommDlgExtendedError(); - - public static bool ShCoreAvailable => LoadLibrary("shcore.dll") != IntPtr.Zero; - - [DllImport("shcore.dll")] - public static extern void SetProcessDpiAwareness(PROCESS_DPI_AWARENESS value); - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool SetProcessDpiAwarenessContext(IntPtr dpiAWarenessContext); - - [DllImport("shcore.dll")] - public static extern long GetDpiForMonitor(IntPtr hmonitor, MONITOR_DPI_TYPE dpiType, out uint dpiX, out uint dpiY); - - [DllImport("gdi32.dll")] - public static extern int GetDeviceCaps(IntPtr hdc, DEVICECAP nIndex); - - [DllImport("shcore.dll")] - public static extern void GetScaleFactorForMonitor(IntPtr hMon, out uint pScale); - - [DllImport("user32.dll", SetLastError = true)] - public static extern bool SetProcessDPIAware(); - - [DllImport("user32.dll")] - public static extern IntPtr MonitorFromPoint(POINT pt, MONITOR dwFlags); - - [DllImport("user32.dll")] - public static extern IntPtr MonitorFromRect(RECT rect, MONITOR dwFlags); - - [DllImport("user32.dll")] - public static extern IntPtr MonitorFromWindow(IntPtr hwnd, MONITOR dwFlags); - - [DllImport("user32", EntryPoint = "GetMonitorInfoW", ExactSpelling = true, CharSet = CharSet.Unicode)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool GetMonitorInfo([In] IntPtr hMonitor, ref MONITORINFO lpmi); - - [DllImport("user32")] - public static extern bool CloseTouchInputHandle(IntPtr hTouchInput); - - [return: MarshalAs(UnmanagedType.Bool)] - [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "PostMessageW")] - public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); - - [DllImport("gdi32.dll")] - public static extern int SetDIBitsToDevice(IntPtr hdc, int XDest, int YDest, uint - dwWidth, uint dwHeight, int XSrc, int YSrc, uint uStartScan, uint cScanLines, - IntPtr lpvBits, [In] ref BITMAPINFOHEADER lpbmi, uint fuColorUse); - - [DllImport("kernel32.dll", SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool CloseHandle(IntPtr hObject); - [DllImport("gdi32.dll", SetLastError = true)] - public static extern IntPtr CreateDIBSection(IntPtr hDC, ref BITMAPINFOHEADER pBitmapInfo, int un, out IntPtr lplpVoid, IntPtr handle, int dw); - [DllImport("gdi32.dll")] - public static extern int DeleteObject(IntPtr hObject); - [DllImport("gdi32.dll", SetLastError = true)] - public static extern IntPtr CreateCompatibleDC(IntPtr hdc); - [DllImport("gdi32.dll")] - public static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject); - - [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr CreateFileMapping(IntPtr hFile, - IntPtr lpFileMappingAttributes, - uint flProtect, - uint dwMaximumSizeHigh, - uint dwMaximumSizeLow, - string lpName); - - [DllImport("msvcrt.dll", EntryPoint = "memcpy", SetLastError = false, CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, UIntPtr count); - - [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] - public static extern HRESULT RegisterDragDrop(IntPtr hwnd, IDropTarget target); - - [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] - public static extern HRESULT RevokeDragDrop(IntPtr hwnd); - - [DllImport("ole32.dll", EntryPoint = "OleInitialize")] - public static extern HRESULT OleInitialize(IntPtr val); - - [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] - internal static extern void ReleaseStgMedium(ref STGMEDIUM medium); - - [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)] - public static extern int GetClipboardFormatName(int format, StringBuilder lpString, int cchMax); - - [DllImport("user32.dll", BestFitMapping = false, CharSet = CharSet.Auto, SetLastError = true)] - public static extern int RegisterClipboardFormat(string format); - - [DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true, SetLastError = true)] - public static extern IntPtr GlobalSize(IntPtr hGlobal); - - [DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto)] - public static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder lpszFile, int cch); - - [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true, PreserveSig = false)] - internal static extern void DoDragDrop(IOleDataObject dataObject, IDropSource dropSource, int allowedEffects, out int finalEffect); - - public enum MONITOR + public enum MonitorOptions : uint { MONITOR_DEFAULTTONULL = 0x00000000, MONITOR_DEFAULTTOPRIMARY = 0x00000001, - MONITOR_DEFAULTTONEAREST = 0x00000002, + MONITOR_DEFAULTTONEAREST = 0x00000002 } + } - [StructLayout(LayoutKind.Sequential)] - internal struct MONITORINFO + public enum DEVICECAP + { + HORZRES = 8, + DESKTOPHORZRES = 118 + } + + public enum PROCESS_DPI_AWARENESS + { + PROCESS_DPI_UNAWARE = 0, + PROCESS_SYSTEM_DPI_AWARE = 1, + PROCESS_PER_MONITOR_DPI_AWARE = 2 + } + + public enum MONITOR_DPI_TYPE + { + MDT_EFFECTIVE_DPI = 0, + MDT_ANGULAR_DPI = 1, + MDT_RAW_DPI = 2, + MDT_DEFAULT = MDT_EFFECTIVE_DPI + } + + public enum ClipboardFormat + { + /// + /// Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text. + /// + CF_TEXT = 1, + /// + /// A handle to a bitmap + /// + CF_BITMAP = 2, + /// + /// A memory object containing a BITMAPINFO structure followed by the bitmap bits. + /// + CF_DIB = 3, + /// + /// Unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. + /// + CF_UNICODETEXT = 13, + /// + /// A handle to type HDROP that identifies a list of files. + /// + CF_HDROP = 15, + } + + public struct MSG + { + public IntPtr hwnd; + public uint message; + public IntPtr wParam; + public IntPtr lParam; + public uint time; + public POINT pt; + } + + [StructLayout(LayoutKind.Sequential)] + public struct PAINTSTRUCT + { + public IntPtr hdc; + public bool fErase; + public RECT rcPaint; + public bool fRestore; + public bool fIncUpdate; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] rgbReserved; + } + + public struct POINT + { + public int X; + public int Y; + } + + public struct RECT + { + public int left; + public int top; + public int right; + public int bottom; + + public int Width => right - left; + + public int Height => bottom - top; + + public void Offset(POINT pt) { - public int cbSize; - public RECT rcMonitor; - public RECT rcWork; - public int dwFlags; + left += pt.X; + right += pt.X; + top += pt.Y; + bottom += pt.Y; + } + } - public static MONITORINFO Create() - { - return new MONITORINFO() { cbSize = Marshal.SizeOf() }; - } + [StructLayout(LayoutKind.Sequential)] + public struct WINDOWPOS + { + public IntPtr hwnd; + public IntPtr hwndInsertAfter; + public int x; + public int y; + public int cx; + public int cy; + public uint flags; + } - public enum MonitorOptions : uint + [StructLayout(LayoutKind.Sequential)] + public struct NCCALCSIZE_PARAMS + { + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public RECT[] rgrc; + public WINDOWPOS lppos; + } + + public struct TRACKMOUSEEVENT + { + public int cbSize; + public uint dwFlags; + public IntPtr hwndTrack; + public int dwHoverTime; + } + + [StructLayout(LayoutKind.Sequential)] + public struct WINDOWPLACEMENT + { + /// + /// The length of the structure, in bytes. Before calling the GetWindowPlacement or SetWindowPlacement functions, set this member to sizeof(WINDOWPLACEMENT). + /// + /// GetWindowPlacement and SetWindowPlacement fail if this member is not set correctly. + /// + /// + public int Length; + + /// + /// Specifies flags that control the position of the minimized window and the method by which the window is restored. + /// + public int Flags; + + /// + /// The current show state of the window. + /// + public ShowWindowCommand ShowCmd; + + /// + /// The coordinates of the window's upper-left corner when the window is minimized. + /// + public POINT MinPosition; + + /// + /// The coordinates of the window's upper-left corner when the window is maximized. + /// + public POINT MaxPosition; + + /// + /// The window's coordinates when the window is in the restored position. + /// + public RECT NormalPosition; + + /// + /// Gets the default (empty) value. + /// + public static WINDOWPLACEMENT Default + { + get { - MONITOR_DEFAULTTONULL = 0x00000000, - MONITOR_DEFAULTTOPRIMARY = 0x00000001, - MONITOR_DEFAULTTONEAREST = 0x00000002 + WINDOWPLACEMENT result = new WINDOWPLACEMENT(); + result.Length = Marshal.SizeOf(result); + return result; } } - - public enum DEVICECAP - { - HORZRES = 8, - DESKTOPHORZRES = 118 - } - - public enum PROCESS_DPI_AWARENESS - { - PROCESS_DPI_UNAWARE = 0, - PROCESS_SYSTEM_DPI_AWARE = 1, - PROCESS_PER_MONITOR_DPI_AWARE = 2 - } - - public enum MONITOR_DPI_TYPE - { - MDT_EFFECTIVE_DPI = 0, - MDT_ANGULAR_DPI = 1, - MDT_RAW_DPI = 2, - MDT_DEFAULT = MDT_EFFECTIVE_DPI - } - - public enum ClipboardFormat - { - /// - /// Text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. Use this format for ANSI text. - /// - CF_TEXT = 1, - /// - /// A handle to a bitmap - /// - CF_BITMAP = 2, - /// - /// A memory object containing a BITMAPINFO structure followed by the bitmap bits. - /// - CF_DIB = 3, - /// - /// Unicode text format. Each line ends with a carriage return/linefeed (CR-LF) combination. A null character signals the end of the data. - /// - CF_UNICODETEXT = 13, - /// - /// A handle to type HDROP that identifies a list of files. - /// - CF_HDROP = 15, - } - - public struct MSG - { - public IntPtr hwnd; - public uint message; - public IntPtr wParam; - public IntPtr lParam; - public uint time; - public POINT pt; - } - - [StructLayout(LayoutKind.Sequential)] - public struct PAINTSTRUCT - { - public IntPtr hdc; - public bool fErase; - public RECT rcPaint; - public bool fRestore; - public bool fIncUpdate; - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] - public byte[] rgbReserved; - } - - public struct POINT - { - public int X; - public int Y; - } - - public struct RECT - { - public int left; - public int top; - public int right; - public int bottom; - - public int Width => right - left; - - public int Height => bottom - top; - - public void Offset(POINT pt) - { - left += pt.X; - right += pt.X; - top += pt.Y; - bottom += pt.Y; - } - } - - [StructLayout(LayoutKind.Sequential)] - public struct WINDOWPOS - { - public IntPtr hwnd; - public IntPtr hwndInsertAfter; - public int x; - public int y; - public int cx; - public int cy; - public uint flags; - } - - [StructLayout(LayoutKind.Sequential)] - public struct NCCALCSIZE_PARAMS - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] - public RECT[] rgrc; - public WINDOWPOS lppos; - } - - public struct TRACKMOUSEEVENT - { - public int cbSize; - public uint dwFlags; - public IntPtr hwndTrack; - public int dwHoverTime; - } - - [StructLayout(LayoutKind.Sequential)] - public struct WINDOWPLACEMENT - { - /// - /// The length of the structure, in bytes. Before calling the GetWindowPlacement or SetWindowPlacement functions, set this member to sizeof(WINDOWPLACEMENT). - /// - /// GetWindowPlacement and SetWindowPlacement fail if this member is not set correctly. - /// - /// - public int Length; - - /// - /// Specifies flags that control the position of the minimized window and the method by which the window is restored. - /// - public int Flags; - - /// - /// The current show state of the window. - /// - public ShowWindowCommand ShowCmd; - - /// - /// The coordinates of the window's upper-left corner when the window is minimized. - /// - public POINT MinPosition; - - /// - /// The coordinates of the window's upper-left corner when the window is maximized. - /// - public POINT MaxPosition; - - /// - /// The window's coordinates when the window is in the restored position. - /// - public RECT NormalPosition; - - /// - /// Gets the default (empty) value. - /// - public static WINDOWPLACEMENT Default - { - get - { - WINDOWPLACEMENT result = new WINDOWPLACEMENT(); - result.Length = Marshal.SizeOf(result); - return result; - } - } - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct WNDCLASSEX - { - public int cbSize; - public int style; - public WndProc lpfnWndProc; - public int cbClsExtra; - public int cbWndExtra; - public IntPtr hInstance; - public IntPtr hIcon; - public IntPtr hCursor; - public IntPtr hbrBackground; - public string lpszMenuName; - public string lpszClassName; - public IntPtr hIconSm; - } - - [StructLayout(LayoutKind.Sequential)] - public struct TOUCHINPUT - { - public int X; - public int Y; - public IntPtr Source; - public uint Id; - public TouchInputFlags Flags; - public int Mask; - public uint Time; - public IntPtr ExtraInfo; - public int CxContact; - public int CyContact; - } - - [Flags] - public enum TouchInputFlags - { - /// - /// Movement has occurred. Cannot be combined with TOUCHEVENTF_DOWN. - /// - TOUCHEVENTF_MOVE = 0x0001, - - /// - /// The corresponding touch point was established through a new contact. Cannot be combined with TOUCHEVENTF_MOVE or TOUCHEVENTF_UP. - /// - TOUCHEVENTF_DOWN = 0x0002, - - /// - /// A touch point was removed. - /// - TOUCHEVENTF_UP = 0x0004, - - /// - /// A touch point is in range. This flag is used to enable touch hover support on compatible hardware. Applications that do not want support for hover can ignore this flag. - /// - TOUCHEVENTF_INRANGE = 0x0008, - - /// - /// Indicates that this TOUCHINPUT structure corresponds to a primary contact point. See the following text for more information on primary touch points. - /// - TOUCHEVENTF_PRIMARY = 0x0010, - - /// - /// When received using GetTouchInputInfo, this input was not coalesced. - /// - TOUCHEVENTF_NOCOALESCE = 0x0020, - - /// - /// The touch event came from the user's palm. - /// - TOUCHEVENTF_PALM = 0x0080 - } - - [Flags] - public enum OpenFileNameFlags - { - OFN_ALLOWMULTISELECT = 0x00000200, - OFN_EXPLORER = 0x00080000, - OFN_HIDEREADONLY = 0x00000004, - OFN_NOREADONLYRETURN = 0x00008000, - OFN_OVERWRITEPROMPT = 0x00000002 - } - - public enum HRESULT : uint - { - S_FALSE = 0x0001, - S_OK = 0x0000, - E_INVALIDARG = 0x80070057, - E_OUTOFMEMORY = 0x8007000E, - E_NOTIMPL = 0x80004001, - E_UNEXPECTED = 0x8000FFFF - } - - public enum Icons - { - ICON_SMALL = 0, - ICON_BIG = 1 - } - - public const uint SIGDN_FILESYSPATH = 0x80058000; - - [Flags] - public enum FOS : uint - { - FOS_OVERWRITEPROMPT = 0x00000002, - FOS_STRICTFILETYPES = 0x00000004, - FOS_NOCHANGEDIR = 0x00000008, - FOS_PICKFOLDERS = 0x00000020, - FOS_FORCEFILESYSTEM = 0x00000040, // Ensure that items returned are filesystem items. - FOS_ALLNONSTORAGEITEMS = 0x00000080, // Allow choosing items that have no storage. - FOS_NOVALIDATE = 0x00000100, - FOS_ALLOWMULTISELECT = 0x00000200, - FOS_PATHMUSTEXIST = 0x00000800, - FOS_FILEMUSTEXIST = 0x00001000, - FOS_CREATEPROMPT = 0x00002000, - FOS_SHAREAWARE = 0x00004000, - FOS_NOREADONLYRETURN = 0x00008000, - FOS_NOTESTFILECREATE = 0x00010000, - FOS_HIDEMRUPLACES = 0x00020000, - FOS_HIDEPINNEDPLACES = 0x00040000, - FOS_NODEREFERENCELINKS = 0x00100000, - FOS_DONTADDTORECENT = 0x02000000, - FOS_FORCESHOWHIDDEN = 0x10000000, - FOS_DEFAULTNOMINIMODE = 0x20000000 - } - - public static class ShellIds - { - public static readonly Guid OpenFileDialog = Guid.Parse("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7"); - public static readonly Guid SaveFileDialog = Guid.Parse("C0B4E2F3-BA21-4773-8DBA-335EC946EB8B"); - public static readonly Guid IFileDialog = Guid.Parse("42F85136-DB7E-439C-85F1-E4075D135FC8"); - public static readonly Guid IShellItem = Guid.Parse("43826D1E-E718-42EE-BC55-A1E261C37BFE"); - } - - [ComImport(), Guid("42F85136-DB7E-439C-85F1-E4075D135FC8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - public interface IFileDialog - { - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - [PreserveSig()] - uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFileTypes(uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] COMDLG_FILTERSPEC[] rgFilterSpec); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFileTypeIndex([In] uint iFileType); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetFileTypeIndex(out uint piFileType); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint Unadvise([In] uint dwCookie); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetOptions([In] uint fos); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetOptions(out uint fos); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint Close([MarshalAs(UnmanagedType.Error)] uint hr); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetClientGuid([In] ref Guid guid); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint ClearClientData(); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); - } - - [ComImport, Guid("d57c7288-d4ad-4768-be02-9d969532d960"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - public interface IFileOpenDialog - { - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - [PreserveSig()] - uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr rgFilterSpec); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetFileTypeIndex([In] uint iFileType); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetFileTypeIndex(out uint piFileType); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void Unadvise([In] uint dwCookie); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint SetOptions([In] uint fos); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetOptions(out uint fos); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void Close([MarshalAs(UnmanagedType.Error)] int hr); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetClientGuid([In] ref Guid guid); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void ClearClientData(); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetResults([MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppenum); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetSelectedItems([MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppsai); - } - - [ComImport, Guid("B63EA76D-1F85-456F-A19C-48159EFA858B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - public interface IShellItemArray - { - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid rbhid, - [In] ref Guid riid, out IntPtr ppvOut); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetPropertyStore([In] int Flags, [In] ref Guid riid, out IntPtr ppv); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetPropertyDescriptionList([In] ref PROPERTYKEY keyType, [In] ref Guid riid, out IntPtr ppv); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetAttributes([In] SIATTRIBFLAGS dwAttribFlags, [In] uint sfgaoMask, out uint psfgaoAttribs); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetCount(out uint pdwNumItems); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void GetItemAt([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - void EnumItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenumShellItems); - } - - [StructLayout(LayoutKind.Sequential, Pack = 4)] - public struct PROPERTYKEY - { - public Guid fmtid; - public uint pid; - } - - public enum SIATTRIBFLAGS - { - SIATTRIBFLAGS_AND = 1, - SIATTRIBFLAGS_APPCOMPAT = 3, - SIATTRIBFLAGS_OR = 2 - } - - [ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - public interface IShellItem - { - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); - - [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] - uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); - } - - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct COMDLG_FILTERSPEC - { - [MarshalAs(UnmanagedType.LPWStr)] - public string pszName; - [MarshalAs(UnmanagedType.LPWStr)] - public string pszSpec; - } + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct WNDCLASSEX + { + public int cbSize; + public int style; + public WndProc lpfnWndProc; + public int cbClsExtra; + public int cbWndExtra; + public IntPtr hInstance; + public IntPtr hIcon; + public IntPtr hCursor; + public IntPtr hbrBackground; + public string lpszMenuName; + public string lpszClassName; + public IntPtr hIconSm; + } + + [StructLayout(LayoutKind.Sequential)] + public struct TOUCHINPUT + { + public int X; + public int Y; + public IntPtr Source; + public uint Id; + public TouchInputFlags Flags; + public int Mask; + public uint Time; + public IntPtr ExtraInfo; + public int CxContact; + public int CyContact; } [Flags] - public enum NIF : uint + public enum TouchInputFlags { - MESSAGE = 0x00000001, - ICON = 0x00000002, - TIP = 0x00000004, - STATE = 0x00000008, - INFO = 0x00000010, - GUID = 0x00000020, - REALTIME = 0x00000040, - SHOWTIP = 0x00000080 + /// + /// Movement has occurred. Cannot be combined with TOUCHEVENTF_DOWN. + /// + TOUCHEVENTF_MOVE = 0x0001, + + /// + /// The corresponding touch point was established through a new contact. Cannot be combined with TOUCHEVENTF_MOVE or TOUCHEVENTF_UP. + /// + TOUCHEVENTF_DOWN = 0x0002, + + /// + /// A touch point was removed. + /// + TOUCHEVENTF_UP = 0x0004, + + /// + /// A touch point is in range. This flag is used to enable touch hover support on compatible hardware. Applications that do not want support for hover can ignore this flag. + /// + TOUCHEVENTF_INRANGE = 0x0008, + + /// + /// Indicates that this TOUCHINPUT structure corresponds to a primary contact point. See the following text for more information on primary touch points. + /// + TOUCHEVENTF_PRIMARY = 0x0010, + + /// + /// When received using GetTouchInputInfo, this input was not coalesced. + /// + TOUCHEVENTF_NOCOALESCE = 0x0020, + + /// + /// The touch event came from the user's palm. + /// + TOUCHEVENTF_PALM = 0x0080 } [Flags] - public enum NIIF : uint + public enum OpenFileNameFlags { - NONE = 0x00000000, - INFO = 0x00000001, - WARNING = 0x00000002, - ERROR = 0x00000003, - USER = 0x00000004, - ICON_MASK = 0x0000000F, - NOSOUND = 0x00000010, - LARGE_ICON = 0x00000020, - RESPECT_QUIET_TIME = 0x00000080 + OFN_ALLOWMULTISELECT = 0x00000200, + OFN_EXPLORER = 0x00080000, + OFN_HIDEREADONLY = 0x00000004, + OFN_NOREADONLYRETURN = 0x00008000, + OFN_OVERWRITEPROMPT = 0x00000002 } + public enum HRESULT : uint + { + S_FALSE = 0x0001, + S_OK = 0x0000, + E_INVALIDARG = 0x80070057, + E_OUTOFMEMORY = 0x8007000E, + E_NOTIMPL = 0x80004001, + E_UNEXPECTED = 0x8000FFFF + } + + public enum Icons + { + ICON_SMALL = 0, + ICON_BIG = 1 + } + + public const uint SIGDN_FILESYSPATH = 0x80058000; + [Flags] - internal enum DropEffect : int + public enum FOS : uint { - None = 0, - Copy = 1, - Move = 2, - Link = 4, - Scroll = -2147483648, + FOS_OVERWRITEPROMPT = 0x00000002, + FOS_STRICTFILETYPES = 0x00000004, + FOS_NOCHANGEDIR = 0x00000008, + FOS_PICKFOLDERS = 0x00000020, + FOS_FORCEFILESYSTEM = 0x00000040, // Ensure that items returned are filesystem items. + FOS_ALLNONSTORAGEITEMS = 0x00000080, // Allow choosing items that have no storage. + FOS_NOVALIDATE = 0x00000100, + FOS_ALLOWMULTISELECT = 0x00000200, + FOS_PATHMUSTEXIST = 0x00000800, + FOS_FILEMUSTEXIST = 0x00001000, + FOS_CREATEPROMPT = 0x00002000, + FOS_SHAREAWARE = 0x00004000, + FOS_NOREADONLYRETURN = 0x00008000, + FOS_NOTESTFILECREATE = 0x00010000, + FOS_HIDEMRUPLACES = 0x00020000, + FOS_HIDEPINNEDPLACES = 0x00040000, + FOS_NODEREFERENCELINKS = 0x00100000, + FOS_DONTADDTORECENT = 0x02000000, + FOS_FORCESHOWHIDDEN = 0x10000000, + FOS_DEFAULTNOMINIMODE = 0x20000000 } - [ComImport] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [Guid("00000122-0000-0000-C000-000000000046")] - internal interface IDropTarget + public static class ShellIds { - [PreserveSig] - UnmanagedMethods.HRESULT DragEnter([MarshalAs(UnmanagedType.Interface)][In] IOleDataObject pDataObj, [MarshalAs(UnmanagedType.U4)][In] int grfKeyState, [MarshalAs(UnmanagedType.U8)][In] long pt, [In][Out] ref DropEffect pdwEffect); - [PreserveSig] - UnmanagedMethods.HRESULT DragOver([MarshalAs(UnmanagedType.U4)][In] int grfKeyState, [MarshalAs(UnmanagedType.U8)][In] long pt, [In][Out] ref DropEffect pdwEffect); - [PreserveSig] - UnmanagedMethods.HRESULT DragLeave(); - [PreserveSig] - UnmanagedMethods.HRESULT Drop([MarshalAs(UnmanagedType.Interface)][In] IOleDataObject pDataObj, [MarshalAs(UnmanagedType.U4)][In] int grfKeyState, [MarshalAs(UnmanagedType.U8)][In] long pt, [In][Out] ref DropEffect pdwEffect); + public static readonly Guid OpenFileDialog = Guid.Parse("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7"); + public static readonly Guid SaveFileDialog = Guid.Parse("C0B4E2F3-BA21-4773-8DBA-335EC946EB8B"); + public static readonly Guid IFileDialog = Guid.Parse("42F85136-DB7E-439C-85F1-E4075D135FC8"); + public static readonly Guid IShellItem = Guid.Parse("43826D1E-E718-42EE-BC55-A1E261C37BFE"); } - [ComImport] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - [Guid("00000121-0000-0000-C000-000000000046")] - internal interface IDropSource + [ComImport(), Guid("42F85136-DB7E-439C-85F1-E4075D135FC8"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IFileDialog { - [PreserveSig] - int QueryContinueDrag(int fEscapePressed, [MarshalAs(UnmanagedType.U4)][In] int grfKeyState); - [PreserveSig] - int GiveFeedback([MarshalAs(UnmanagedType.U4)][In] int dwEffect); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [PreserveSig()] + uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFileTypes(uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] COMDLG_FILTERSPEC[] rgFilterSpec); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFileTypeIndex([In] uint iFileType); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetFileTypeIndex(out uint piFileType); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint Unadvise([In] uint dwCookie); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetOptions([In] uint fos); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetOptions(out uint fos); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint Close([MarshalAs(UnmanagedType.Error)] uint hr); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetClientGuid([In] ref Guid guid); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint ClearClientData(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); } - [ComImport] - [Guid("0000010E-0000-0000-C000-000000000046")] - [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - internal interface IOleDataObject + [ComImport, Guid("d57c7288-d4ad-4768-be02-9d969532d960"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IFileOpenDialog { - void GetData([In] ref FORMATETC format, out STGMEDIUM medium); - void GetDataHere([In] ref FORMATETC format, ref STGMEDIUM medium); - [PreserveSig] - int QueryGetData([In] ref FORMATETC format); - [PreserveSig] - int GetCanonicalFormatEtc([In] ref FORMATETC formatIn, out FORMATETC formatOut); - void SetData([In] ref FORMATETC formatIn, [In] ref STGMEDIUM medium, [MarshalAs(UnmanagedType.Bool)] bool release); - IEnumFORMATETC EnumFormatEtc(DATADIR direction); - [PreserveSig] - int DAdvise([In] ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection); - void DUnadvise(int connection); - [PreserveSig] - int EnumDAdvise(out IEnumSTATDATA enumAdvise); + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + [PreserveSig()] + uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr rgFilterSpec); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetFileTypeIndex([In] uint iFileType); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFileTypeIndex(out uint piFileType); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Unadvise([In] uint dwCookie); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint SetOptions([In] uint fos); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetOptions(out uint fos); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void Close([MarshalAs(UnmanagedType.Error)] int hr); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetClientGuid([In] ref Guid guid); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void ClearClientData(); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetResults([MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppenum); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetSelectedItems([MarshalAs(UnmanagedType.Interface)] out IShellItemArray ppsai); + } + + [ComImport, Guid("B63EA76D-1F85-456F-A19C-48159EFA858B"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IShellItemArray + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void BindToHandler([In, MarshalAs(UnmanagedType.Interface)] IntPtr pbc, [In] ref Guid rbhid, + [In] ref Guid riid, out IntPtr ppvOut); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetPropertyStore([In] int Flags, [In] ref Guid riid, out IntPtr ppv); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetPropertyDescriptionList([In] ref PROPERTYKEY keyType, [In] ref Guid riid, out IntPtr ppv); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetAttributes([In] SIATTRIBFLAGS dwAttribFlags, [In] uint sfgaoMask, out uint psfgaoAttribs); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetCount(out uint pdwNumItems); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void GetItemAt([In] uint dwIndex, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + void EnumItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenumShellItems); + } + + [StructLayout(LayoutKind.Sequential, Pack = 4)] + public struct PROPERTYKEY + { + public Guid fmtid; + public uint pid; + } + + public enum SIATTRIBFLAGS + { + SIATTRIBFLAGS_AND = 1, + SIATTRIBFLAGS_APPCOMPAT = 3, + SIATTRIBFLAGS_OR = 2 + } + + [ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IShellItem + { + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); + + [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] + uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); + } + + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct COMDLG_FILTERSPEC + { + [MarshalAs(UnmanagedType.LPWStr)] + public string pszName; + [MarshalAs(UnmanagedType.LPWStr)] + public string pszSpec; } } -#nullable enable \ No newline at end of file +[Flags] +internal enum NIF : uint +{ + MESSAGE = 0x00000001, + ICON = 0x00000002, + TIP = 0x00000004, + STATE = 0x00000008, + INFO = 0x00000010, + GUID = 0x00000020, + REALTIME = 0x00000040, + SHOWTIP = 0x00000080 +} + +[Flags] +internal enum NIIF : uint +{ + NONE = 0x00000000, + INFO = 0x00000001, + WARNING = 0x00000002, + ERROR = 0x00000003, + USER = 0x00000004, + ICON_MASK = 0x0000000F, + NOSOUND = 0x00000010, + LARGE_ICON = 0x00000020, + RESPECT_QUIET_TIME = 0x00000080 +} + +[Flags] +internal enum DropEffect : int +{ + None = 0, + Copy = 1, + Move = 2, + Link = 4, + Scroll = -2147483648, +} + +[ComImport] +[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[Guid("00000122-0000-0000-C000-000000000046")] +internal interface IDropTarget +{ + [PreserveSig] + UnmanagedMethods.HRESULT DragEnter([MarshalAs(UnmanagedType.Interface)][In] IOleDataObject pDataObj, [MarshalAs(UnmanagedType.U4)][In] int grfKeyState, [MarshalAs(UnmanagedType.U8)][In] long pt, [In][Out] ref DropEffect pdwEffect); + [PreserveSig] + UnmanagedMethods.HRESULT DragOver([MarshalAs(UnmanagedType.U4)][In] int grfKeyState, [MarshalAs(UnmanagedType.U8)][In] long pt, [In][Out] ref DropEffect pdwEffect); + [PreserveSig] + UnmanagedMethods.HRESULT DragLeave(); + [PreserveSig] + UnmanagedMethods.HRESULT Drop([MarshalAs(UnmanagedType.Interface)][In] IOleDataObject pDataObj, [MarshalAs(UnmanagedType.U4)][In] int grfKeyState, [MarshalAs(UnmanagedType.U8)][In] long pt, [In][Out] ref DropEffect pdwEffect); +} + +[ComImport] +[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +[Guid("00000121-0000-0000-C000-000000000046")] +internal interface IDropSource +{ + [PreserveSig] + int QueryContinueDrag(int fEscapePressed, [MarshalAs(UnmanagedType.U4)][In] int grfKeyState); + [PreserveSig] + int GiveFeedback([MarshalAs(UnmanagedType.U4)][In] int dwEffect); +} + +[ComImport] +[Guid("0000010E-0000-0000-C000-000000000046")] +[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] +internal interface IOleDataObject +{ + void GetData([In] ref FORMATETC format, out STGMEDIUM medium); + void GetDataHere([In] ref FORMATETC format, ref STGMEDIUM medium); + [PreserveSig] + int QueryGetData([In] ref FORMATETC format); + [PreserveSig] + int GetCanonicalFormatEtc([In] ref FORMATETC formatIn, out FORMATETC formatOut); + void SetData([In] ref FORMATETC formatIn, [In] ref STGMEDIUM medium, [MarshalAs(UnmanagedType.Bool)] bool release); + IEnumFORMATETC EnumFormatEtc(DATADIR direction); + [PreserveSig] + int DAdvise([In] ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection); + void DUnadvise(int connection); + [PreserveSig] + int EnumDAdvise(out IEnumSTATDATA enumAdvise); +} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/User32Window.cs b/src/ST.Client.Desktop.Windows/Internals/User32Window.cs index 7f956e429..979d8e8ec 100644 --- a/src/ST.Client.Desktop.Windows/Internals/User32Window.cs +++ b/src/ST.Client.Desktop.Windows/Internals/User32Window.cs @@ -1,235 +1,232 @@ +using System; using System.Runtime.InteropServices; using System.Text; -// ReSharper disable once CheckNamespace -namespace System +internal static class User32Window { - internal static class User32Window + public const string LibraryName = "user32.dll"; + + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "FlashWindow")] + static extern void FlashWindow(IntPtr hwnd, bool bInvert); + + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "FlashWindowEx")] + static extern void FlashWindowEx(ref FLASHWINFO pwfi); + + [DllImport(LibraryName, CharSet = CharSet.Auto)] + public static extern bool ShowWindow(IntPtr hWnd, short State); + + [DllImport(LibraryName, CharSet = CharSet.Auto)] + internal static extern IntPtr GetOpenClipboardWindow(); + + [DllImport(LibraryName, SetLastError = true, CharSet = CharSet.Auto)] + internal static extern int GetWindowTextLength(IntPtr hWnd); + + public enum Cmd_SHOWWINDOWS : short { - public const string LibraryName = "user32.dll"; + /// + /// Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when + /// minimizing windows from a different thread. + /// + SW_FORCEMINIMIZE = 11, - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "FlashWindow")] - static extern void FlashWindow(IntPtr hwnd, bool bInvert); + /// + /// Hides the window and activates another window. + /// + SW_HIDE = 0, - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "FlashWindowEx")] - static extern void FlashWindowEx(ref FLASHWINFO pwfi); + /// + /// Maximizes the specified window. + /// + SW_MAXIMIZE = 3, - [DllImport(LibraryName, CharSet = CharSet.Auto)] - public static extern bool ShowWindow(IntPtr hWnd, short State); + /// + /// Minimizes the specified window and activates the next top-level window in the Z order. + /// + SW_MINIMIZE = 6, - [DllImport(LibraryName, CharSet = CharSet.Auto)] - internal static extern IntPtr GetOpenClipboardWindow(); + /// + /// Activates and displays the window. If the window is minimized or maximized, the system restores it to its original + /// size and position. An application should specify this flag when restoring a minimized window. + /// + SW_RESTORE = 9, - [DllImport(LibraryName, SetLastError = true, CharSet = CharSet.Auto)] - internal static extern int GetWindowTextLength(IntPtr hWnd); + /// + /// Activates the window and displays it in its current size and position. + /// + SW_SHOW = 5, - public enum Cmd_SHOWWINDOWS : short - { - /// - /// Minimizes a window, even if the thread that owns the window is not responding. This flag should only be used when - /// minimizing windows from a different thread. - /// - SW_FORCEMINIMIZE = 11, + /// + /// Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess + /// function by the program that started the application. + /// + SW_SHOWDEFAULT = 10, - /// - /// Hides the window and activates another window. - /// - SW_HIDE = 0, + /// + /// Activates the window and displays it as a maximized window. + /// + SW_SHOWMAXIMIZED = 3, - /// - /// Maximizes the specified window. - /// - SW_MAXIMIZE = 3, + /// + /// Activates the window and displays it as a minimized window. + /// + SW_SHOWMINIMIZED = 2, - /// - /// Minimizes the specified window and activates the next top-level window in the Z order. - /// - SW_MINIMIZE = 6, + /// + /// Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not + /// activated. + /// + SW_SHOWMINNOACTIVE = 7, - /// - /// Activates and displays the window. If the window is minimized or maximized, the system restores it to its original - /// size and position. An application should specify this flag when restoring a minimized window. - /// - SW_RESTORE = 9, + /// + /// Displays the window in its current size and position. This value is similar to SW_SHOW, except that the window is + /// not activated. + /// + SW_SHOWNA = 8, - /// - /// Activates the window and displays it in its current size and position. - /// - SW_SHOW = 5, + /// + /// Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the + /// window is not activated. + /// + SW_SHOWNOACTIVATE = 4, - /// - /// Sets the show state based on the SW_ value specified in the STARTUPINFO structure passed to the CreateProcess - /// function by the program that started the application. - /// - SW_SHOWDEFAULT = 10, + /// + /// Activates and displays a window. If the window is minimized or maximized, the system restores it to its original + /// size and position. An application should specify this flag when displaying the window for the first time. + /// + SW_SHOWNORMAL = 1 + }; - /// - /// Activates the window and displays it as a maximized window. - /// - SW_SHOWMAXIMIZED = 3, - - /// - /// Activates the window and displays it as a minimized window. - /// - SW_SHOWMINIMIZED = 2, - - /// - /// Displays the window as a minimized window. This value is similar to SW_SHOWMINIMIZED, except the window is not - /// activated. - /// - SW_SHOWMINNOACTIVE = 7, - - /// - /// Displays the window in its current size and position. This value is similar to SW_SHOW, except that the window is - /// not activated. - /// - SW_SHOWNA = 8, - - /// - /// Displays a window in its most recent size and position. This value is similar to SW_SHOWNORMAL, except that the - /// window is not activated. - /// - SW_SHOWNOACTIVATE = 4, - - /// - /// Activates and displays a window. If the window is minimized or maximized, the system restores it to its original - /// size and position. An application should specify this flag when displaying the window for the first time. - /// - SW_SHOWNORMAL = 1 - }; - - internal struct FLASHWINFO - { + internal struct FLASHWINFO + { #pragma warning disable 649 - /// - /// 该结构的字节大小 - /// - public uint cbSize; + /// + /// 该结构的字节大小 + /// + public uint cbSize; - /// - /// 要闪烁的窗口的句柄,该窗口可以是打开的或最小化的 - /// - public IntPtr hwnd; + /// + /// 要闪烁的窗口的句柄,该窗口可以是打开的或最小化的 + /// + public IntPtr hwnd; - /// - /// 闪烁的状态 - /// - public uint dwFlags; + /// + /// 闪烁的状态 + /// + public uint dwFlags; - /// - /// 闪烁窗口的次数 - /// - public uint uCount; + /// + /// 闪烁窗口的次数 + /// + public uint uCount; - /// - /// 窗口闪烁的频度,毫秒为单位;若该值为0,则为默认图标的闪烁频度 - /// - public uint dwTimeout; + /// + /// 窗口闪烁的频度,毫秒为单位;若该值为0,则为默认图标的闪烁频度 + /// + public uint dwTimeout; #pragma warning restore 649 - } + } - public const uint FLASHW_TRAY = 2; - public const uint FLASHW_TIMERNOFG = 12; + public const uint FLASHW_TRAY = 2; + public const uint FLASHW_TIMERNOFG = 12; - //获取窗口标题 - [DllImport(LibraryName, CharSet = CharSet.Unicode, SetLastError = true)] - public static extern int GetWindowText( - IntPtr hWnd,//窗口句柄 - StringBuilder lpString,//标题 - int nMaxCount //最大值 - ); + //获取窗口标题 + [DllImport(LibraryName, CharSet = CharSet.Unicode, SetLastError = true)] + public static extern int GetWindowText( + IntPtr hWnd,//窗口句柄 + StringBuilder lpString,//标题 + int nMaxCount //最大值 + ); - //获取类的名字 - [DllImport(LibraryName, CharSet = CharSet.Unicode)] - public static extern int GetClassName( - IntPtr hWnd,//句柄 - StringBuilder lpString, //类名 - int nMaxCount //最大值 - ); + //获取类的名字 + [DllImport(LibraryName, CharSet = CharSet.Unicode)] + public static extern int GetClassName( + IntPtr hWnd,//句柄 + StringBuilder lpString, //类名 + int nMaxCount //最大值 + ); - //获取句柄所属进程pid - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "GetWindowThreadProcessId")] - public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int pid); + //获取句柄所属进程pid + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "GetWindowThreadProcessId")] + public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int pid); - [DllImport(LibraryName, CharSet = CharSet.Unicode)] - public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); + [DllImport(LibraryName, CharSet = CharSet.Unicode)] + public static extern IntPtr FindWindow(string lpClassName, string lpWindowName); - [DllImport(LibraryName, CharSet = CharSet.Unicode)] - public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); + [DllImport(LibraryName, CharSet = CharSet.Unicode)] + public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow); - [DllImport(LibraryName, CharSet = CharSet.Auto)] - public static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); + [DllImport(LibraryName, CharSet = CharSet.Auto)] + public static extern IntPtr SendMessage(IntPtr hwnd, uint msg, IntPtr wParam, IntPtr lParam); - public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); + public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); - [DllImport(LibraryName, ExactSpelling = true)] - public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); + [DllImport(LibraryName, ExactSpelling = true)] + public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam); - [DllImport(LibraryName, ExactSpelling = true)] - public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); + [DllImport(LibraryName, ExactSpelling = true)] + public static extern int EnumChildWindows(IntPtr hWndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam); - [DllImport(LibraryName, ExactSpelling = true)] - public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); + [DllImport(LibraryName, ExactSpelling = true)] + public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); - [DllImport(LibraryName, ExactSpelling = true)] - public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint); + [DllImport(LibraryName, ExactSpelling = true)] + public static extern bool MoveWindow(IntPtr hWnd, int x, int y, int nWidth, int nHeight, bool bRepaint); - // This static method is required because Win32 does not support - // GetWindowLongPtr directly - public static IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex) - { - return IntPtr.Size > 4 - ? GetWindowLongPtr_x64(hwnd, nIndex) - : new IntPtr(GetWindowLong(hwnd, nIndex)); - } + // This static method is required because Win32 does not support + // GetWindowLongPtr directly + public static IntPtr GetWindowLongPtr(IntPtr hwnd, int nIndex) + { + return IntPtr.Size > 4 + ? GetWindowLongPtr_x64(hwnd, nIndex) + : new IntPtr(GetWindowLong(hwnd, nIndex)); + } - [DllImport(LibraryName, CharSet = CharSet.Auto)] - public static extern int GetWindowLongA(IntPtr hWnd, int nIndex); + [DllImport(LibraryName, CharSet = CharSet.Auto)] + public static extern int GetWindowLongA(IntPtr hWnd, int nIndex); - [DllImport(LibraryName, CharSet = CharSet.Auto)] - static extern int GetWindowLong(IntPtr hwnd, int nIndex); + [DllImport(LibraryName, CharSet = CharSet.Auto)] + static extern int GetWindowLong(IntPtr hwnd, int nIndex); - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "GetWindowLongPtr")] - static extern IntPtr GetWindowLongPtr_x64(IntPtr hwnd, int nIndex); + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "GetWindowLongPtr")] + static extern IntPtr GetWindowLongPtr_x64(IntPtr hwnd, int nIndex); - // This static method is required because Win32 does not support - // GetWindowLongPtr directly - public static IntPtr SetWindowLongPtr(IntPtr hwnd, int nIndex, IntPtr dwNewLong) - { - return IntPtr.Size > 4 - ? SetWindowLongPtr_x64(hwnd, nIndex, dwNewLong) - : new IntPtr(SetWindowLong(hwnd, nIndex, dwNewLong.ToInt32())); - } + // This static method is required because Win32 does not support + // GetWindowLongPtr directly + public static IntPtr SetWindowLongPtr(IntPtr hwnd, int nIndex, IntPtr dwNewLong) + { + return IntPtr.Size > 4 + ? SetWindowLongPtr_x64(hwnd, nIndex, dwNewLong) + : new IntPtr(SetWindowLong(hwnd, nIndex, dwNewLong.ToInt32())); + } - [DllImport(LibraryName, CharSet = CharSet.Auto)] - public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong); + [DllImport(LibraryName, CharSet = CharSet.Auto)] + public static extern int SetWindowLong(IntPtr hwnd, int nIndex, int dwNewLong); - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "SetWindowLongPtr")] - public static extern IntPtr SetWindowLongPtr_x64(IntPtr hwnd, int nIndex, IntPtr dwNewLong); + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "SetWindowLongPtr")] + public static extern IntPtr SetWindowLongPtr_x64(IntPtr hwnd, int nIndex, IntPtr dwNewLong); - [DllImport(LibraryName, CharSet = CharSet.Auto)] - public static extern IntPtr SetActiveWindow(IntPtr hWnd); + [DllImport(LibraryName, CharSet = CharSet.Auto)] + public static extern IntPtr SetActiveWindow(IntPtr hWnd); - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "SetForegroundWindow")] - //设置此窗体为活动窗体 - public static extern bool SetForegroundWindow(IntPtr hWnd); + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "SetForegroundWindow")] + //设置此窗体为活动窗体 + public static extern bool SetForegroundWindow(IntPtr hWnd); - [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "SetLayeredWindowAttributes")] - public static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags); + [DllImport(LibraryName, CharSet = CharSet.Auto, EntryPoint = "SetLayeredWindowAttributes")] + public static extern int SetLayeredWindowAttributes(IntPtr hwnd, int crKey, int bAlpha, int dwFlags); - public static void FlashWindow(IntPtr hwnd) - { - //ShowWindow(hwnd, (short)Cmd_SHOWWINDOWS.SW_NORMAL); - //直接调用FlashWindow即可 - FlashWindow(hwnd, true); - } + public static void FlashWindow(IntPtr hwnd) + { + //ShowWindow(hwnd, (short)Cmd_SHOWWINDOWS.SW_NORMAL); + //直接调用FlashWindow即可 + FlashWindow(hwnd, true); + } - public static void FlashWindow(ref FLASHWINFO f) - { - //直接调用FlashWindow即可 - FlashWindowEx(ref f); - } + public static void FlashWindow(ref FLASHWINFO f) + { + //直接调用FlashWindow即可 + FlashWindowEx(ref f); } } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/WinHttp.cs b/src/ST.Client.Desktop.Windows/Internals/WinHttp.cs index ec7c4436c..42e7d3bdf 100644 --- a/src/ST.Client.Desktop.Windows/Internals/WinHttp.cs +++ b/src/ST.Client.Desktop.Windows/Internals/WinHttp.cs @@ -1,27 +1,23 @@ -using System.Runtime.InteropServices; +using System.Runtime.InteropServices; -// ReSharper disable once CheckNamespace -namespace System +internal static class WinHttp { - internal static class WinHttp - { - [DllImport("winhttp.dll", SetLastError = true)] - internal static extern bool WinHttpGetIEProxyConfigForCurrentUser(ref WinHttpCurrentUserIEProxyConfig pProxyConfig); - } + [DllImport("winhttp.dll", SetLastError = true)] + internal static extern bool WinHttpGetIEProxyConfigForCurrentUser(ref WinHttpCurrentUserIEProxyConfig pProxyConfig); +} - [StructLayout(LayoutKind.Sequential)] - internal struct WinHttpCurrentUserIEProxyConfig - { - [MarshalAs(UnmanagedType.Bool)] - public bool AutoDetect; +[StructLayout(LayoutKind.Sequential)] +internal struct WinHttpCurrentUserIEProxyConfig +{ + [MarshalAs(UnmanagedType.Bool)] + public bool AutoDetect; - [MarshalAs(UnmanagedType.LPWStr)] - public string AutoConfigUrl; + [MarshalAs(UnmanagedType.LPWStr)] + public string AutoConfigUrl; - [MarshalAs(UnmanagedType.LPWStr)] - public string Proxy; + [MarshalAs(UnmanagedType.LPWStr)] + public string Proxy; - [MarshalAs(UnmanagedType.LPWStr)] - public string ProxyBypass; - } + [MarshalAs(UnmanagedType.LPWStr)] + public string ProxyBypass; } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/WinInet.cs b/src/ST.Client.Desktop.Windows/Internals/WinInet.cs index f68a1ee74..0112c125d 100644 --- a/src/ST.Client.Desktop.Windows/Internals/WinInet.cs +++ b/src/ST.Client.Desktop.Windows/Internals/WinInet.cs @@ -1,129 +1,126 @@ +using System; using System.Net; using System.Runtime.InteropServices; using System.Text; -// ReSharper disable once CheckNamespace -namespace System +internal static class WinInet { - internal static class WinInet - { - // For PInvoke: Initiates the enumeration of the cache groups in the Internet cache - [DllImport(@"wininet", - SetLastError = true, - CharSet = CharSet.Auto, - EntryPoint = "FindFirstUrlCacheGroup", - CallingConvention = CallingConvention.StdCall)] - public static extern IntPtr FindFirstUrlCacheGroup( - int dwFlags, - int dwFilter, - IntPtr lpSearchCondition, - int dwSearchCondition, - ref long lpGroupId, - IntPtr lpReserved); + // For PInvoke: Initiates the enumeration of the cache groups in the Internet cache + [DllImport(@"wininet", + SetLastError = true, + CharSet = CharSet.Auto, + EntryPoint = "FindFirstUrlCacheGroup", + CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr FindFirstUrlCacheGroup( + int dwFlags, + int dwFilter, + IntPtr lpSearchCondition, + int dwSearchCondition, + ref long lpGroupId, + IntPtr lpReserved); - // For PInvoke: Retrieves the next cache group in a cache group enumeration - [DllImport(@"wininet", - SetLastError = true, - CharSet = CharSet.Auto, - EntryPoint = "FindNextUrlCacheGroup", - CallingConvention = CallingConvention.StdCall)] - public static extern bool FindNextUrlCacheGroup( - IntPtr hFind, - ref long lpGroupId, - IntPtr lpReserved); + // For PInvoke: Retrieves the next cache group in a cache group enumeration + [DllImport(@"wininet", + SetLastError = true, + CharSet = CharSet.Auto, + EntryPoint = "FindNextUrlCacheGroup", + CallingConvention = CallingConvention.StdCall)] + public static extern bool FindNextUrlCacheGroup( + IntPtr hFind, + ref long lpGroupId, + IntPtr lpReserved); - // For PInvoke: Releases the specified GROUPID and any associated state in the cache index file - [DllImport(@"wininet", - SetLastError = true, - CharSet = CharSet.Auto, - EntryPoint = "DeleteUrlCacheGroup", - CallingConvention = CallingConvention.StdCall)] - public static extern bool DeleteUrlCacheGroup( - long groupId, - int dwFlags, - IntPtr lpReserved); + // For PInvoke: Releases the specified GROUPID and any associated state in the cache index file + [DllImport(@"wininet", + SetLastError = true, + CharSet = CharSet.Auto, + EntryPoint = "DeleteUrlCacheGroup", + CallingConvention = CallingConvention.StdCall)] + public static extern bool DeleteUrlCacheGroup( + long groupId, + int dwFlags, + IntPtr lpReserved); - // For PInvoke: Begins the enumeration of the Internet cache - [DllImport(@"wininet", - SetLastError = true, - CharSet = CharSet.Auto, - EntryPoint = "FindFirstUrlCacheEntryA", - CallingConvention = CallingConvention.StdCall)] - public static extern IntPtr FindFirstUrlCacheEntry( - [MarshalAs(UnmanagedType.LPWStr)] string lpszUrlSearchPattern, - IntPtr lpFirstCacheEntryInfo, - ref int lpdwFirstCacheEntryInfoBufferSize); + // For PInvoke: Begins the enumeration of the Internet cache + [DllImport(@"wininet", + SetLastError = true, + CharSet = CharSet.Auto, + EntryPoint = "FindFirstUrlCacheEntryA", + CallingConvention = CallingConvention.StdCall)] + public static extern IntPtr FindFirstUrlCacheEntry( + [MarshalAs(UnmanagedType.LPWStr)] string lpszUrlSearchPattern, + IntPtr lpFirstCacheEntryInfo, + ref int lpdwFirstCacheEntryInfoBufferSize); - // For PInvoke: Retrieves the next entry in the Internet cache - [DllImport(@"wininet", - SetLastError = true, - CharSet = CharSet.Auto, - EntryPoint = "FindNextUrlCacheEntryA", - CallingConvention = CallingConvention.StdCall)] - public static extern bool FindNextUrlCacheEntry( - IntPtr hFind, - IntPtr lpNextCacheEntryInfo, - ref int lpdwNextCacheEntryInfoBufferSize); + // For PInvoke: Retrieves the next entry in the Internet cache + [DllImport(@"wininet", + SetLastError = true, + CharSet = CharSet.Auto, + EntryPoint = "FindNextUrlCacheEntryA", + CallingConvention = CallingConvention.StdCall)] + public static extern bool FindNextUrlCacheEntry( + IntPtr hFind, + IntPtr lpNextCacheEntryInfo, + ref int lpdwNextCacheEntryInfoBufferSize); - // For PInvoke: Removes the file that is associated with the source name from the cache, if the file exists - [DllImport(@"wininet", - SetLastError = true, - CharSet = CharSet.Auto, - EntryPoint = "DeleteUrlCacheEntryA", - CallingConvention = CallingConvention.StdCall)] - public static extern bool DeleteUrlCacheEntry( - IntPtr lpszUrlName); + // For PInvoke: Removes the file that is associated with the source name from the cache, if the file exists + [DllImport(@"wininet", + SetLastError = true, + CharSet = CharSet.Auto, + EntryPoint = "DeleteUrlCacheEntryA", + CallingConvention = CallingConvention.StdCall)] + public static extern bool DeleteUrlCacheEntry( + IntPtr lpszUrlName); - [DllImport("wininet.dll", - SetLastError = true, + [DllImport("wininet.dll", + SetLastError = true, CharSet = CharSet.Unicode, - EntryPoint = "InternetGetCookieEx", - CallingConvention = CallingConvention.StdCall)] - public static extern bool InternetGetCookieEx( - string url, - string? cookieName, - StringBuilder cookieData, - ref int size, - int dwFlags, - IntPtr lpReserved); + EntryPoint = "InternetGetCookieEx", + CallingConvention = CallingConvention.StdCall)] + public static extern bool InternetGetCookieEx( + string url, + string? cookieName, + StringBuilder cookieData, + ref int size, + int dwFlags, + IntPtr lpReserved); - //Read HTTP Only - const int InternetCookieHttponly = 0x2000; + //Read HTTP Only + const int InternetCookieHttponly = 0x2000; - public static CookieContainer? GetUriCookieContainer(Uri uri) + public static CookieContainer? GetUriCookieContainer(Uri uri) + { + // First, create a null cookie container + CookieContainer? cookies = null; + + // Determine the size of the cookie + var datasize = 8192 * 16; + var cookieData = new StringBuilder(datasize); + + // Call InternetGetCookieEx from wininet.dll + if (!InternetGetCookieEx(uri.ToString(), null, cookieData, ref datasize, InternetCookieHttponly, IntPtr.Zero)) { - // First, create a null cookie container - CookieContainer? cookies = null; - - // Determine the size of the cookie - var datasize = 8192 * 16; - var cookieData = new StringBuilder(datasize); - - // Call InternetGetCookieEx from wininet.dll - if (!InternetGetCookieEx(uri.ToString(), null, cookieData, ref datasize, InternetCookieHttponly, IntPtr.Zero)) - { - if (datasize < 0) - return null; - // Allocate stringbuilder large enough to hold the cookie - cookieData = new StringBuilder(datasize); - if (!InternetGetCookieEx( - uri.ToString(), - null, cookieData, - ref datasize, - InternetCookieHttponly, - IntPtr.Zero)) - return null; - } - - // If the cookie contains data, add it to the cookie container - if (cookieData.Length > 0) - { - cookies = new CookieContainer(); - cookies.SetCookies(uri, cookieData.ToString().Replace(';', ',')); - } - - // Return the cookie container - return cookies; + if (datasize < 0) + return null; + // Allocate stringbuilder large enough to hold the cookie + cookieData = new StringBuilder(datasize); + if (!InternetGetCookieEx( + uri.ToString(), + null, cookieData, + ref datasize, + InternetCookieHttponly, + IntPtr.Zero)) + return null; } + + // If the cookie contains data, add it to the cookie container + if (cookieData.Length > 0) + { + cookies = new CookieContainer(); + cookies.SetCookies(uri, cookieData.ToString().Replace(';', ',')); + } + + // Return the cookie container + return cookies; } } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Internals/WindowLongFlags.cs b/src/ST.Client.Desktop.Windows/Internals/WindowLongFlags.cs new file mode 100644 index 000000000..c6944117a --- /dev/null +++ b/src/ST.Client.Desktop.Windows/Internals/WindowLongFlags.cs @@ -0,0 +1,9 @@ +using System; + +[Flags] +internal enum WindowLongFlags +{ + GWL_STYLE = -16, + GWL_EXSTYLE = -20, + WS_EX_NOACTIVATE = 0x8000000, +} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/MouseEventArgs.cs b/src/ST.Client.Desktop.Windows/MouseEventArgs.cs deleted file mode 100644 index ee60166ef..000000000 --- a/src/ST.Client.Desktop.Windows/MouseEventArgs.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System.Application -{ - public class MouseEventArgs : EventArgs - { - - public MouseEventArgs(PointInt32 point) - { - MousePosition = point; - } - - public MouseEventArgs(int x, int y) - { - MousePosition = new PointInt32(x, y); - } - - /// - /// 指针位置 - /// - public PointInt32 MousePosition { get; set; } - } -} diff --git a/src/ST.Client.Desktop.Windows/UI/Resx/SR.Designer.cs b/src/ST.Client.Desktop.Windows/Properties/SR.Designer.cs similarity index 96% rename from src/ST.Client.Desktop.Windows/UI/Resx/SR.Designer.cs rename to src/ST.Client.Desktop.Windows/Properties/SR.Designer.cs index ba0935925..ea0fc2982 100644 --- a/src/ST.Client.Desktop.Windows/UI/Resx/SR.Designer.cs +++ b/src/ST.Client.Desktop.Windows/Properties/SR.Designer.cs @@ -8,7 +8,7 @@ // //------------------------------------------------------------------------------ -namespace System.Application.UI.Resx { +namespace System.Application.Properties { using System; @@ -19,7 +19,7 @@ namespace System.Application.UI.Resx { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class SR { @@ -39,7 +39,7 @@ namespace System.Application.UI.Resx { internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Application.UI.Resx.SR", typeof(SR).Assembly); + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("System.Application.Properties.SR", typeof(SR).Assembly); resourceMan = temp; } return resourceMan; diff --git a/src/ST.Client.Desktop.Windows/UI/Resx/SR.resx b/src/ST.Client.Desktop.Windows/Properties/SR.resx similarity index 100% rename from src/ST.Client.Desktop.Windows/UI/Resx/SR.resx rename to src/ST.Client.Desktop.Windows/Properties/SR.resx diff --git a/src/ST.Client.Desktop.Windows/ST.Client.Desktop.Windows.csproj b/src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj similarity index 92% rename from src/ST.Client.Desktop.Windows/ST.Client.Desktop.Windows.csproj rename to src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj index 98e716908..0ad731287 100644 --- a/src/ST.Client.Desktop.Windows/ST.Client.Desktop.Windows.csproj +++ b/src/ST.Client.Desktop.Windows/ST.Client.Windows.csproj @@ -46,8 +46,7 @@ - - + @@ -63,7 +62,7 @@
- + True True SR.resx @@ -71,7 +70,7 @@ - + ResXFileCodeGenerator SR.Designer.cs diff --git a/src/ST.Client.Desktop.Windows/ServiceCollectionExtensions.cs b/src/ST.Client.Desktop.Windows/ServiceCollectionExtensions.cs index e8912188c..10ad57443 100644 --- a/src/ST.Client.Desktop.Windows/ServiceCollectionExtensions.cs +++ b/src/ST.Client.Desktop.Windows/ServiceCollectionExtensions.cs @@ -10,15 +10,13 @@ namespace Microsoft.Extensions.DependencyInjection { public static partial class ServiceCollectionExtensions { - public static IServiceCollection AddDesktopPlatformService(this IServiceCollection services, bool hasSteam, bool hasGUI, bool hasNotifyIcon) + public static IServiceCollection AddPlatformService(this IServiceCollection services, bool hasSteam, bool hasGUI, bool hasNotifyIcon) { if (OperatingSystem2.IsWindows) { - services.AddSingleton(); - services.AddSingleton(); - services.AddSingleton(s => s.GetRequiredService()); - services.AddSingleton(s => s.GetRequiredService()); - services.AddSingleton(s => s.GetRequiredService()); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(s => s.GetRequiredService()); if (hasSteam) { services.AddSingleton(); @@ -32,6 +30,7 @@ namespace Microsoft.Extensions.DependencyInjection services.AddSingleton(s => s.GetRequiredService()); if (OperatingSystem2.IsWindows10AtLeast) { + services.AddSingleton(s => s.GetRequiredService()); services.AddSingleton(); } services.AddSingleton(); diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/JumpListServiceImpl.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/JumpListServiceImpl.cs index e455db237..82024d7b8 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/JumpListServiceImpl.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/JumpListServiceImpl.cs @@ -1,19 +1,52 @@ extern alias JumpLists; using JumpLists::System.Windows.Shell; -using JumpList = System.Application.UI.JumpLists; +using AvaloniaApplication = Avalonia.Application; +using System.Linq; namespace System.Application.Services.Implementation { + /// internal sealed class JumpListServiceImpl : IJumpListService { public void InitJumpList() { - JumpList.Init(); + var jumpList1 = new JumpList + { + ShowRecentCategory = true, + ShowFrequentCategory = false, + }; + //jumpList1.JumpItemsRejected += JumpList1_JumpItemsRejected; + //jumpList1.JumpItemsRemovedByUser += JumpList1_JumpItemsRemovedByUser; + //jumpList1.JumpItems.Add(new JumpTask + //{ + // Title = "RuaRua", + // Description = "以该账号启动Steam", + // ApplicationPath = AppHelper.ProgramPath, + // Arguments = "-clt steam -account ruarua", + // IconResourcePath = AppHelper.ProgramPath, + //}); + //jumpList1.JumpItems.Add(new JumpTask + //{ + // Title = "Read Me", + // Description = "Open readme.txt in Notepad.", + // ApplicationPath = @"C:\Windows\notepad.exe", + // IconResourcePath = @"C:\Windows\System32\imageres.dll", + // IconResourceIndex = 14, + // WorkingDirectory = @"C:\Users\Public\Documents", + // Arguments = "readme.txt", + //}); + //JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current); + //if (jumpList1 != null) + //{ + // jumpList1.JumpItems.Clear(); + // jumpList1.Apply(); + //} + JumpList.SetJumpList(AvaloniaApplication.Current, jumpList1); } public void AddJumpTask(string title, string applicationPath, string iconResourcePath, string arguments = "", string description = "", string customCategory = "") { - JumpList.AddJumpTask(new JumpTask + AddJumpTask(new JumpTask { // Get the path to Calculator and set the JumpTask properties. ApplicationPath = applicationPath, @@ -24,5 +57,53 @@ namespace System.Application.Services.Implementation CustomCategory = customCategory, }); } + + public static void AddJumpTask(JumpTask task, bool isRecent = false) + { + // Get the JumpList from the application and update it. + JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current); + if (jumpList1 != null) + { + var tk = jumpList1.JumpItems.FirstOrDefault(s => s is JumpTask t && t.ApplicationPath == task.ApplicationPath && t.Arguments == task.Arguments); + if (tk != null) + { + jumpList1.JumpItems.Remove(tk); + } + jumpList1.JumpItems.Add(task); + if (isRecent) + JumpList.AddToRecentCategory(task); + MainThread2.BeginInvokeOnMainThread(() => jumpList1.Apply()); + } + } + + public static void AddRecentJumpTask(JumpTask task) + { + // Get the JumpList from the application and update it. + JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current); + if (jumpList1 != null) + { + JumpList.AddToRecentCategory(task); + MainThread2.BeginInvokeOnMainThread(() => jumpList1.Apply()); + } + } + + //static void AddJumpTask() + //{ + // // Configure a new JumpTask. + // var jumpTask1 = new JumpTask + // { + // // Get the path to Calculator and set the JumpTask properties. + // ApplicationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe"), + // IconResourcePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe"), + // Title = "Calculator", + // Description = "Open Calculator.", + // CustomCategory = "User Added Tasks" + // }; + // // Get the JumpList from the application and update it. + // JumpList jumpList1 = JumpList.GetJumpList(WpfApplication.Current); + // jumpList1.JumpItems.Add(jumpTask1); + // JumpList.AddToRecentCategory(jumpTask1); + // jumpList1.Apply(); + //} } } \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/NativeWindowApiServiceImpl.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/NativeWindowApiServiceImpl.cs index b2cc2977c..120d067ee 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/NativeWindowApiServiceImpl.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/NativeWindowApiServiceImpl.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Text; +using System.Windows; namespace System.Application.Services.Implementation { @@ -15,7 +16,7 @@ namespace System.Application.Services.Implementation /// 目标窗口回调 public void GetMoveMouseDownWindow(Action action) { - void MouseHook_OnMouseUp(object? sender, PointDouble p) + void MouseHook_OnMouseUp(object? sender, Point p) { //Point GetMousePos = Mouse.GetPosition(App.Current.MainWindow); //Name = System.Windows.Forms.Cursor.Position.X + "," + System.Windows.Forms.Cursor.Position.Y; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/PlatformHttpPlatformHelper.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsClientHttpPlatformHelperServiceImpl.cs similarity index 93% rename from src/ST.Client.Desktop.Windows/Services/Implementation/PlatformHttpPlatformHelper.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsClientHttpPlatformHelperServiceImpl.cs index 168fe55fd..9fbc06fa0 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/PlatformHttpPlatformHelper.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsClientHttpPlatformHelperServiceImpl.cs @@ -4,7 +4,7 @@ using Xamarin.Essentials; namespace System.Application.Services.Implementation { - internal sealed class PlatformHttpPlatformHelper : DesktopHttpPlatformHelper + internal sealed class WindowsClientHttpPlatformHelperServiceImpl : ClientHttpPlatformHelperServiceImpl { static readonly Lazy mUserAgent = new(() => { @@ -14,7 +14,7 @@ namespace System.Application.Services.Implementation public override string UserAgent => mUserAgent.Value; - public override bool IsConnected + protected override bool IsConnected { get { diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.Administrator.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.Administrator.cs similarity index 82% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.Administrator.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.Administrator.cs index ef2ad3cdd..c3f28b655 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.Administrator.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.Administrator.cs @@ -2,7 +2,7 @@ using System.Security.Principal; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { #region Administrator @@ -18,7 +18,7 @@ namespace System.Application.Services.Implementation /// public static bool IsAdministrator => mIsAdministrator.Value; - bool IDesktopPlatformService.IsAdministrator => IsAdministrator; + bool IPlatformService.IsAdministrator => IsAdministrator; #endregion } diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.Encoding.Default.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.Encoding.Default.cs similarity index 96% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.Encoding.Default.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.Encoding.Default.cs index f345ed61a..ffd6bd049 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.Encoding.Default.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.Encoding.Default.cs @@ -2,7 +2,7 @@ using System.Text; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { static volatile Encoding? defaultEncoding; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IDisposable.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IDisposable.cs similarity index 94% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IDisposable.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IDisposable.cs index 3ef9d02c4..f55dbab28 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IDisposable.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IDisposable.cs @@ -1,6 +1,6 @@ namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl : IDisposable + partial class WindowsPlatformServiceImpl : IDisposable { bool disposedValue; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IEmailPlatformService.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IEmailPlatformService.cs similarity index 93% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IEmailPlatformService.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IEmailPlatformService.cs index 4dfd6a96f..680d8398a 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IEmailPlatformService.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IEmailPlatformService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.IO; +using System.Runtime.Versioning; using System.Threading.Tasks; using Windows.ApplicationModel.Email; using Windows.Foundation.Metadata; @@ -12,12 +13,13 @@ using NativeEmailMessage = Windows.ApplicationModel.Email.EmailMessage; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl : IEmailPlatformService + partial class WindowsPlatformServiceImpl : IEmailPlatformService { // https://github.com/xamarin/Essentials/blob/main/Xamarin.Essentials/Email/Email.uwp.cs static string NormalizePath(string path) => path.Replace('/', Path.DirectorySeparatorChar); + [SupportedOSPlatform("Windows10.0.10240.0")] public async Task PlatformComposeAsync(EmailMessage? message) { var isComposeSupported = ApiInformation.IsTypePresent("Windows.ApplicationModel.Email.EmailManager"); @@ -60,6 +62,7 @@ namespace System.Application.Services.Implementation await EmailManager.ShowComposeNewEmailAsync(nativeMessage); } + [SupportedOSPlatform("Windows10.0.10240.0")] static void Sync(List recipients, IList nativeRecipients) { if (recipients == null) diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IFilePickerPlatformService.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IFilePickerPlatformService.cs similarity index 96% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IFilePickerPlatformService.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IFilePickerPlatformService.cs index 4f6224fa5..c8f27ebe1 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.IFilePickerPlatformService.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.IFilePickerPlatformService.cs @@ -12,7 +12,7 @@ using static System.Application.Services.IFilePickerPlatformService.IServiceBase namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl : IOpenFileDialogService + partial class WindowsPlatformServiceImpl : IOpenFileDialogService { bool IOpenFileDialogService.IsSupportedFileExtensionFilter => true; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.LightMode.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.LightMode.cs similarity index 95% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.LightMode.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.LightMode.cs index cbd6db845..018de2911 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.LightMode.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.LightMode.cs @@ -6,7 +6,7 @@ using System.Security.Principal; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { const string Themes_Personalize = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize"; const string AppsUseLightTheme = "AppsUseLightTheme"; @@ -71,7 +71,7 @@ namespace System.Application.Services.Implementation var theme_value = value.Value ? AppTheme.Light : AppTheme.Dark; MainThread2.BeginInvokeOnMainThread(() => { - IDesktopApplication.Instance.SetThemeNotChangeValue(theme_value); + app.SetThemeNotChangeValue(theme_value); }); } }; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.OSVersion.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.OSVersion.cs similarity index 97% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.OSVersion.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.OSVersion.cs index 879cf6531..61991bef0 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.OSVersion.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.OSVersion.cs @@ -9,7 +9,7 @@ using Microsoft.Win32; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { static (string productName, int revision, string releaseIdOrDisplayVersion) GetWinNTCurrentVersion() { diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.OpenDesktopIconsSettings.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.OpenDesktopIconsSettings.cs similarity index 94% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.OpenDesktopIconsSettings.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.OpenDesktopIconsSettings.cs index 5f854f8ca..881529c73 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.OpenDesktopIconsSettings.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.OpenDesktopIconsSettings.cs @@ -2,7 +2,7 @@ using System.Diagnostics; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { #region rundll32 command list public const string OpenDesktopIconsSettingsCommandArguments = "shell32.dll,Control_RunDLL desk.cpl,,0"; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.UnelevatedProcessStarter.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.UnelevatedProcessStarter.cs similarity index 99% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.UnelevatedProcessStarter.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.UnelevatedProcessStarter.cs index dfbf171a4..dc0f8ba6b 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.UnelevatedProcessStarter.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.UnelevatedProcessStarter.cs @@ -3,7 +3,7 @@ using System.Runtime.InteropServices; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { public void UnelevatedProcessStart(string cmdArgs) { diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.WindowTopRightButtons.cs similarity index 94% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.WindowTopRightButtons.cs index ac9b6aae3..a31f6b33e 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.WindowTopRightButtons.cs @@ -3,7 +3,7 @@ using System.Windows; namespace System.Application.Services.Implementation { - partial class WindowsDesktopPlatformServiceImpl + partial class WindowsPlatformServiceImpl { #region 窗口右上角的三个按钮(最小化,最大化,关闭) @@ -79,16 +79,16 @@ namespace System.Application.Services.Implementation _ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX); } - public void SetResizeMode(IntPtr hWnd, ResizeModeCompat value) + public void SetResizeMode(IntPtr hWnd, ResizeMode value) { switch (value) { - case ResizeModeCompat.NoResize: + case ResizeMode.NoResize: _ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MAXIMIZE, MF_BYCOMMAND); _ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MINIMIZE, MF_BYCOMMAND); HideMinimizeAndMaximizeButtons(hWnd); break; - case ResizeModeCompat.CanMinimize: + case ResizeMode.CanMinimize: _ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MAXIMIZE, MF_BYCOMMAND); DisableMaximizeButton(hWnd); break; diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.cs similarity index 96% rename from src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs rename to src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.cs index 60872ac43..6b781b496 100644 --- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.cs +++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsPlatformServiceImpl.cs @@ -20,11 +20,19 @@ using Windows.ApplicationModel; namespace System.Application.Services.Implementation { [SupportedOSPlatform("Windows")] - internal sealed partial class WindowsDesktopPlatformServiceImpl : IDesktopPlatformService + internal sealed partial class WindowsPlatformServiceImpl : IPlatformService { - const string TAG = "WindowsDesktopPlatformS"; + const string TAG = "WindowsPlatformS"; const string SteamRegistryPath = @"SOFTWARE\Valve\Steam"; + + readonly IApplication app; + public WindowsPlatformServiceImpl(IApplication app) + { + this.app = app; + } + public string? GetRegistryVdfPath() { return null; } + public string GetCommandLineArgs(Process process) { try @@ -171,8 +179,8 @@ namespace System.Application.Services.Implementation td.Settings.StopIfGoingOnBatteries = false; td.Settings.DisallowStartIfOnBatteries = false; td.Triggers.Add(new LogonTrigger { UserId = userId }); - td.Actions.Add(new ExecAction(AppHelper.ProgramName, - IDesktopPlatformService.SystemBootRunArguments, + td.Actions.Add(new ExecAction(IApplication.ProgramName, + IPlatformService.SystemBootRunArguments, IOPath.BaseDirectory)); if (IsAdministrator) td.Principal.RunLevel = TaskRunLevel.Highest; @@ -238,7 +246,7 @@ namespace System.Application.Services.Implementation static string GetMachineSecretKey() => Registry.LocalMachine.Read(@"SOFTWARE\Microsoft\Cryptography", "MachineGuid"); - static readonly Lazy<(byte[] key, byte[] iv)> mMachineSecretKey = IDesktopPlatformService.GetMachineSecretKey(GetMachineSecretKey); + static readonly Lazy<(byte[] key, byte[] iv)> mMachineSecretKey = IPlatformService.GetMachineSecretKey(GetMachineSecretKey); public (byte[] key, byte[] iv) MachineSecretKey => mMachineSecretKey.Value; diff --git a/src/ST.Client.Desktop.Windows/UI/JumpLists.cs b/src/ST.Client.Desktop.Windows/UI/JumpLists.cs deleted file mode 100644 index 0fd3f749b..000000000 --- a/src/ST.Client.Desktop.Windows/UI/JumpLists.cs +++ /dev/null @@ -1,100 +0,0 @@ -extern alias JumpLists; -using JumpLists::System.Windows.Shell; -using AvaloniaApplication = Avalonia.Application; -using System.Linq; - -namespace System.Application.UI -{ - /// - /// 表示作为菜单显示在 Windows 7 任务栏按钮上的项和任务的列表。 - /// - /// Taskbar Extensions - /// - /// - public static class JumpLists - { - public static void Init() - { - var jumpList1 = new JumpList - { - ShowRecentCategory = true, - ShowFrequentCategory = false, - }; - //jumpList1.JumpItemsRejected += JumpList1_JumpItemsRejected; - //jumpList1.JumpItemsRemovedByUser += JumpList1_JumpItemsRemovedByUser; - //jumpList1.JumpItems.Add(new JumpTask - //{ - // Title = "RuaRua", - // Description = "以该账号启动Steam", - // ApplicationPath = AppHelper.ProgramPath, - // Arguments = "-clt steam -account ruarua", - // IconResourcePath = AppHelper.ProgramPath, - //}); - //jumpList1.JumpItems.Add(new JumpTask - //{ - // Title = "Read Me", - // Description = "Open readme.txt in Notepad.", - // ApplicationPath = @"C:\Windows\notepad.exe", - // IconResourcePath = @"C:\Windows\System32\imageres.dll", - // IconResourceIndex = 14, - // WorkingDirectory = @"C:\Users\Public\Documents", - // Arguments = "readme.txt", - //}); - //JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current); - //if (jumpList1 != null) - //{ - // jumpList1.JumpItems.Clear(); - // jumpList1.Apply(); - //} - JumpList.SetJumpList(AvaloniaApplication.Current, jumpList1); - } - - public static void AddJumpTask(JumpTask task, bool isRecent = false) - { - // Get the JumpList from the application and update it. - JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current); - if (jumpList1 != null) - { - var tk = jumpList1.JumpItems.FirstOrDefault(s => s is JumpTask t && t.ApplicationPath == task.ApplicationPath && t.Arguments == task.Arguments); - if (tk != null) - { - jumpList1.JumpItems.Remove(tk); - } - jumpList1.JumpItems.Add(task); - if (isRecent) - JumpList.AddToRecentCategory(task); - MainThread2.BeginInvokeOnMainThread(() => jumpList1.Apply()); - } - } - - public static void AddRecentJumpTask(JumpTask task) - { - // Get the JumpList from the application and update it. - JumpList jumpList1 = JumpList.GetJumpList(AvaloniaApplication.Current); - if (jumpList1 != null) - { - JumpList.AddToRecentCategory(task); - MainThread2.BeginInvokeOnMainThread(() => jumpList1.Apply()); - } - } - - //static void AddJumpTask() - //{ - // // Configure a new JumpTask. - // var jumpTask1 = new JumpTask - // { - // // Get the path to Calculator and set the JumpTask properties. - // ApplicationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe"), - // IconResourcePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.SystemX86), "calc.exe"), - // Title = "Calculator", - // Description = "Open Calculator.", - // CustomCategory = "User Added Tasks" - // }; - // // Get the JumpList from the application and update it. - // JumpList jumpList1 = JumpList.GetJumpList(WpfApplication.Current); - // jumpList1.JumpItems.Add(jumpTask1); - // JumpList.AddToRecentCategory(jumpTask1); - // jumpList1.Apply(); - //} - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Windows/Generated/Point.cs b/src/ST.Client.Desktop.Windows/Windows/Generated/Point.cs new file mode 100644 index 000000000..6050a877f --- /dev/null +++ b/src/ST.Client.Desktop.Windows/Windows/Generated/Point.cs @@ -0,0 +1,321 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// https://github.com/dotnet/wpf/blob/v6.0.0-rc.2.21501.7/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Generated/Point.cs +// +// +// This file was generated, please do not edit it directly. +// +// Please see MilCodeGen.html for more information. +// + +namespace System.Windows +{ + [Serializable] + partial struct Point : IFormattable + { + //------------------------------------------------------ + // + // Public Methods + // + //------------------------------------------------------ + + #region Public Methods + + + + + /// + /// Compares two Point instances for exact equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which are logically equal may fail. + /// Furthermore, using this equality operator, Double.NaN is not equal to itself. + /// + /// + /// bool - true if the two Point instances are exactly equal, false otherwise + /// + /// The first Point to compare + /// The second Point to compare + public static bool operator ==(Point point1, Point point2) + { + return point1.X == point2.X && + point1.Y == point2.Y; + } + + /// + /// Compares two Point instances for exact inequality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which are logically equal may fail. + /// Furthermore, using this equality operator, Double.NaN is not equal to itself. + /// + /// + /// bool - true if the two Point instances are exactly unequal, false otherwise + /// + /// The first Point to compare + /// The second Point to compare + public static bool operator !=(Point point1, Point point2) + { + return !(point1 == point2); + } + /// + /// Compares two Point instances for object equality. In this equality + /// Double.NaN is equal to itself, unlike in numeric equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which + /// are logically equal may fail. + /// + /// + /// bool - true if the two Point instances are exactly equal, false otherwise + /// + /// The first Point to compare + /// The second Point to compare + public static bool Equals(Point point1, Point point2) + { + return point1.X.Equals(point2.X) && + point1.Y.Equals(point2.Y); + } + + /// + /// Equals - compares this Point with the passed in object. In this equality + /// Double.NaN is equal to itself, unlike in numeric equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which + /// are logically equal may fail. + /// + /// + /// bool - true if the object is an instance of Point and if it's equal to "this". + /// + /// The object to compare to "this" + public override bool Equals(object? o) + { + if ((null == o) || o is not Point) + { + return false; + } + + Point value = (Point)o; + return Point.Equals(this, value); + } + + /// + /// Equals - compares this Point with the passed in object. In this equality + /// Double.NaN is equal to itself, unlike in numeric equality. + /// Note that double values can acquire error when operated upon, such that + /// an exact comparison between two values which + /// are logically equal may fail. + /// + /// + /// bool - true if "value" is equal to "this". + /// + /// The Point to compare to "this" + public bool Equals(Point value) + { + return Point.Equals(this, value); + } + /// + /// Returns the HashCode for this Point + /// + /// + /// int - the HashCode for this Point + /// + public override int GetHashCode() + { + // Perform field-by-field XOR of HashCodes + return X.GetHashCode() ^ + Y.GetHashCode(); + } + + #endregion Public Methods + + //------------------------------------------------------ + // + // Public Properties + // + //------------------------------------------------------ + + + + + #region Public Properties + + /// + /// X - double. Default value is 0. + /// + public double X + { + get + { + return _x; + } + + set + { + _x = value; + } + } + + /// + /// Y - double. Default value is 0. + /// + public double Y + { + get + { + return _y; + } + + set + { + _y = value; + } + } + + #endregion Public Properties + + //------------------------------------------------------ + // + // Protected Methods + // + //------------------------------------------------------ + + #region Protected Methods + + + + + + #endregion ProtectedMethods + + //------------------------------------------------------ + // + // Internal Methods + // + //------------------------------------------------------ + + #region Internal Methods + + + + + + + + + + #endregion Internal Methods + + //------------------------------------------------------ + // + // Internal Properties + // + //------------------------------------------------------ + + #region Internal Properties + + + /// + /// Creates a string representation of this object based on the current culture. + /// + /// + /// A string representation of this object. + /// + public override string ToString() + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, null /* format provider */); + } + + /// + /// Creates a string representation of this object based on the IFormatProvider + /// passed in. If the provider is null, the CurrentCulture is used. + /// + /// + /// A string representation of this object. + /// + public string ToString(IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(null /* format string */, provider); + } + + /// + /// Creates a string representation of this object based on the format string + /// and IFormatProvider passed in. + /// If the provider is null, the CurrentCulture is used. + /// See the documentation for IFormattable for more information. + /// + /// + /// A string representation of this object. + /// + string IFormattable.ToString(string format, IFormatProvider provider) + { + // Delegate to the internal method which implements all ToString calls. + return ConvertToString(format, provider); + } + + /// + /// Creates a string representation of this object based on the format string + /// and IFormatProvider passed in. + /// If the provider is null, the CurrentCulture is used. + /// See the documentation for IFormattable for more information. + /// + /// + /// A string representation of this object. + /// + internal string ConvertToString(string format, IFormatProvider provider) + { + // Helper to get the numeric list separator for a given culture. + char separator = MS.Internal.TokenizerHelper.GetNumericListSeparator(provider); + return String.Format(provider, + "{1:" + format + "}{0}{2:" + format + "}", + separator, + _x, + _y); + } + + + + #endregion Internal Properties + + //------------------------------------------------------ + // + // Dependency Properties + // + //------------------------------------------------------ + + #region Dependency Properties + + + + #endregion Dependency Properties + + //------------------------------------------------------ + // + // Internal Fields + // + //------------------------------------------------------ + + #region Internal Fields + + + internal double _x; + internal double _y; + + #endregion Internal Fields + + + + #region Constructors + + //------------------------------------------------------ + // + // Constructors + // + //------------------------------------------------------ + + + + + #endregion Constructors + } +} \ No newline at end of file diff --git a/src/ST.Client.Desktop.Windows/Windows/Point.cs b/src/ST.Client.Desktop.Windows/Windows/Point.cs new file mode 100644 index 000000000..40816a2a8 --- /dev/null +++ b/src/ST.Client.Desktop.Windows/Windows/Point.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +// https://github.com/dotnet/wpf/blob/v6.0.0-rc.2.21501.7/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Point.cs +// + +using System.Drawing; +using PointInt32 = System.Drawing.Point; + +namespace System.Windows +{ + /// + /// Point - Defaults to 0,0 + /// + public partial struct Point + { + #region Constructors + + /// + /// Constructor which accepts the X and Y values + /// + /// The value for the X coordinate of the new Point + /// The value for the Y coordinate of the new Point + public Point(double x, double y) + { + _x = x; + _y = y; + } + + #endregion Constructors + + #region Public Methods + + /// + /// Offset - update the location by adding offsetX to X and offsetY to Y + /// + /// The offset in the x dimension + /// The offset in the y dimension + public void Offset(double offsetX, double offsetY) + { + _x += offsetX; + _y += offsetY; + } + + /// + /// Explicit conversion to Size. Note that since Size cannot contain negative values, + /// the resulting size will contains the absolute values of X and Y + /// + /// + /// Size - A Size equal to this Point + /// + /// Point - the Point to convert to a Size + public static explicit operator Size(Point point) + { + return new Size(Convert.ToInt32(Math.Abs(point._x)), Convert.ToInt32(Math.Abs(point._y))); + } + + public static explicit operator PointInt32(Point point) + { + return new PointInt32(Convert.ToInt32(point._x), Convert.ToInt32(point._y)); + } + + #endregion Public Methods + } +} \ No newline at end of file diff --git a/src/ST.Client.Desktop/ImageSouceHelper.cs b/src/ST.Client.Desktop/ImageSouceHelper.cs deleted file mode 100644 index 5a27dc5ee..000000000 --- a/src/ST.Client.Desktop/ImageSouceHelper.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Diagnostics.CodeAnalysis; -using System.IO; -using static System.Application.ImageSouce; - -namespace System.Application -{ - public static class ImageSouceHelper - { - /// - /// 将图片文件本地路径或 Avalonia 资源路径转为图像源 - /// - /// - /// 是否为圆形 - /// 图像可配置选项 - /// - public static object? TryParse(string? filePathOrAvaloniaResPath, bool isCircle = false, Action? config = null) - { - if (filePathOrAvaloniaResPath == null) - return null; - if (filePathOrAvaloniaResPath.StartsWith("avares:")) - return filePathOrAvaloniaResPath; - ClipStream? clipStream = filePathOrAvaloniaResPath; - if (clipStream != null) - { - clipStream.Circle = isCircle; - config?.Invoke(clipStream); - } - return clipStream; - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/ST.Client.Desktop.csproj b/src/ST.Client.Desktop/ST.Client.Desktop.csproj index fb71ff634..70a237eef 100644 --- a/src/ST.Client.Desktop/ST.Client.Desktop.csproj +++ b/src/ST.Client.Desktop/ST.Client.Desktop.csproj @@ -57,4 +57,17 @@ SR.Designer.cs + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/ST.Client.Desktop/ServiceCollectionExtensions.AddGeneralLogging.cs b/src/ST.Client.Desktop/ServiceCollectionExtensions.AddGeneralLogging.cs index 12cade01f..54e5adab9 100644 --- a/src/ST.Client.Desktop/ServiceCollectionExtensions.AddGeneralLogging.cs +++ b/src/ST.Client.Desktop/ServiceCollectionExtensions.AddGeneralLogging.cs @@ -15,7 +15,7 @@ namespace Microsoft.Extensions.DependencyInjection /// public static IServiceCollection AddGeneralLogging(this IServiceCollection services) { - var (minLevel, action) = AppHelper.ConfigureLogging(); + var (minLevel, action) = IApplication.ConfigureLogging(); services.AddLogging(b => { action(b); diff --git a/src/ST.Client.Desktop/ServiceCollectionExtensions.cs b/src/ST.Client.Desktop/ServiceCollectionExtensions.cs deleted file mode 100644 index 2d6b80098..000000000 --- a/src/ST.Client.Desktop/ServiceCollectionExtensions.cs +++ /dev/null @@ -1,109 +0,0 @@ -using Microsoft.Extensions.DependencyInjection.Extensions; -using Microsoft.Extensions.Logging; -using System.Application.Services; -using System.Application.Services.Implementation; -using System.Application.UI; -using System.Net.Http; - -// ReSharper disable once CheckNamespace -namespace Microsoft.Extensions.DependencyInjection -{ - public static partial class ServiceCollectionExtensions - { - /// - /// 尝试添加适用于 Desktop 的 Toast - /// - /// - /// - public static IServiceCollection TryAddToast(this IServiceCollection services) - => PlatformToastImpl.TryAddToast(services); - - /// - /// 添加 hosts 文件助手服务 - /// - /// - /// - public static IServiceCollection AddHostsFileService(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } - - /// - /// 添加 Steam 相关助手、工具类服务 - /// - /// - /// - public static IServiceCollection AddSteamService(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } - - /// - /// 尝试添加 Steamworks LocalApi Service - /// - /// - /// - public static IServiceCollection TryAddSteamworksLocalApiService(this IServiceCollection services) - { - services.TryAddSingleton(); - return services; - } - - /// - /// 添加 SteamDb WebApi Service - /// - /// - /// - public static IServiceCollection AddSteamDbWebApiService(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } - - /// - /// 添加 Steamworks WebApi Service - /// - /// - /// - public static IServiceCollection AddSteamworksWebApiService(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } - - /// - /// 添加适用于桌面端的 - /// - /// - /// - public static IServiceCollection TryAddDesktopHttpPlatformHelper(this IServiceCollection services) - { - services.TryAddSingleton(); - return services; - } - - /// - /// 添加窗口服务 - /// - /// - /// - public static IServiceCollection AddWindowService(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } - - /// - /// 添加适用于桌面端的 - /// - /// - /// - public static IServiceCollection AddNotificationService(this IServiceCollection services) - { - services.AddSingleton(); - return services; - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs b/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs deleted file mode 100644 index 57d21ca53..000000000 --- a/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs +++ /dev/null @@ -1,285 +0,0 @@ -using System.Application.Models; -using System.Application.Settings; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Runtime.Versioning; -using System.Security.Cryptography; - -namespace System.Application.Services -{ - public partial interface IDesktopPlatformService : IPlatformService - { - protected new const string TAG = "DesktopPlatformS"; - - public new static IDesktopPlatformService Instance => DI.Get(); - - void SetResizeMode(IntPtr hWnd, ResizeMode value); - - /// - /// hosts 文件所在目录 - /// - string HostsFilePath => string.Format("{0}etc{0}hosts", Path.DirectorySeparatorChar); - - void IPlatformService.OpenFileByTextReader(string filePath) - { - TextReaderProvider? userProvider = null; - var p = GeneralSettings.TextReaderProvider.Value; - if (p != null) - { - var platform = DeviceInfo2.Platform; - if (p.ContainsKey(platform)) - { - var value = p[platform]; - if (!string.IsNullOrWhiteSpace(value)) - { - if (Enum.TryParse(value, out var enumValue)) - { - userProvider = enumValue; - } - else - { - try - { - Process2.StartPath(value, filePath); - return; - } - catch (Exception e) - { - Log.Error(TAG, e, "UserSettings OpenFileByTextReader Fail."); - } - } - } - } - } - - var providers = new List() { - TextReaderProvider.VSCode, - TextReaderProvider.Notepad }; - - if (userProvider.HasValue) - { - providers.Remove(userProvider.Value); - providers.Insert(0, userProvider.Value); - } - - foreach (var item in providers) - { - if (item == TextReaderProvider.VSCode && !OperatingSystem2.IsWindows) - { - // 其他平台的 VSCode 打开方式尚未实现 - continue; - } - try - { - var fileName = GetFileName(item); - if (fileName == null) continue; - Process2.StartPath(fileName, filePath); - return; - } - catch (Exception e) - { - if (item == TextReaderProvider.Notepad) - { - Log.Error(TAG, e, "OpenFileByTextReader Fail."); - } - } - } - } - - /// - /// 使用资源管理器打开某个路径 - /// - /// - void OpenFolder(string path) - { - sbyte isDirectory = -1; - FileInfo? fileInfo; - DirectoryInfo directoryInfo = new(path); - if (directoryInfo.Exists) // 路径为文件夹,则打开文件夹 - { - fileInfo = null; - isDirectory = 1; - } - else - { - fileInfo = new(path); - if (fileInfo.Exists) // 路径为文件,则打开文件 - { - isDirectory = 0; - } - else if (fileInfo.DirectoryName != null) - { - directoryInfo = new(fileInfo.DirectoryName); - fileInfo = null; - if (directoryInfo.Exists) // 路径为文件但文件不存在,文件夹存在,则打开文件夹 - { - fileInfo = null; - isDirectory = 1; - } - } - } - - switch (isDirectory) - { - case 1: - if (directoryInfo != null) OpenFolderByDirectoryPath(directoryInfo); - break; - case 0: - if (fileInfo != null) OpenFolderSelectFilePath(fileInfo); - break; - } - } - - /// - /// 使用资源管理器打开文件夹路径 - /// - /// - void OpenFolderByDirectoryPath(DirectoryInfo info); - - /// - /// 使用资源管理器选中文件路径 - /// - /// - void OpenFolderSelectFilePath(FileInfo info); - - /// - /// 设置系统关闭时任务 - /// - void SetSystemSessionEnding(Action action); - - /// - /// 获取文本阅读器提供商程序文件路径或文件名(如果提供程序已注册环境变量) - /// - /// - /// - string? GetFileName(TextReaderProvider provider); - - /// - /// 设置开机自启动 - /// - /// 开启、关闭 - /// - void SetBootAutoStart(bool isAutoStart, string name); - - #region Steam - - /// - string? GetSteamDirPath(); - - /// - string? GetSteamProgramPath(); - string? GetRegistryVdfPath(); - - /// - string GetLastSteamLoginUserName(); - - /// - void SetCurrentUser(string userName); - - #endregion - - #region MachineUniqueIdentifier - - private static (byte[] key, byte[] iv) GetMachineSecretKey(string? value) - { - value ??= string.Empty; - var result = AESUtils.GetParameters(value); - return result; - } - - protected static Lazy<(byte[] key, byte[] iv)> GetMachineSecretKey(Func action) => new(() => - { - string? value = null; - try - { - value = action(); - } - catch (Exception e) - { - Log.Warn(TAG, e, "GetMachineSecretKey Fail."); - } - if (string.IsNullOrWhiteSpace(value)) - { - value = Environment.MachineName; - } - return GetMachineSecretKey(value); - }); - - (byte[] key, byte[] iv) MachineSecretKey { get; } - - #endregion - - /// - /// 是否应使用 亮色主题 / 暗色主题 - /// - bool? IsLightOrDarkTheme { get; } - - /// - /// 设置亮色或暗色主题跟随系统 - /// - /// - void SetLightOrDarkThemeFollowingSystem(bool enable); - - /// - /// 打开桌面图标设置 - /// - [SupportedOSPlatform("Windows")] - void OpenDesktopIconsSettings(); - - [SupportedOSPlatform("Windows")] - void OpenGameControllers(); - - /// - /// 已正常权限启动进程 - /// - /// - /// - [SupportedOSPlatform("Windows")] - Process StartAsInvoker(string fileName); - - /// - /// 获取占用端口的进程 - /// - /// - /// - /// - [SupportedOSPlatform("Windows")] - Process? GetProcessByPortOccupy(ushort port, bool isTCPorUDP = true); - - [SupportedOSPlatform("Windows")] - [SupportedOSPlatform("Linux")] - bool IsAdministrator { get; } - - /// - /// 从管理员权限进程中降权到普通权限启动进程 - /// - /// - [SupportedOSPlatform("Windows")] - void UnelevatedProcessStart(string cmdArgs); - - void FixFluentWindowStyleOnWin7(IntPtr hWnd) - { - } - - /// - /// 获取当前 Windows 系统产品名称,例如 Windows 10 Pro - /// - [SupportedOSPlatform("Windows")] - string WindowsProductName => ""; - - /// - /// 获取当前 Windows 系统第四位版本号 - /// - [SupportedOSPlatform("Windows")] - int WindowsVersionRevision => 0; - - /// - /// 获取当前 Windows 10/11 系统显示版本,例如 21H1 - /// - [SupportedOSPlatform("Windows")] - string WindowsReleaseIdOrDisplayVersion => ""; - - bool IPlatformService.IsMobile => false; - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/IJumpListService.cs b/src/ST.Client.Desktop/Services/IJumpListService.cs deleted file mode 100644 index a60ff4e23..000000000 --- a/src/ST.Client.Desktop/Services/IJumpListService.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace System.Application.Services -{ - public interface IJumpListService - { - void InitJumpList(); - - void AddJumpTask(string title, string applicationPath, string iconResourcePath, string arguments = "", string description = "", string customCategory = ""); - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/Implementation/PlatformApplicationUpdateServiceImpl.cs b/src/ST.Client.Desktop/Services/Implementation/PlatformApplicationUpdateServiceImpl.cs deleted file mode 100644 index 7cd1d580f..000000000 --- a/src/ST.Client.Desktop/Services/Implementation/PlatformApplicationUpdateServiceImpl.cs +++ /dev/null @@ -1,107 +0,0 @@ -using Microsoft.Extensions.Options; -using System.Application.Models; -using System.Application.Properties; -using System.Application.UI; -using System.Diagnostics; -using System.IO; -using System.Properties; -using System.Text; -using System.Threading.Tasks; -using CC = System.Common.Constants; - -namespace System.Application.Services.Implementation -{ - public abstract partial class PlatformApplicationUpdateServiceImpl : ApplicationUpdateServiceImpl - { - public PlatformApplicationUpdateServiceImpl(IToast toast, ICloudServiceClient client, IOptions options) : base(toast, client, options) - { - } - - protected override Version OSVersion => Environment.OSVersion.Version; - - /// - /// 当更新下载完毕并校验完成时,即将退出程序之前 - /// - protected abstract void OnExit(); - - protected override async void OverwriteUpgrade(string value, bool isIncrement, AppDownloadType downloadType) - { - if (isIncrement) // 增量更新 - { - OverwriteUpgradePrivate(value); - } - else // 全量更新 - { - var dirPath = Path.Combine(IOPath.BaseDirectory, Path.GetFileNameWithoutExtension(value)); - - if (Directory.Exists(dirPath)) - { - Directory.Delete(dirPath, true); - } - - var isOK = await Task.Run(() => downloadType switch - { - AppDownloadType.Compressed_GZip - => TarGZipHelper.Unpack(value, dirPath, - progress: new Progress(OnReportDecompressing), - maxProgress: CC.MaxProgress), - AppDownloadType.Compressed_7z - => SevenZipHelper.Unpack(value, dirPath, - progress: new Progress(OnReportDecompressing), - maxProgress: CC.MaxProgress), - _ => false, - }); - if (isOK) - { - OnReport(CC.MaxProgress); - IOPath.FileTryDelete(value); - OverwriteUpgradePrivate(dirPath); - } - else - { - toast.Show(SR.UpdateUnpackFail); - OnReport(CC.MaxProgress); - IsNotStartUpdateing = true; - } - } - - void OverwriteUpgradePrivate(string dirPath) - { - OnExit(); - - var updateCommandPath = Path.Combine(IOPath.CacheDirectory, "update.cmd"); - IOPath.FileIfExistsItDelete(updateCommandPath); - - var updateCommand = string.Format( - SR.ProgramUpdateCmd_, - AppHelper.ProgramName, - dirPath.TrimEnd(Path.DirectorySeparatorChar), - IOPath.BaseDirectory, - AppHelper.ProgramPath); - - updateCommand = "chcp 65001" + Environment.NewLine + updateCommand; - - File.WriteAllText(updateCommandPath, updateCommand, Encoding.Default); - - using var p = new Process(); - p.StartInfo.FileName = updateCommandPath; - p.StartInfo.UseShellExecute = false; - p.StartInfo.CreateNoWindow = !ThisAssembly.Debuggable; // 不显示程序窗口 - p.StartInfo.Verb = "runas"; // 管理员权限运行 - p.Start(); // 启动程序 - } - } - - protected override async void OpenInAppStore() - { - if (DesktopBridge.IsRunningAsUwp) - { - await Browser2.OpenAsync(UrlConstants.MicrosoftStoreProtocolLink); - } - else - { - base.OpenInAppStore(); - } - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/Implementation/PlatformApplicationUpdateServiceImpl.shared.cs b/src/ST.Client.Desktop/Services/Implementation/PlatformApplicationUpdateServiceImpl.shared.cs deleted file mode 100644 index e1c23334a..000000000 --- a/src/ST.Client.Desktop/Services/Implementation/PlatformApplicationUpdateServiceImpl.shared.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Application.Models; -using System.Application.Settings; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Linq; - -namespace System.Application.Services.Implementation -{ - partial class PlatformApplicationUpdateServiceImpl - { - protected sealed override AppVersionDTO.Download? GetByDownloadChannelSettings(IEnumerable downloads) - { - var channel = GeneralSettings.UpdateChannel.Value; - switch (channel) - { - case UpdateChannelType.GitHub: - case UpdateChannelType.Gitee: - break; - default: - channel = R.Language.StartsWith("zh") ? UpdateChannelType.Gitee : UpdateChannelType.GitHub; - break; - } - return downloads.FirstOrDefault(x => x.DownloadChannelType == channel) - ?? downloads.FirstOrDefault(); - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/Mvvm/ASFService.shared.cs b/src/ST.Client.Desktop/Services/Mvvm/ASFService.shared.cs deleted file mode 100644 index c672322d7..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/ASFService.shared.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.Services -{ - public partial class ASFService : Abstractions.ASFService - { - public ASFService() { } - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/AuthService.cs b/src/ST.Client.Desktop/Services/Mvvm/AuthService.cs deleted file mode 100644 index 650b772e4..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/AuthService.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Application.Models; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.Services -{ - partial class AuthService - { - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/AuthService.shared.cs b/src/ST.Client.Desktop/Services/Mvvm/AuthService.shared.cs deleted file mode 100644 index b3051bb2c..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/AuthService.shared.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using System.Application.Models; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using MyAuthenticatorBase = System.Application.Models.Abstractions.MyAuthenticator; - -// ReSharper disable once CheckNamespace -namespace System.Application.Services -{ - public partial class AuthService : Abstractions.AuthService - { - public AuthService() { } - - protected override MyAuthenticatorBase GetMyAuthenticator(IGAPAuthenticatorDTO dto) - => new MyAuthenticator(dto); - - protected override MyAuthenticatorBase GetMyAuthenticator() - => new MyAuthenticator(); - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/ProxyService.shared.cs b/src/ST.Client.Desktop/Services/Mvvm/ProxyService.shared.cs deleted file mode 100644 index 605f5cddc..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/ProxyService.shared.cs +++ /dev/null @@ -1,19 +0,0 @@ -using ReactiveUI; -using System; -using System.Application.Properties; -using System.Application.Settings; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.Services -{ - public partial class ProxyService : Abstractions.ProxyService - { - public ProxyService() { } - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/ToastService.cs b/src/ST.Client.Desktop/Services/Mvvm/ToastService.cs deleted file mode 100644 index 599384e4f..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/ToastService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ReactiveUI; -using System; -using System.Application.Properties; -using System.Application.Settings; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System.Application.Services -{ - partial class ToastService - { - - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/ToastService.shared.cs b/src/ST.Client.Desktop/Services/Mvvm/ToastService.shared.cs deleted file mode 100644 index 7573963be..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/ToastService.shared.cs +++ /dev/null @@ -1,22 +0,0 @@ -using ReactiveUI; -using System; -using System.Application.Properties; -using System.Application.Settings; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System.Application.Services -{ - /// - public partial class ToastService : Abstractions.ToastService - { - public ToastService() - { - - } - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/UserService.cs b/src/ST.Client.Desktop/Services/Mvvm/UserService.cs deleted file mode 100644 index 60b711cc5..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/UserService.cs +++ /dev/null @@ -1,86 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.UI.Resx; -using System.Application.UI.ViewModels; -using System.Properties; -using System.Linq; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.Services -{ - partial class UserService - { - SteamUser? _SteamUser; - public SteamUser? CurrentSteamUser - { - get => _SteamUser; - set => this.RaiseAndSetIfChanged(ref _SteamUser, value); - } - - protected override string DefaultAvaterPath => "avares://System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Assets/AppResources/avater_default.png"; - - protected override void OnSignOut() - { - CurrentSteamUser = null; - } - - public override async Task RefreshUserAvaterAsync() - { - if (User != null) - { - if (User.AvatarUrl.Any_Nullable()) - { - var settingPriority = FastLoginChannel.Steam; // 设置中优先选取头像渠道配置项 - var order = new[] { settingPriority }.Concat(new[] { - FastLoginChannel.Steam, - FastLoginChannel.QQ, - FastLoginChannel.Apple, - FastLoginChannel.Microsoft, - }.Where(x => x != settingPriority)); - foreach (var item in order) - { - if (User.AvatarUrl!.ContainsKey(item)) - { - var avatarUrl = User.AvatarUrl[item]; - if (!string.IsNullOrWhiteSpace(avatarUrl)) - { - var avatarLocalFilePath = await IHttpService.Instance.GetImageAsync(avatarUrl, ImageChannelType.SteamAvatars); - var avaterSouce = ImageSouceHelper.TryParse(avatarLocalFilePath, isCircle: true); - AvaterPath = avaterSouce ?? DefaultAvaterPath; - } - return; - } - else if (item == FastLoginChannel.Steam - && await RefreshSteamUserAvaterAsync()) - { - return; - } - } - } - else if (await RefreshSteamUserAvaterAsync()) - { - return; - } - - async Task RefreshSteamUserAvaterAsync() - { - if (User != null && User.SteamAccountId.HasValue) - { - CurrentSteamUser = await ISteamworksWebApiService.Instance.GetUserInfo(User.SteamAccountId.Value); - CurrentSteamUser.AvatarStream = IHttpService.Instance.GetImageAsync(CurrentSteamUser.AvatarFull, ImageChannelType.SteamAvatars); - var avaterSouce = ImageSouceHelper.TryParse(await CurrentSteamUser.AvatarStream, isCircle: true); - AvaterPath = avaterSouce ?? DefaultAvaterPath; - return true; - } - else - { - return false; - } - } - } - - AvaterPath = DefaultAvaterPath; - } - } -} diff --git a/src/ST.Client.Desktop/Services/Mvvm/UserService.shared.cs b/src/ST.Client.Desktop/Services/Mvvm/UserService.shared.cs deleted file mode 100644 index 7e23e254b..000000000 --- a/src/ST.Client.Desktop/Services/Mvvm/UserService.shared.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.UI.Resx; -using System.Application.UI.ViewModels; -using System.Properties; -using System.Linq; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.Services -{ - public partial class UserService : Abstractions.UserService - { - public UserService() { } - } -} diff --git a/src/ST.Client.Desktop/Settings/GeneralSettings.cs b/src/ST.Client.Desktop/Settings/GeneralSettings.cs deleted file mode 100644 index 3df141317..000000000 --- a/src/ST.Client.Desktop/Settings/GeneralSettings.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System.Application.Services; -using System.Collections.Generic; -using System.Properties; - -namespace System.Application.Settings -{ - public sealed class GeneralSettings : Abstractions.GeneralSettings - { - static GeneralSettings() - { - WindowsStartupAutoRun.ValueChanged += WindowsStartupAutoRun_ValueChanged; - //CreateDesktopShortcut.ValueChanged += CreateDesktopShortcut_ValueChanged; - } - - private static void WindowsStartupAutoRun_ValueChanged(object? sender, ValueChangedEventArgs e) - { - DI.Get().SetBootAutoStart(e.NewValue, ThisAssembly.AssemblyTrademark); - } - - public static void InitWindowsStartupAutoRun() - { - WindowsStartupAutoRun_ValueChanged(null, new(default, WindowsStartupAutoRun.Value)); - } - - /// - /// 程序是否开机自启动 - /// - public static SerializableProperty WindowsStartupAutoRun { get; } - = GetProperty(defaultValue: false, autoSave: true); - - ///// - ///// 创建桌面快捷方式 - ///// - //public static SerializableProperty CreateDesktopShortcut { get; } - // = new SerializableProperty(GetKey(), Providers.Roaming, false) { AutoSave = true }; - - /// - /// 程序启动时最小化 - /// - public static SerializableProperty IsStartupAppMinimized { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 是否显示起始页 - /// - public static SerializableProperty IsShowStartPage { get; } - = GetProperty(defaultValue: true, autoSave: true); - - /// - /// 启用游戏列表本地缓存 - /// - public static SerializableProperty IsSteamAppListLocalCache { get; } - = GetProperty(defaultValue: true, autoSave: true); - - /// - /// 启用错误日志记录 - /// - public static SerializableProperty IsEnableLogRecord { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 用户设置的文本阅读器提供商,根据平台值不同,值格式为 枚举字符串 或 程序路径 - /// - public static SerializableProperty> TextReaderProvider { get; } - = GetProperty(defaultValue: (IReadOnlyDictionary?)null, autoSave: true); - - /// - /// 使用硬件加速(仅macOS) - /// - public static SerializableProperty UseGPURendering { get; } - = GetProperty(defaultValue: true, autoSave: true); - - /// - /// Hosts 文件编码类型 - /// - public static SerializableProperty HostsEncodingType { get; } - = GetProperty(defaultValue: default(IHostsFileService.EncodingType), autoSave: true); - - ///// - ///// 使用 Direct2D1 渲染(仅 Windows) - ///// - //public static SerializableProperty UseDirect2D1 { get; } - // = GetProperty(defaultValue: false, autoSave: true); - - /// - /// Avalonia would try to use native Widows OpenGL when set to true. The default value is false.(仅 Windows) - /// - public static SerializableProperty UseOpenGL { get; } - = GetProperty(defaultValue: OperatingSystem2.IsWindows7, autoSave: true); - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Settings/ProxySettings.cs b/src/ST.Client.Desktop/Settings/ProxySettings.cs deleted file mode 100644 index cbdf1306b..000000000 --- a/src/ST.Client.Desktop/Settings/ProxySettings.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Application.Services; -using System.Collections.Generic; -using System.Net; - -namespace System.Application.Settings -{ - public sealed class ProxySettings : Abstractions.ProxySettings - { - /// - /// 启用GOG插件代理 - /// - public static SerializableProperty IsProxyGOG { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 启用系统代理模式 - /// - public static SerializableProperty EnableWindowsProxy { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 是否只针对Steam内置浏览器启用脚本 - /// - public static SerializableProperty IsOnlyWorkSteamBrowser { get; } - = GetProperty(defaultValue: false, autoSave: true); - - #region 代理设置 - - /// - /// Host代理模式端口 - /// - public static SerializableProperty HostProxyPortId { get; } - = GetProperty(defaultValue: 443, autoSave: false); - - #endregion - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/Settings/UISettings.cs b/src/ST.Client.Desktop/Settings/UISettings.cs deleted file mode 100644 index 3e5e48f05..000000000 --- a/src/ST.Client.Desktop/Settings/UISettings.cs +++ /dev/null @@ -1,110 +0,0 @@ -using DynamicData; -using System.Application.Services; -using System.Application.UI.ViewModels; -using System.Collections.Concurrent; -using System.Collections.Generic; - -namespace System.Application.Settings -{ - public sealed class UISettings : Abstractions.UISettings - { - static UISettings() - { - //Theme.ValueChanged += Theme_ValueChanged; - AppGridSize.ValueChanged += AppGridSize_ValueChanged; - EnableDesktopBackground.ValueChanged += EnableDesktopBackground_ValueChanged; - } - - private static void EnableDesktopBackground_ValueChanged(object? sender, ValueChangedEventArgs e) - { - if (OperatingSystem2.IsWindows) - { - if (e.NewValue) - { - IDesktopApplication.Instance.SetDesktopBackgroundWindow(); - } - else - { - DI.Get().ResetWallerpaper(); - } - } - } - - private static void AppGridSize_ValueChanged(object? sender, ValueChangedEventArgs e) - { - SteamConnectService.Current.SteamApps.Refresh(); - } - - //private static void Theme_ValueChanged(object sender, ValueChangedEventArgs e) - //{ - // if (e.NewValue != e.OldValue) - // { - // var value = (AppTheme)e.NewValue; - // if (value.IsDefined()) - // { - // AppHelper.Current.Theme = value; - // } - // } - //} - - /// - /// 字体 - /// - public static SerializableProperty FontName { get; } - = GetProperty(defaultValue: "Default", autoSave: true); - - /// - /// 窗口毛玻璃背景透明度 - /// - public static SerializableProperty AcrylicOpacity { get; } - = GetProperty(defaultValue: .8, autoSave: true); - - /// - /// 库存游戏封面大小 - /// - public static SerializableProperty AppGridSize { get; } - = GetProperty(defaultValue: 150, autoSave: true); - - /// - /// Steam账号备注替换名称显示 - /// - public static SerializableProperty SteamAccountRemarkReplaceName { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 启用圆角界面 - /// - public static SerializableProperty EnableFilletUI { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 启用动态桌面背景 - /// - public static SerializableProperty EnableDesktopBackground { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 启用自定义背景图片 - /// - public static SerializableProperty EnableCustomBackgroundImage { get; } - = GetProperty(defaultValue: false, autoSave: true); - - /// - /// 背景图片路径 - /// - public static SerializableProperty BackgroundImagePath { get; } - = GetProperty(defaultValue: "avares://System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Assets/AppResources/Placeholders/0.png", autoSave: true); - - /// - /// 主题颜色(十六进制字符串) - /// - public static SerializableProperty ThemeAccent { get; } - = GetProperty(defaultValue: "#FF0078D7", autoSave: true); - - /// - /// 主题颜色从系统获取 - /// - public static SerializableProperty GetUserThemeAccent { get; } - = GetProperty(defaultValue: true, autoSave: true); - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ApplicationInstance.cs b/src/ST.Client.Desktop/UI/ApplicationInstance.cs deleted file mode 100644 index 4c07a4ddd..000000000 --- a/src/ST.Client.Desktop/UI/ApplicationInstance.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.IO.Pipes; -using System.Linq; -using System.Security.Cryptography; -using System.Security.Principal; -using System.Threading; -using System.Threading.Tasks; - -namespace System.Application.UI -{ - /// - /// 支持检测应用程序的多次启动以及在正在运行的实例之间发送和接收消息 - /// - public sealed class ApplicationInstance : IDisposable - { - private bool disposedValue; - - /// - /// 获取一个值,该值指示此实例是否是第一个要启动的实例 - /// - public bool IsFirst { get; } - - /// - /// 在接收新启动的实例的消息时发生 - /// - public event Action? MessageReceived; - - public ApplicationInstance() - { - IsFirst = GetIsFirst(); - if (IsFirst) - { - Task.Run(RunPipeServer); - } - } - - static IEnumerable GetCurrentAllProcess() - { - var current = Process.GetCurrentProcess(); -#if DEBUG - if (string.Equals("dotnet", Path.GetFileNameWithoutExtension(current.MainModule?.FileName), StringComparison.OrdinalIgnoreCase)) - { - return Array.Empty(); - } -#endif - var currentMainModule = current.TryGetMainModule(); - var query = from p in Process.GetProcessesByName(current.ProcessName) - let pMainModule = p.TryGetMainModule() - where p.Id != current.Id && - p.ProcessName == current.ProcessName && - (currentMainModule == null || - (pMainModule != null && - pMainModule.FileName == currentMainModule.FileName && - pMainModule.ModuleName == currentMainModule.ModuleName)) - select p; - return query; - } - - public static bool TryKillCurrentAllProcess() - { - foreach (var p in GetCurrentAllProcess()) - { - try - { - p.Kill(true); - p.WaitForExit(500); - } - catch - { - } - } - return GetIsFirst(); - } - - static bool GetIsFirst() - { - var query = GetCurrentAllProcess(); - var r = query.Any(); - return !r; - } - - #region Pipes - - static string GetPipeName() => BuildConfig.APPLICATION_ID + "_" + Hashs.String.Crc32(AppHelper.ProgramPath); - - CancellationTokenSource? cts; - void RunPipeServer() - { - cts = new CancellationTokenSource(); - var name = GetPipeName(); - while (true) - { - using var pipeServer = new NamedPipeServerStream(name, PipeDirection.In, 1); - try - { - pipeServer.WaitForConnection(); - using var sr = new StreamReader(pipeServer); - //int i = 0; - try - { - var line = sr.ReadLine(); - //Console.WriteLine($"({i++})RunPipeServer line: {line ?? "null"}, name: {name}"); - if (line != null) - { - MessageReceived?.Invoke(line); - } - } - catch (IOException) - { - } - pipeServer.Close(); - cts.Token.ThrowIfCancellationRequested(); - } - catch (OperationCanceledException) - { - } - catch (Exception e) - { - Log.Error(nameof(ApplicationInstance), e, nameof(RunPipeServer)); - return; - } - } - } - - /// - /// 给主进程发送消息 - /// - /// - public static bool SendMessage(string value) - { - var name = GetPipeName(); - try - { - using var pipeClient = new NamedPipeClientStream(".", name, PipeDirection.Out, PipeOptions.None, TokenImpersonationLevel.Impersonation); - pipeClient.Connect(1000); - using StreamWriter sw = new StreamWriter(pipeClient); - sw.WriteLine(value); - return true; - } - catch - { - return false; - } - } - - #endregion - - private void Dispose(bool disposing) - { - if (!disposedValue) - { - if (disposing) - { - // TODO: 释放托管状态(托管对象) - cts?.Cancel(); - MessageReceived = null; - } - - // TODO: 释放未托管的资源(未托管的对象)并替代终结器 - // TODO: 将大型字段设置为 null - disposedValue = true; - } - } - - public void Dispose() - { - // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 - Dispose(disposing: true); - GC.SuppressFinalize(this); - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/Resx/R.shared.cs b/src/ST.Client.Desktop/UI/Resx/R.shared.cs deleted file mode 100644 index d85782b83..000000000 --- a/src/ST.Client.Desktop/UI/Resx/R.shared.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System.Application.UI.Resx -{ - public sealed class R : Abstractions.R - { - public R() - { - - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs deleted file mode 100644 index e1883dbed..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/MainWindowViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System.Application.UI.ViewModels -{ - public class MainWindowViewModel : Abstractions.MainWindowViewModel - { - public MainWindowViewModel() - { - - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.cs deleted file mode 100644 index 2a181c6e6..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ReactiveUI; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Linq; -using System.Properties; -using System.Reactive; -using System.Runtime.InteropServices; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class AboutPageViewModel - { - - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs deleted file mode 100644 index b75cce2cc..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs +++ /dev/null @@ -1,17 +0,0 @@ -using ReactiveUI; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Linq; -using System.Properties; -using System.Reactive; -using System.Runtime.InteropServices; -using System.Windows.Input; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class AboutPageViewModel : Abstractions.AboutPageViewModel - { - - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/ArchiSteamFarmPlusPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/ArchiSteamFarmPlusPageViewModel.shared.cs deleted file mode 100644 index fc1bc2912..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/ArchiSteamFarmPlusPageViewModel.shared.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class ArchiSteamFarmPlusPageViewModel : Abstractions.ArchiSteamFarmPlusPageViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs deleted file mode 100644 index 8ddee9ff5..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs +++ /dev/null @@ -1,41 +0,0 @@ -using DynamicData; -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Models; -using System.Application.Settings; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Properties; -using System.Reactive; -using System.Reactive.Linq; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class CommunityProxyPageViewModel - { - protected readonly IHostsFileService hostsFileService = IHostsFileService.Instance; - protected readonly IDesktopPlatformService desktopPlatformService = IDesktopPlatformService.Instance; - - public CommunityProxyPageViewModel() - { - - } - - protected override void OpenCertificateDir() - { - var fileName = $"{ThisAssembly.AssemblyProduct}.Certificate.cer"; - desktopPlatformService.OpenFolder(Path.Combine(IOPath.AppDataDirectory, fileName)); - } - - protected override void EditHostsFile() - { - hostsFileService.OpenFile(); - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/CommunityProxyPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/CommunityProxyPageViewModel.shared.cs deleted file mode 100644 index ac88a75eb..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/CommunityProxyPageViewModel.shared.cs +++ /dev/null @@ -1,24 +0,0 @@ -using DynamicData; -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Models; -using System.Application.Settings; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Properties; -using System.Reactive; -using System.Reactive.Linq; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class CommunityProxyPageViewModel : Abstractions.CommunityProxyPageViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.shared.cs deleted file mode 100644 index 6f165d34f..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.shared.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class DebugPageViewModel : Abstractions.DebugPageViewModel - { - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.shared.cs deleted file mode 100644 index 12b7a0fe4..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.shared.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class GameListPageViewModel : Abstractions.GameListPageViewModel - { - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.cs deleted file mode 100644 index 770d6e9fe..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class GameRelatedPageViewModel - { - public GameRelatedPageViewModel() - { - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.shared.cs deleted file mode 100644 index bfa4b9be5..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.shared.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class GameRelatedPageViewModel : Abstractions.GameRelatedPageViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/LocalAuthPageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/LocalAuthPageViewModel.cs deleted file mode 100644 index e4a015e14..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/LocalAuthPageViewModel.cs +++ /dev/null @@ -1,27 +0,0 @@ -using DynamicData; -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Models; -using System.Application.Repositories; -using System.Application.Security; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using System.Properties; -using System.Reactive; -using System.Reactive.Linq; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class LocalAuthPageViewModel - { - public LocalAuthPageViewModel() - { - - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/OtherPlatformPageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/OtherPlatformPageViewModel.cs deleted file mode 100644 index c5598e11f..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/OtherPlatformPageViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class OtherPlatformPageViewModel : Abstractions.OtherPlatformPageViewModel - { - public OtherPlatformPageViewModel() - { - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/OtherPlatformPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/OtherPlatformPageViewModel.shared.cs deleted file mode 100644 index 895b3e7ca..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/OtherPlatformPageViewModel.shared.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class OtherPlatformPageViewModel : Abstractions.OtherPlatformPageViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/ProxyScriptManagePageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/ProxyScriptManagePageViewModel.shared.cs deleted file mode 100644 index 6e66b963c..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/ProxyScriptManagePageViewModel.shared.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class ProxyScriptManagePageViewModel : Abstractions.ProxyScriptManagePageViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.shared.cs deleted file mode 100644 index 2be65b568..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.shared.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class SettingsPageViewModel : Abstractions.SettingsPageViewModel - { - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.cs deleted file mode 100644 index 22193cb9f..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class StartPageViewModel - { - public StartPageViewModel() - { - - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.shared.cs deleted file mode 100644 index 537b7b353..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/StartPageViewModel.shared.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class StartPageViewModel : Abstractions.StartPageViewModel - { - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.shared.cs deleted file mode 100644 index f95d16309..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.shared.cs +++ /dev/null @@ -1,22 +0,0 @@ -using DynamicData; -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Models; -using System.Application.Settings; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.Linq; -using System.Properties; -using System.Reactive; -using System.Reactive.Linq; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class SteamAccountPageViewModel : Abstractions.SteamAccountPageViewModel - { - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamIdlePageViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamIdlePageViewModel.cs deleted file mode 100644 index c2325bd57..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamIdlePageViewModel.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class SteamIdlePageViewModel - { - public SteamIdlePageViewModel() - { - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamIdlePageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamIdlePageViewModel.shared.cs deleted file mode 100644 index 711a4661e..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamIdlePageViewModel.shared.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class SteamIdlePageViewModel : Abstractions.SteamIdlePageViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs deleted file mode 100644 index 9c8e20258..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs +++ /dev/null @@ -1,32 +0,0 @@ -using ArchiSteamFarm.Steam; -using Newtonsoft.Json.Linq; -using ReactiveUI; -using System.Application.Models; -using System.Application.UI.Resx; -using System.Properties; - -namespace System.Application.UI.ViewModels -{ - public class ASF_AddBotWindowViewModel : WindowViewModel - { - public ASF_AddBotWindowViewModel() : base() - { - Title = ThisAssembly.AssemblyTrademark + " | 新增Bot"; - } - - public ASF_AddBotWindowViewModel(Bot bot) : this() - { - Title = ThisAssembly.AssemblyTrademark + " | 编辑Bot"; - _Bot = bot; - } - - private Bot? _Bot; - public Bot? Bot - { - get => _Bot; - set => this.RaiseAndSetIfChanged(ref _Bot, value); - } - - - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.shared.cs deleted file mode 100644 index 0aedc25c1..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.shared.cs +++ /dev/null @@ -1,15 +0,0 @@ -using ArchiSteamFarm.Steam; -using Newtonsoft.Json.Linq; -using ReactiveUI; -using System.Application.Models; -using System.Application.UI.Resx; -using System.Properties; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class ASF_AddBotWindowViewModel : Abstractions.ASF_AddBotWindowViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.cs deleted file mode 100644 index 6fbfbaf88..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.cs +++ /dev/null @@ -1,20 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Properties; -using System.Threading; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class BindPhoneNumberWindowViewModel - { - public BindPhoneNumberWindowViewModel() - { - - } - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.shared.cs deleted file mode 100644 index 8ae668545..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.shared.cs +++ /dev/null @@ -1,16 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Properties; -using System.Threading; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class BindPhoneNumberWindowViewModel : Abstractions.BindPhoneNumberWindowViewModel - { - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.cs deleted file mode 100644 index 6fce5a62b..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Properties; -using System.Threading; -using System.Threading.Tasks; -using static System.Application.Services.CloudService.Constants; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class ChangeBindPhoneNumberWindowViewModel - { - - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.shared.cs deleted file mode 100644 index 88d5bbacf..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.shared.cs +++ /dev/null @@ -1,18 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Properties; -using System.Threading; -using System.Threading.Tasks; -using static System.Application.Services.CloudService.Constants; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class ChangeBindPhoneNumberWindowViewModel : Abstractions.ChangeBindPhoneNumberWindowViewModel - { - - } -} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.cs deleted file mode 100644 index d8e5f31cb..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace System.Application.UI.ViewModels -{ - partial class AddAuthWindowViewModel : WindowViewModel - { - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs deleted file mode 100644 index 1e695363f..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace System.Application.UI.ViewModels -{ - partial class AuthTradeWindowViewModel - { - protected override bool IsLoadImage => true; - - protected override void RegisterSelectAllObservable() - { - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.shared.cs deleted file mode 100644 index 80932f7cd..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.shared.cs +++ /dev/null @@ -1,31 +0,0 @@ -using DynamicData; -using ReactiveUI; -using System.Application.Models; -using System.Application.Repositories; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.ObjectModel; -using System.Linq; -using System.Properties; -using System.Reactive.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using WinAuth; -using MyAuthenticator = System.Application.Models.Abstractions.MyAuthenticator; - -namespace System.Application.UI.ViewModels -{ - public partial class AuthTradeWindowViewModel : Abstractions.AuthTradeWindowViewModel - { - public AuthTradeWindowViewModel() : base() - { - - } - - public AuthTradeWindowViewModel(MyAuthenticator? auth) : base(auth) - { - - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.cs deleted file mode 100644 index adc015cd1..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace System.Application.UI.ViewModels -{ - partial class EncryptionAuthWindowViewModel : WindowViewModel - { - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.cs deleted file mode 100644 index b702f09f3..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Windows.Input; - -namespace System.Application.UI.ViewModels -{ - partial class ExportAuthWindowViewModel : WindowViewModel - { - public ICommand SelectPathButton_Click { get; } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs deleted file mode 100644 index 5798a785f..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs +++ /dev/null @@ -1,64 +0,0 @@ -//#if DEBUG -//using ReactiveUI; -//using System.Application.Services; -//using System.Application.UI.Resx; -//using System.Threading.Tasks; -//using System.Windows; -//#if __MOBILE__ -//using WindowViewModel = System.Application.UI.ViewModels.PageViewModel; -//#endif - -//namespace System.Application.UI.ViewModels -//{ -// [Obsolete("use TextBoxWindowViewModel")] -// public class PasswordWindowViewModel : WindowViewModel, ITextBoxWindowViewModel -// { -// public PasswordWindowViewModel() : base() -// { -// Title = AppResources.LocalAuth_PasswordRequired; -// } - -// private string? _Password; -// public string? Password -// { -// get => _Password; -// set => this.RaiseAndSetIfChanged(ref _Password, value); -// } - -// string? ITextBoxWindowViewModel.Value { get => Password; set => Password = value; } - -// [Obsolete("use TextBoxWindowViewModel.ShowDialogAsync(TextBoxType.LocalAuth_PasswordRequired)")] -// public static async Task ShowPasswordDialog() -// { -// return await TextBoxWindowViewModel.ShowDialogByPresetAsync(TextBoxWindowViewModel.PresetType.LocalAuth_PasswordRequired); -// } - -// public bool InputValidator() -// { -// if (string.IsNullOrWhiteSpace(Password)) -// { -// Toast.Show(AppResources.LocalAuth_ProtectionAuth_PasswordErrorTip); -// return false; -// } -// return true; -// } - -//#if !__MOBILE__ -// public void Ok() -// { -// if (!InputValidator()) -// { -// return; -// } -// this.Close(); -// } - -// public void Cancel() -// { -// Password = string.Empty; -// this.Close(); -// } -//#endif -// } -//} -//#endif \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs deleted file mode 100644 index a42592101..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Application.Models; -using System.Application.UI.Resx; -using System.Properties; - -namespace System.Application.UI.ViewModels -{ - partial class ShowAuthWindowViewModel - { - - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.shared.cs deleted file mode 100644 index c108a1340..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.shared.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Application.Models; -using System.Application.UI.Resx; -using System.Properties; -using MyAuthenticator = System.Application.Models.Abstractions.MyAuthenticator; - -namespace System.Application.UI.ViewModels -{ - public partial class ShowAuthWindowViewModel : Abstractions.ShowAuthWindowViewModel - { - public ShowAuthWindowViewModel() : base() - { - - } - - public ShowAuthWindowViewModel(MyAuthenticator? auth) : base(auth) - { - - } - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs deleted file mode 100644 index 080bb1150..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs +++ /dev/null @@ -1,22 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.Mvvm; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Drawing; -using System.Properties; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Input; -using Xamarin.Essentials; -using static System.Application.Services.CloudService.Constants; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class LoginOrRegisterWindowViewModel - { - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.shared.cs deleted file mode 100644 index a52c289c7..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.shared.cs +++ /dev/null @@ -1,23 +0,0 @@ -using ReactiveUI; -using System.Application.Models; -using System.Application.Mvvm; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.ObjectModel; -using System.Drawing; -using System.Properties; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Input; -using Xamarin.Essentials; -using static System.Application.Services.CloudService.Constants; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class LoginOrRegisterWindowViewModel : Abstractions.LoginOrRegisterWindowViewModel - { - - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/UserProfileWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/UserProfileWindowViewModel.cs deleted file mode 100644 index 1afce6eca..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/UserProfileWindowViewModel.cs +++ /dev/null @@ -1,19 +0,0 @@ -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Entities; -using System.Application.Models; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Linq; -using System.Linq.Expressions; -using System.Properties; -using System.Threading.Tasks; -using System.Windows.Input; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - partial class UserProfileWindowViewModel - { - } -} \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/UserProfileWindowViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/UserProfileWindowViewModel.shared.cs deleted file mode 100644 index c59f3df66..000000000 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/UserProfileWindowViewModel.shared.cs +++ /dev/null @@ -1,20 +0,0 @@ -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Entities; -using System.Application.Models; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Linq; -using System.Linq.Expressions; -using System.Properties; -using System.Threading.Tasks; -using System.Windows.Input; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels -{ - public partial class UserProfileWindowViewModel : Abstractions.UserProfileWindowViewModel - { - - } -} \ No newline at end of file diff --git a/src/ST.Client.Mobile.Droid.App/Properties/AndroidManifest.xml b/src/ST.Client.Mobile.Droid.App/Properties/AndroidManifest.xml index 6002b4e2e..86a7ff01e 100644 --- a/src/ST.Client.Mobile.Droid.App/Properties/AndroidManifest.xml +++ b/src/ST.Client.Mobile.Droid.App/Properties/AndroidManifest.xml @@ -1,5 +1,5 @@ - + diff --git a/src/ST.Client.Mobile.Droid.App/ST.Client.Mobile.Droid.App.csproj b/src/ST.Client.Mobile.Droid.App/ST.Client.Mobile.Droid.App.csproj index 5d750a052..9aba030fc 100644 --- a/src/ST.Client.Mobile.Droid.App/ST.Client.Mobile.Droid.App.csproj +++ b/src/ST.Client.Mobile.Droid.App/ST.Client.Mobile.Droid.App.csproj @@ -1,4 +1,4 @@ - + Debug @@ -95,14 +95,6 @@ {e7468fdd-75f7-4b08-ba47-b715bbcfcc11} Common.CoreLib - - {bd0441c0-2fa4-4f50-a3d6-12dc468193ac} - ST.Client.Mobile.Droid - - - {32C3BEF2-D9F2-470E-9814-A7D6E1E142A9} - ST.Client.Mobile - diff --git a/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj b/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj index df3ff4b28..a87f7e3f2 100644 --- a/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj +++ b/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj @@ -1,7 +1,7 @@ - MonoAndroid11.0 + net6.0-android;MonoAndroid11.0 System.Application System.Application.SteamTools.Client.Mobile.Android __HAVE_ANDROIDX__;$(DefineConstants) @@ -178,7 +178,6 @@ - diff --git a/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs b/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs index 6d4ec9927..9e2db54b8 100644 --- a/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs +++ b/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs @@ -22,13 +22,13 @@ namespace Microsoft.Extensions.DependencyInjection } /// - /// 添加适用于安卓的 + /// 添加适用于安卓的 /// /// /// public static IServiceCollection AddPlatformHttpPlatformHelper(this IServiceCollection services) { - services.AddSingleton(); + services.AddSingleton(); return services; } diff --git a/src/ST.Client.Mobile.iOS.App/Info.plist b/src/ST.Client.Mobile.iOS.App/Info.plist index c99b189ba..5957ffb6a 100644 --- a/src/ST.Client.Mobile.iOS.App/Info.plist +++ b/src/ST.Client.Mobile.iOS.App/Info.plist @@ -27,7 +27,7 @@ CFBundleIdentifier net.steampp.app CFBundleVersion - 2.5.0.0 + 2.4.14.0 UILaunchStoryboardName LaunchScreen CFBundleName @@ -35,6 +35,6 @@ XSAppIconAssets Assets.xcassets/AppIcon.appiconset CFBundleShortVersionString - 2.5.0 + 2.4.14 diff --git a/src/ST.Client.Mobile.iOS/ST.Client.Mobile.iOS.csproj b/src/ST.Client.Mobile.iOS/ST.Client.Mobile.iOS.csproj index 0cb215813..18eda5a9c 100644 --- a/src/ST.Client.Mobile.iOS/ST.Client.Mobile.iOS.csproj +++ b/src/ST.Client.Mobile.iOS/ST.Client.Mobile.iOS.csproj @@ -36,10 +36,6 @@ - - - - diff --git a/src/ST.Client.Desktop/DnsResolution.cs b/src/ST.Client/DnsResolution.cs similarity index 100% rename from src/ST.Client.Desktop/DnsResolution.cs rename to src/ST.Client/DnsResolution.cs diff --git a/src/ST.Client.Desktop/Extensions/HandleWindowExtensions.cs b/src/ST.Client/Extensions/HandleWindowExtensions.cs similarity index 100% rename from src/ST.Client.Desktop/Extensions/HandleWindowExtensions.cs rename to src/ST.Client/Extensions/HandleWindowExtensions.cs diff --git a/src/ST.Client/Extensions/ProcessExtensions.cs b/src/ST.Client/Extensions/ProcessExtensions.cs index a4d245a01..a63feb1e7 100644 --- a/src/ST.Client/Extensions/ProcessExtensions.cs +++ b/src/ST.Client/Extensions/ProcessExtensions.cs @@ -9,7 +9,7 @@ namespace System ///
public static class ProcessExtensions { - /// + /// public static string GetCommandLineArgs(this Process process) { try diff --git a/src/ST.Client.Desktop/FileSystemDesktop.cs b/src/ST.Client/FileSystemDesktop.cs similarity index 80% rename from src/ST.Client.Desktop/FileSystemDesktop.cs rename to src/ST.Client/FileSystemDesktop.cs index 9c04ef4af..a9148dca5 100644 --- a/src/ST.Client.Desktop/FileSystemDesktop.cs +++ b/src/ST.Client/FileSystemDesktop.cs @@ -40,15 +40,5 @@ namespace System.Application string GetAppDataDirectory() => appDataPath; string GetCacheDirectory() => cachePath; } - -#if DEBUG - /// - [Obsolete("use IOPath.AppDataDirectory", true)] - public static string AppDataDirectory => IOPath.AppDataDirectory; - - /// - [Obsolete("use IOPath.CacheDirectory", true)] - public static string CacheDirectory => IOPath.CacheDirectory; -#endif } } \ No newline at end of file diff --git a/src/ST.Client/ImageSouce.cs b/src/ST.Client/ImageSouce.cs index 3eb65f489..3b51352cd 100644 --- a/src/ST.Client/ImageSouce.cs +++ b/src/ST.Client/ImageSouce.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics.CodeAnalysis; +using System.Application.UI; namespace System.Application { @@ -100,5 +101,30 @@ namespace System.Application } } } + + /// + /// 将图片文件本地路径或资源路径转为图像源 + /// + /// + /// 是否为圆形 + /// 图像可配置选项 + /// + public static object? TryParse(string? filePathOrResUri, bool isCircle = false, Action? config = null) + { + if (filePathOrResUri == null) + return null; + if (IApplication.Type == IApplication.AppType.Avalonia) + { + if (filePathOrResUri.StartsWith("avares:")) + return filePathOrResUri; + } + ClipStream? clipStream = filePathOrResUri; + if (clipStream != null) + { + clipStream.Circle = isCircle; + config?.Invoke(clipStream); + } + return clipStream; + } } } diff --git a/src/ST.Client/MessageBox.cs b/src/ST.Client/MessageBox.cs index 07ccad0b4..8e24b2f3d 100644 --- a/src/ST.Client/MessageBox.cs +++ b/src/ST.Client/MessageBox.cs @@ -102,9 +102,9 @@ namespace System.Application Abort = 1000, } - const string default_caption = ThisAssembly.AssemblyTrademark; + const string default_caption = Constants.HARDCODED_APP_NAME; const Button default_button = Button.OK; - static readonly IMessageBoxService? mbcs = DI.Get_Nullable(); + static readonly IMessageBoxService? mbcs = IMessageBoxService.Instance; public const Button OKCancel = Button.OKCancel; /// diff --git a/src/ST.Client/Models/Abstractions/MyAuthenticator.cs b/src/ST.Client/Models/Abstractions/MyAuthenticator.cs deleted file mode 100644 index b18c83c7f..000000000 --- a/src/ST.Client/Models/Abstractions/MyAuthenticator.cs +++ /dev/null @@ -1,330 +0,0 @@ -using ReactiveUI; -using System.Application.Mvvm; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Application.UI.ViewModels; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Xml; -using WinAuth; -using static System.Application.Services.Abstractions.AuthService; - -namespace System.Application.Models.Abstractions -{ - public abstract class MyAuthenticator : ReactiveObject - { - protected MyAuthenticator() - { - AuthenticatorData = new GAPAuthenticatorDTO(); - OriginName = string.Empty; - } - - protected MyAuthenticator(IGAPAuthenticatorDTO data) - { - AuthenticatorData = data; - OriginName = AuthenticatorData.Name; - } - - public IGAPAuthenticatorDTO AuthenticatorData { get; set; } - - public ushort Id - { - get - { - return AuthenticatorData.Id; - } - set - { - AuthenticatorData.Id = value; - this.RaisePropertyChanged(); - } - } - - public string OriginName; - public string Name - { - get - { - return AuthenticatorData.Name; - } - set - { - AuthenticatorData.Name = value; - this.RaisePropertyChanged(); - } - } - - public int Index - { - get - { - return AuthenticatorData.Index; - } - set - { - AuthenticatorData.Index = value; - this.RaisePropertyChanged(); - } - } - - public DateTimeOffset Create - { - get - { - return AuthenticatorData.Created; - } - set - { - AuthenticatorData.Created = value; - this.RaisePropertyChanged(); - } - } - - public int Period - { - get - { - return AuthenticatorData.Value.Period; - } - set - { - AuthenticatorData.Value.Period = value; - this.RaisePropertyChanged(); - } - } - - private int _CodeCountdown; - public int CodeCountdown - { - get - { - return _CodeCountdown; - } - set - { - _CodeCountdown = value; - this.RaisePropertyChanged(); - } - } - - string _CurrentCode = string.Empty; - string? _CurrentCodeCache; - - string GetCurrentCode() - { - try - { - return AuthenticatorData.Value.CurrentCode; - } - catch - { - return string.Empty; - } - } - - public Task QrCodeStream => GetQrCodeStream(); - - public string CurrentCode - { - get - { - if (_CurrentCodeCache == null) - { - _CurrentCode = GetCurrentCode(); - return _CurrentCode; - } - else - { - var r = _CurrentCodeCache; - _CurrentCodeCache = null; - return r; - } - } - set - { - this.RaiseAndSetIfChanged(ref _CurrentCode, value); - } - } - - public string CurrentCodeCache - { - set => _CurrentCodeCache = value; - } - - public string? GetNextCode() - { - var value = GetCurrentCode(); - if (value != _CurrentCode) return value; - return null; - } - - public void RefreshCode(string? value = null) - { - value ??= GetCurrentCode(); - CurrentCodeCache = value; - CurrentCode = value; - } - - public void Sync() => AuthenticatorData.Value.Sync(); - - public bool ReadXml(XmlReader reader, string? password) - { - bool changed = false; - - //if (Guid.TryParse(reader.GetAttribute("id"), out Guid id) == true) - //{ - // Id = id; - //} - var authenticatorType = reader.GetAttribute("type"); - switch (authenticatorType) - { - case "WinAuth.SteamAuthenticator": - AuthenticatorData.Value = new GAPAuthenticatorValueDTO.SteamAuthenticator(); - break; - case "WinAuth.BattleNetAuthenticator": - AuthenticatorData.Value = new GAPAuthenticatorValueDTO.BattleNetAuthenticator(); - break; - case "WinAuth.GoogleAuthenticator": - AuthenticatorData.Value = new GAPAuthenticatorValueDTO.GoogleAuthenticator(); - break; - case "WinAuth.HOTPAuthenticator": - AuthenticatorData.Value = new GAPAuthenticatorValueDTO.HOTPAuthenticator(); - break; - case "WinAuth.MicrosoftAuthenticator": - AuthenticatorData.Value = new GAPAuthenticatorValueDTO.MicrosoftAuthenticator(); - break; - default: - return false; - } - - //string encrypted = reader.GetAttribute("encrypted"); - //if (string.IsNullOrEmpty(encrypted) == false) - //{ - // // read the encrypted text from the node - // string data = reader.ReadElementContentAsString(); - // // decrypt - // Authenticator.PasswordTypes passwordType; - // data = Authenticator.DecryptSequence(data, encrypted, password, out passwordType); - - // using (MemoryStream ms = new MemoryStream(Authenticator.StringToByteArray(data))) - // { - // reader = XmlReader.Create(ms); - // ReadXml(reader, password); - // } - // this.PasswordType = passwordType; - // this.Password = password; - - // return; - //} - - reader.MoveToContent(); - - if (reader.IsEmptyElement) - { - reader.Read(); - return changed; - } - - reader.Read(); - while (reader.EOF == false) - { - if (reader.IsStartElement()) - { - switch (reader.Name) - { - case "name": - Name = reader.ReadElementContentAsString(); - OriginName = Name; - break; - - case "created": - long t = reader.ReadElementContentAsLong(); - t += Convert.ToInt64(new TimeSpan(new DateTime(1970, 1, 1).Ticks).TotalMilliseconds); - t *= TimeSpan.TicksPerMillisecond; - Create = new DateTimeOffset(new DateTime(t).ToLocalTime()); - break; - - case "authenticatordata": - try - { - // we don't pass the password as they are locked till clicked - changed = AuthenticatorData.Value.ReadXml(reader) || changed; - } - catch (WinAuthEncryptedSecretDataException) - { - // no action needed - } - catch (WinAuthBadPasswordException) - { - // no action needed - } - break; - - // v2 - case "authenticator": - AuthenticatorData.Value = GAPAuthenticatorValueDTO.ReadXmlv2(reader, password); - break; - // v2 - case "servertimediff": - AuthenticatorData.Value.ServerTimeDiff = reader.ReadElementContentAsLong(); - break; - - default: - reader.Skip(); - break; - } - } - else - { - reader.Read(); - break; - } - } - - return changed; - } - - public Task GetQrCodeStream() => GetQrCodeStreamAsync(AuthenticatorData); - - /// - /// 编辑令牌自定义名称 - /// - /// - public async Task EditNameAsync() - { - var value = await TextBoxWindowViewModel.ShowDialogAsync(new() - { - Value = Name, - Title = AppResources.EditName, - MaxLength = IGAPAuthenticatorDTO.MaxLength_Name, - }); - if (value == null) - return; - Name = value; - await AuthService.Current.SaveEditNameByAuthenticatorAsync(this); - } - - public void CopyCodeCilp() - { - Clipboard2.SetText(CurrentCode); - Toast.Show(AppResources.LocalAuth_CopyAuthTip + Name); - } - - private bool _IsShowCode; - public bool IsShowCode - { - get - { - return _IsShowCode; - } - set - { - _IsShowCode = value; - this.RaisePropertyChanged(); - } - } - } -} diff --git a/src/ST.Client/Models/MyAuthenticator.cs b/src/ST.Client/Models/MyAuthenticator.cs index 3bb93c0ca..8d798df0d 100644 --- a/src/ST.Client/Models/MyAuthenticator.cs +++ b/src/ST.Client/Models/MyAuthenticator.cs @@ -1,13 +1,332 @@ -using System; +using ReactiveUI; +using System.Application.Mvvm; +using System.Application.Services; +using System.Application.UI.Resx; +using System.Application.UI.ViewModels; using System.Collections.Generic; +using System.IO; using System.Linq; -using System.Text; +using System.Threading; using System.Threading.Tasks; +using System.Xml; +using WinAuth; namespace System.Application.Models { - public partial class MyAuthenticator + public sealed class MyAuthenticator : ReactiveObject { + public static List Get(IEnumerable items) + => items.Select(x => new MyAuthenticator(x)).ToList(); + public MyAuthenticator() + { + AuthenticatorData = new GAPAuthenticatorDTO(); + OriginName = string.Empty; + } + + public MyAuthenticator(IGAPAuthenticatorDTO data) + { + AuthenticatorData = data; + OriginName = AuthenticatorData.Name; + } + + public IGAPAuthenticatorDTO AuthenticatorData { get; set; } + + public ushort Id + { + get + { + return AuthenticatorData.Id; + } + set + { + AuthenticatorData.Id = value; + this.RaisePropertyChanged(); + } + } + + public string OriginName; + public string Name + { + get + { + return AuthenticatorData.Name; + } + set + { + AuthenticatorData.Name = value; + this.RaisePropertyChanged(); + } + } + + public int Index + { + get + { + return AuthenticatorData.Index; + } + set + { + AuthenticatorData.Index = value; + this.RaisePropertyChanged(); + } + } + + public DateTimeOffset Create + { + get + { + return AuthenticatorData.Created; + } + set + { + AuthenticatorData.Created = value; + this.RaisePropertyChanged(); + } + } + + public int Period + { + get + { + return AuthenticatorData.Value.Period; + } + set + { + AuthenticatorData.Value.Period = value; + this.RaisePropertyChanged(); + } + } + + private int _CodeCountdown; + public int CodeCountdown + { + get + { + return _CodeCountdown; + } + set + { + _CodeCountdown = value; + this.RaisePropertyChanged(); + } + } + + string _CurrentCode = string.Empty; + string? _CurrentCodeCache; + + string GetCurrentCode() + { + try + { + return AuthenticatorData.Value.CurrentCode; + } + catch + { + return string.Empty; + } + } + + public Task QrCodeStream => GetQrCodeStream(); + + public string CurrentCode + { + get + { + if (_CurrentCodeCache == null) + { + _CurrentCode = GetCurrentCode(); + return _CurrentCode; + } + else + { + var r = _CurrentCodeCache; + _CurrentCodeCache = null; + return r; + } + } + set + { + this.RaiseAndSetIfChanged(ref _CurrentCode, value); + } + } + + public string CurrentCodeCache + { + set => _CurrentCodeCache = value; + } + + public string? GetNextCode() + { + var value = GetCurrentCode(); + if (value != _CurrentCode) return value; + return null; + } + + public void RefreshCode(string? value = null) + { + value ??= GetCurrentCode(); + CurrentCodeCache = value; + CurrentCode = value; + } + + public void Sync() => AuthenticatorData.Value.Sync(); + + public bool ReadXml(XmlReader reader, string? password) + { + bool changed = false; + + //if (Guid.TryParse(reader.GetAttribute("id"), out Guid id) == true) + //{ + // Id = id; + //} + var authenticatorType = reader.GetAttribute("type"); + switch (authenticatorType) + { + case "WinAuth.SteamAuthenticator": + AuthenticatorData.Value = new GAPAuthenticatorValueDTO.SteamAuthenticator(); + break; + case "WinAuth.BattleNetAuthenticator": + AuthenticatorData.Value = new GAPAuthenticatorValueDTO.BattleNetAuthenticator(); + break; + case "WinAuth.GoogleAuthenticator": + AuthenticatorData.Value = new GAPAuthenticatorValueDTO.GoogleAuthenticator(); + break; + case "WinAuth.HOTPAuthenticator": + AuthenticatorData.Value = new GAPAuthenticatorValueDTO.HOTPAuthenticator(); + break; + case "WinAuth.MicrosoftAuthenticator": + AuthenticatorData.Value = new GAPAuthenticatorValueDTO.MicrosoftAuthenticator(); + break; + default: + return false; + } + + //string encrypted = reader.GetAttribute("encrypted"); + //if (string.IsNullOrEmpty(encrypted) == false) + //{ + // // read the encrypted text from the node + // string data = reader.ReadElementContentAsString(); + // // decrypt + // Authenticator.PasswordTypes passwordType; + // data = Authenticator.DecryptSequence(data, encrypted, password, out passwordType); + + // using (MemoryStream ms = new MemoryStream(Authenticator.StringToByteArray(data))) + // { + // reader = XmlReader.Create(ms); + // ReadXml(reader, password); + // } + // this.PasswordType = passwordType; + // this.Password = password; + + // return; + //} + + reader.MoveToContent(); + + if (reader.IsEmptyElement) + { + reader.Read(); + return changed; + } + + reader.Read(); + while (reader.EOF == false) + { + if (reader.IsStartElement()) + { + switch (reader.Name) + { + case "name": + Name = reader.ReadElementContentAsString(); + OriginName = Name; + break; + + case "created": + long t = reader.ReadElementContentAsLong(); + t += Convert.ToInt64(new TimeSpan(new DateTime(1970, 1, 1).Ticks).TotalMilliseconds); + t *= TimeSpan.TicksPerMillisecond; + Create = new DateTimeOffset(new DateTime(t).ToLocalTime()); + break; + + case "authenticatordata": + try + { + // we don't pass the password as they are locked till clicked + changed = AuthenticatorData.Value.ReadXml(reader) || changed; + } + catch (WinAuthEncryptedSecretDataException) + { + // no action needed + } + catch (WinAuthBadPasswordException) + { + // no action needed + } + break; + + // v2 + case "authenticator": + AuthenticatorData.Value = GAPAuthenticatorValueDTO.ReadXmlv2(reader, password); + break; + // v2 + case "servertimediff": + AuthenticatorData.Value.ServerTimeDiff = reader.ReadElementContentAsLong(); + break; + + default: + reader.Skip(); + break; + } + } + else + { + reader.Read(); + break; + } + } + + return changed; + } + + public Task GetQrCodeStream() => AuthService.GetQrCodeStreamAsync(AuthenticatorData); + + /// + /// 编辑令牌自定义名称 + /// + /// + public async Task EditNameAsync() + { + var value = await TextBoxWindowViewModel.ShowDialogAsync(new() + { + Value = Name, + Title = AppResources.EditName, + MaxLength = IGAPAuthenticatorDTO.MaxLength_Name, + }); + if (value == null) + return; + Name = value; + await AuthService.Current.SaveEditNameByAuthenticatorAsync(this); + } + + public void CopyCodeCilp() + { + Clipboard2.SetText(CurrentCode); + Toast.Show(AppResources.LocalAuth_CopyAuthTip + Name); + } + + private bool _IsShowCode; + public bool IsShowCode + { + get + { + return _IsShowCode; + } + set + { + _IsShowCode = value; + this.RaisePropertyChanged(); + } + } } -} \ No newline at end of file +} diff --git a/src/ST.Client/Models/MyAuthenticator.shared.cs b/src/ST.Client/Models/MyAuthenticator.shared.cs deleted file mode 100644 index bd1fa4a53..000000000 --- a/src/ST.Client/Models/MyAuthenticator.shared.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace System.Application.Models -{ - public partial class MyAuthenticator : Abstractions.MyAuthenticator - { - public MyAuthenticator() : base() - { - - } - - public MyAuthenticator(IGAPAuthenticatorDTO data) : base(data) - { - - } - - public static List Get(IEnumerable items) - => items.Select(x => new MyAuthenticator(x)).ToList(); - } -} diff --git a/src/ST.Client/Models/SteamApp.cs b/src/ST.Client/Models/SteamApp.cs index 409c15f2a..e5732f53b 100644 --- a/src/ST.Client/Models/SteamApp.cs +++ b/src/ST.Client/Models/SteamApp.cs @@ -252,7 +252,7 @@ namespace System.Application.Models public Process? StartSteamAppProcess() { return Process = Process2.Start( - AppHelper.ProgramPath, + IApplication.ProgramPath, $"-clt app -silence -id {AppId}"); } @@ -309,7 +309,11 @@ namespace System.Application.Models { var dllPath = Path.GetDirectoryName(dll); var targetDllPath = Path.Combine(dllPath!, "nvngx_dlss.dll"); +#if NETSTANDARD + File.Move(dll, targetDllPath); +#else File.Move(dll, targetDllPath, true); +#endif } catch (Exception err) { diff --git a/src/ST.Client/Properties/SR.Designer.cs b/src/ST.Client/Properties/SR.Designer.cs index 67763714f..77bac479f 100644 --- a/src/ST.Client/Properties/SR.Designer.cs +++ b/src/ST.Client/Properties/SR.Designer.cs @@ -19,7 +19,7 @@ namespace System.Application.Properties { // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。 // 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen // (以 /str 作为命令选项),或重新生成 VS 项目。 - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class SR { @@ -123,6 +123,33 @@ namespace System.Application.Properties { } } + /// + /// 查找类似 文件属性为只读,修改失败 的本地化字符串。 + /// + internal static string FileAttributeIsReadOnlyModifyFail { + get { + return ResourceManager.GetString("FileAttributeIsReadOnlyModifyFail", resourceCulture); + } + } + + /// + /// 查找类似 文件大小过大 的本地化字符串。 + /// + internal static string FileSizeTooLarge { + get { + return ResourceManager.GetString("FileSizeTooLarge", resourceCulture); + } + } + + /// + /// 查找类似 文件访问被拒绝,没有权限 的本地化字符串。 + /// + internal static string FileUnauthorized { + get { + return ResourceManager.GetString("FileUnauthorized", resourceCulture); + } + } + /// /// 查找类似 当前已是最新版本 的本地化字符串。 /// @@ -196,6 +223,47 @@ namespace System.Application.Properties { } } + /// + /// 查找类似 操作 hosts 错误 {0} 的本地化字符串。 + /// + internal static string OperationHostsError_ { + get { + return ResourceManager.GetString("OperationHostsError_", resourceCulture); + } + } + + /// + /// 查找类似 @echo off + ///:loop + ///ping -n 1 127.0.0.1 + ///tasklist|find /i "{0}" + ///if %errorlevel%==0 ( + ///taskkill /im "{0}" /f + ///) + ///else( + ///taskkill /im "{0}" /f + ///xcopy /y /c /h /r /s "{1}\*.*" "{2}" + ///rmdir /s /q "{1}" + ///"{3}" + ///del %0 + ///) + ///goto :loop 的本地化字符串。 + /// + internal static string ProgramUpdateCmd_ { + get { + return ResourceManager.GetString("ProgramUpdateCmd_", resourceCulture); + } + } + + /// + /// 查找类似 Steam++ 替换升级中... 的本地化字符串。 + /// + internal static string ProgramUpdateEcho { + get { + return ResourceManager.GetString("ProgramUpdateEcho", resourceCulture); + } + } + /// /// 查找类似 脚本依赖下载出错:[{0}]_{1} 的本地化字符串。 /// @@ -313,6 +381,15 @@ namespace System.Application.Properties { } } + /// + /// 查找类似 找不到 Steam 安装路径 的本地化字符串。 + /// + internal static string SteamInstallPathNotFound { + get { + return ResourceManager.GetString("SteamInstallPathNotFound", resourceCulture); + } + } + /// /// 查找类似 下载更新包失败,请打开官网手动更新 的本地化字符串。 /// @@ -330,5 +407,14 @@ namespace System.Application.Properties { return ResourceManager.GetString("UpdatePackVerificationFail", resourceCulture); } } + + /// + /// 查找类似 更新包解压失败,请打开官网手动更新 的本地化字符串。 + /// + internal static string UpdateUnpackFail { + get { + return ResourceManager.GetString("UpdateUnpackFail", resourceCulture); + } + } } } diff --git a/src/ST.Client/Properties/SR.en.resx b/src/ST.Client/Properties/SR.en.resx deleted file mode 100644 index ba8836736..000000000 --- a/src/ST.Client/Properties/SR.en.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Checking ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Checking: {0}% - Comment=;Author=MicrosoftTranslator - - - Failed to create the certificate - Comment=Fail;Author=MicrosoftTranslator - - - Decompressing: {0}% - Comment=;Author=MicrosoftTranslator - - - Downloading ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Downloading: {0}% - Comment=;Author=MicrosoftTranslator - - - The download of the update package failed, please try again later - Comment=;Author=MicrosoftTranslator - - - It is currently the latest version - Comment=;Author=MicrosoftTranslator - - - The new version is updated - Comment=;Author=MicrosoftTranslator - - - The {0} version of Steam?v is updated - Comment=;Author=MicrosoftTranslator - - - Prompt notification when a new announcement is made. - Comment=;Author=MicrosoftTranslator - - - New version notifications - Comment=;Author=MicrosoftTranslator - - - Script dependency download error: {0} {1} - Comment=;Author=MicrosoftTranslator - - - Script binding error: {0} - Comment=;Author=MicrosoftTranslator - - - Cache file deletion failed: {0} - Comment=;Author=MicrosoftTranslator - - - The deletion failed - Comment=;Author=MicrosoftTranslator - - - The deletion was successful - Comment=;Author=MicrosoftTranslator - - - File deletion failed: {0} - Comment=;Author=MicrosoftTranslator - - - The script repeats - Comment=;Author=MicrosoftTranslator - - - Script: {0} file is missing and deleted - Comment=;Author=MicrosoftTranslator - - - Script: {0} file is missing, deletion fails to attempt to delete manually - Comment=;Author=MicrosoftTranslator - - - Program Exception The primary key is empty - Comment=;Author=MicrosoftTranslator - - - Script read exception Check syntax for errors: {0} - Comment=;Author=MicrosoftTranslator - - - There was an error saving the data - Comment=;Author=MicrosoftTranslator - - - The addition was successful - Comment=;Author=MicrosoftTranslator - - - Failed to download the update package, please open the official website to manually update - Comment=;Author=MicrosoftTranslator - - - The file check failed, please open the official website to manually update - Comment=;Author=MicrosoftTranslator - - - Prompt notifications when a new version is available and progress notifications when a new version is downloaded. - Comment=;Author=MicrosoftTranslator - - - Announcement notification - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/Properties/SR.es.resx b/src/ST.Client/Properties/SR.es.resx deleted file mode 100644 index 95f147edc..000000000 --- a/src/ST.Client/Properties/SR.es.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Comprobación ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Comprobación: {0}% - Comment=;Author=MicrosoftTranslator - - - No se pudo crear el certificado - Comment=Fail;Author=MicrosoftTranslator - - - Descompresión: {0}% - Comment=;Author=MicrosoftTranslator - - - Descarga ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Descarga: {0}% - Comment=;Author=MicrosoftTranslator - - - Error en la descarga del paquete de actualización, inténtelo de nuevo más tarde - Comment=;Author=MicrosoftTranslator - - - Actualmente es la última versión - Comment=;Author=MicrosoftTranslator - - - Se actualiza la nueva versión - Comment=;Author=MicrosoftTranslator - - - Se actualiza la versión de la versión de Steam-v{0} - Comment=;Author=MicrosoftTranslator - - - Notificación inmediata cuando se realiza un nuevo anuncio. - Comment=;Author=MicrosoftTranslator - - - .. \Resources\OpenSourceLibraryList.mpo; System.Byte[], mscorlib, versión = 4.0.0.0, referencia cultural = neutral, PublicKeyToken = b77a5c561934e089 - Comment=;Author=MicrosoftTranslator - - - Error de descarga de dependencia de script: {0} {1} - Comment=;Author=MicrosoftTranslator - - - Error de enlace de script: {0} - Comment=;Author=MicrosoftTranslator - - - Error al eliminar el archivo de caché: {0} - Comment=;Author=MicrosoftTranslator - - - Error al eliminar - Comment=;Author=MicrosoftTranslator - - - La eliminación se realizó correctamente - Comment=;Author=MicrosoftTranslator - - - Error al eliminar el archivo: {0} - Comment=;Author=MicrosoftTranslator - - - El script se repite - Comment=;Author=MicrosoftTranslator - - - Script: falta {0} archivo y se elimina - Comment=;Author=MicrosoftTranslator - - - Script: {0} falta el archivo, la eliminación no puede intentar eliminar manualmente - Comment=;Author=MicrosoftTranslator - - - Excepción de programa La clave principal está vacía - Comment=;Author=MicrosoftTranslator - - - Excepción de lectura de script Compruebe la sintaxis de los errores: {0} - Comment=;Author=MicrosoftTranslator - - - Se ha producido un error al guardar los datos - Comment=;Author=MicrosoftTranslator - - - La adición fue exitosa - Comment=;Author=MicrosoftTranslator - - - No se pudo descargar el paquete de actualización, abra el sitio web oficial para actualizar manualmente - Comment=;Author=MicrosoftTranslator - - - Error en la verificación de archivos, abra la actualización del manual del sitio web oficial - Comment=;Author=MicrosoftTranslator - - - Notificaciones de solicitud cuando hay una nueva versión disponible y notificaciones de progreso cuando se descarga una nueva versión. - Comment=;Author=MicrosoftTranslator - - - Notificación de anuncio - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/Properties/SR.it.resx b/src/ST.Client/Properties/SR.it.resx deleted file mode 100644 index fbb54ff37..000000000 --- a/src/ST.Client/Properties/SR.it.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Controllo ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Controllo: {0}% - Comment=;Author=MicrosoftTranslator - - - Impossibile creare il certificato - Comment=Fail;Author=MicrosoftTranslator - - - Decompressione: {0}% - Comment=;Author=MicrosoftTranslator - - - Download ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Download: {0}% - Comment=;Author=MicrosoftTranslator - - - Il download del pacchetto di aggiornamento non è riuscito, riprovare più tardi - Comment=;Author=MicrosoftTranslator - - - Attualmente è l'ultima versione - Comment=;Author=MicrosoftTranslator - - - La nuova versione viene aggiornata - Comment=;Author=MicrosoftTranslator - - - La versione di Steam-v{0} viene aggiornata - Comment=;Author=MicrosoftTranslator - - - Richiedi notifica quando viene fatto un nuovo annuncio. - Comment=;Author=MicrosoftTranslator - - - .. \Resources\OpenSourceLibraryList.mpo; System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Comment=;Author=MicrosoftTranslator - - - Errore di download della dipendenza da script: {0} {1} - Comment=;Author=MicrosoftTranslator - - - Errore di associazione script: {0} - Comment=;Author=MicrosoftTranslator - - - Eliminazione file cache non riuscita: {0} - Comment=;Author=MicrosoftTranslator - - - Eliminazione non riuscita - Comment=;Author=MicrosoftTranslator - - - L'eliminazione è stata esito positivo - Comment=;Author=MicrosoftTranslator - - - Eliminazione file non riuscita: {0} - Comment=;Author=MicrosoftTranslator - - - Lo script si ripete - Comment=;Author=MicrosoftTranslator - - - Script: {0} file mancante ed eliminato - Comment=;Author=MicrosoftTranslator - - - Script: {0} file mancante, l'eliminazione non riesce a tentare di eliminarlo manualmente - Comment=;Author=MicrosoftTranslator - - - Eccezione programma La chiave primaria è vuota - Comment=;Author=MicrosoftTranslator - - - Eccezione di lettura script Controllare la sintassi degli errori: {0} - Comment=;Author=MicrosoftTranslator - - - Si è verificato un errore durante il salvataggio dei dati - Comment=;Author=MicrosoftTranslator - - - L'aggiunta ha avuto successo - Comment=;Author=MicrosoftTranslator - - - Impossibile scaricare il pacchetto di aggiornamento, aprire il sito Web ufficiale per aggiornare manualmente - Comment=;Author=MicrosoftTranslator - - - Verifica del file non riuscita, aprire l'aggiornamento manuale ufficiale del sito Web - Comment=;Author=MicrosoftTranslator - - - Richiedi notifiche quando è disponibile una nuova versione e notifiche sullo stato di avanzamento quando viene scaricata una nuova versione. - Comment=;Author=MicrosoftTranslator - - - Notifica annuncio - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/Properties/SR.ja.resx b/src/ST.Client/Properties/SR.ja.resx deleted file mode 100644 index 362cdd2bf..000000000 --- a/src/ST.Client/Properties/SR.ja.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 検証中 ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - 検証中: {0}% - Comment=;Author=MicrosoftTranslator - - - 証明書の作成に失敗しました - Comment=Fail;Author=MicrosoftTranslator - - - 解凍中: {0}% - Comment=;Author=MicrosoftTranslator - - - ダウンロード中 ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - ダウンロード中: {0}% - Comment=;Author=MicrosoftTranslator - - - アップデートパッケージのダウンロードに失敗しました。しばらくしてからもう一度お試しください - Comment=;Author=MicrosoftTranslator - - - 現在最新バージョン - Comment=;Author=MicrosoftTranslator - - - 新しいバージョンの更新 - Comment=;Author=MicrosoftTranslator - - - Steam++ v{0}更新されました - Comment=;Author=MicrosoftTranslator - - - 新しいアナウンスがある場合のプロンプト通知。 - Comment=;Author=MicrosoftTranslator - - - 新しいバージョンの通知 - Comment=;Author=MicrosoftTranslator - - - スクリプト依存ダウンロード エラー: [{0}]_{1} - Comment=;Author=MicrosoftTranslator - - - スクリプト バインド エラー: {0} - Comment=;Author=MicrosoftTranslator - - - キャッシュ ファイルの削除に失敗しました: {0} - Comment=;Author=MicrosoftTranslator - - - 削除に失敗しました - Comment=;Author=MicrosoftTranslator - - - 削除は成功しました - Comment=;Author=MicrosoftTranslator - - - ファイルの削除に失敗しました: {0} - Comment=;Author=MicrosoftTranslator - - - スクリプトが繰り返されます - Comment=;Author=MicrosoftTranslator - - - スクリプト: {0}_ファイルが見つからない場合は削除されました - Comment=;Author=MicrosoftTranslator - - - スクリプト: {0}_ファイルが見つからない場合、削除は手動で削除しようとして失敗します - Comment=;Author=MicrosoftTranslator - - - プログラム例外 主キーが空です - Comment=;Author=MicrosoftTranslator - - - スクリプトは例外を読み取り、構文にエラーがないか確認してください{0} - Comment=;Author=MicrosoftTranslator - - - データの保存中にエラーが発生しました - Comment=;Author=MicrosoftTranslator - - - 追加は成功しました - Comment=;Author=MicrosoftTranslator - - - 更新プログラム パッケージのダウンロードに失敗しました - Comment=;Author=MicrosoftTranslator - - - ファイルの確認に失敗しました。公式ウェブサイトを開いて手動で更新してください - Comment=;Author=MicrosoftTranslator - - - 新しいバージョンが利用可能になったときのプロンプト通知と、新しいバージョンがダウンロードされたときの進行状況の通知。 - Comment=;Author=MicrosoftTranslator - - - お知らせのお知らせ - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/Properties/SR.ko.resx b/src/ST.Client/Properties/SR.ko.resx deleted file mode 100644 index ca7d8cf1c..000000000 --- a/src/ST.Client/Properties/SR.ko.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 검증 중({1}/{2}):{0}% - Comment=;Author=MicrosoftTranslator - - - 확인 중: {0}% - Comment=;Author=MicrosoftTranslator - - - 인증서를 만들지 못했습니다 - Comment=Fail;Author=MicrosoftTranslator - - - 압축 해제 중: {0}% - Comment=;Author=MicrosoftTranslator - - - 다운로드 중({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - 다운로드 중: {0}% - Comment=;Author=MicrosoftTranslator - - - 업데이트 패키지를 다운로드하지 못했습니다 - Comment=;Author=MicrosoftTranslator - - - 현재 최신 버전입니다 - Comment=;Author=MicrosoftTranslator - - - 새 버전이 업데이트됩니다 - Comment=;Author=MicrosoftTranslator - - - Steam++ v{0} 업데이트됩니다 - Comment=;Author=MicrosoftTranslator - - - 새 공지가 있을 때 알림을 표시합니다. - Comment=;Author=MicrosoftTranslator - - - 새 버전 알림입니다 - Comment=;Author=MicrosoftTranslator - - - 스크립트 종속 다운로드 오류: [{0}]_{1} - Comment=;Author=MicrosoftTranslator - - - 스크립트 바인딩 오류: {0} - Comment=;Author=MicrosoftTranslator - - - 캐시 파일 삭제 실패: {0} - Comment=;Author=MicrosoftTranslator - - - 삭제에 실패했습니다 - Comment=;Author=MicrosoftTranslator - - - 삭제에 성공했습니다 - Comment=;Author=MicrosoftTranslator - - - 파일 삭제 실패: {0} - Comment=;Author=MicrosoftTranslator - - - 스크립트가 반복됩니다 - Comment=;Author=MicrosoftTranslator - - - 스크립트: {0}_파일 손실삭제가 삭제되었습니다 - Comment=;Author=MicrosoftTranslator - - - 스크립트: {0}_파일이 누락되어 삭제가 실패하여 수동으로 삭제를 시도합니다 - Comment=;Author=MicrosoftTranslator - - - 프로그램 예외 기본 키가 비어 있습니다 - Comment=;Author=MicrosoftTranslator - - - 스크립트 읽기 예외 구문에 오류가 있는지 확인합니다{0} - Comment=;Author=MicrosoftTranslator - - - 데이터를 저장하는 데 오류가 발생했습니다 - Comment=;Author=MicrosoftTranslator - - - 추가에 성공했습니다 - Comment=;Author=MicrosoftTranslator - - - 업데이트 패키지를 다운로드하지 못했습니다 - Comment=;Author=MicrosoftTranslator - - - 파일 유효성 검사에 실패했습니다. 공식 웹 사이트를 열어 수동으로 업데이트하십시오 - Comment=;Author=MicrosoftTranslator - - - 새 버전을 사용할 수 있는 경우 프롬프트 알림 및 새 버전을 다운로드할 때의 진행률 알림입니다. - Comment=;Author=MicrosoftTranslator - - - 공지 사항 - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/Properties/SR.resx b/src/ST.Client/Properties/SR.resx index 2549c3006..ab50e8875 100644 --- a/src/ST.Client/Properties/SR.resx +++ b/src/ST.Client/Properties/SR.resx @@ -117,96 +117,26 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 正在校验({1}/{2}):{0}% - - - 正在校验:{0}% - - - 创建证书失败 - Fail - - - 正在解压:{0}% - - - 正在下载({1}/{2}):{0}% - - - 正在下载:{0}% - - - 下载更新包失败,请稍后重试 - - - 当前已是最新版本 - - - 新版本更新 - - - Steam++ v{0} 版本更新 - - - 当有新公告时的提示通知。 - - - 当有新版本可用时的提示通知与下载新版本时的进度通知。 - - - 公告通知 - - - 新版本通知 - ..\Resources\OpenSourceLibraryList.mpo;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - 脚本依赖下载出错:[{0}]_{1} - - - 脚本绑定出错:{0} - - - 缓存文件删除失败:{0} - - - 删除失败 - - - 删除成功 - - - 文件删除失败:{0} - - - 脚本重复 - - - 脚本:{0}_文件丢失已删除 - - - 脚本:{0}_文件丢失,删除失败去尝试手动删除 - - - 程序异常 主键为空 - - - 脚本读取异常请检查语法是否有错误:{0} - - - 保存数据出错请重试 - - - 添加成功 - - - 下载更新包失败,请打开官网手动更新 - - - 文件校验失败,请打开官网手动更新 + + @echo off +:loop +ping -n 1 127.0.0.1 +tasklist|find /i "{0}" +if %errorlevel%==0 ( +taskkill /im "{0}" /f +) +else( +taskkill /im "{0}" /f +xcopy /y /c /h /r /s "{1}\*.*" "{2}" +rmdir /s /q "{1}" +"{3}" +del %0 +) +goto :loop + 升级程序CMD命令行 \ No newline at end of file diff --git a/src/ST.Client/Properties/SR.ru.resx b/src/ST.Client/Properties/SR.ru.resx deleted file mode 100644 index 4ca4a4fb5..000000000 --- a/src/ST.Client/Properties/SR.ru.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Проверка ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Проверка: {0}% - Comment=;Author=MicrosoftTranslator - - - Не удалось создать сертификат - Comment=Fail;Author=MicrosoftTranslator - - - Распаковка: {0}% - Comment=;Author=MicrosoftTranslator - - - Загрузка ({1}/{2}): {0}% - Comment=;Author=MicrosoftTranslator - - - Загрузка: {0}% - Comment=;Author=MicrosoftTranslator - - - Не удалось загрузить пакет обновления, повторите попытку позже - Comment=;Author=MicrosoftTranslator - - - В настоящее время это последняя версия - Comment=;Author=MicrosoftTranslator - - - Обновление новой версии - Comment=;Author=MicrosoftTranslator - - - Обновление версии Steam++ {0} версии - Comment=;Author=MicrosoftTranslator - - - Уведомление о подсказке при появлении нового объявления. - Comment=;Author=MicrosoftTranslator - - - Уведомление о новой версии - Comment=;Author=MicrosoftTranslator - - - Сценарий зависит от ошибки загрузки: [{0}]_{1} - Comment=;Author=MicrosoftTranslator - - - Ошибка привязки скрипта: {0} - Comment=;Author=MicrosoftTranslator - - - Сбой удаления кэшированных файлов: {0} - Comment=;Author=MicrosoftTranslator - - - Не удалось удалить - Comment=;Author=MicrosoftTranslator - - - Удаление выполнено успешно - Comment=;Author=MicrosoftTranslator - - - Сбой удаления файла: {0} - Comment=;Author=MicrosoftTranslator - - - Сценарий повторяется - Comment=;Author=MicrosoftTranslator - - - Сценарий: {0} файл был удален - Comment=;Author=MicrosoftTranslator - - - Сценарий: {0} файл отсутствует, удаление завершается неудачей, чтобы попытаться удалить вручную - Comment=;Author=MicrosoftTranslator - - - Основной ключ исключения программы пуст - Comment=;Author=MicrosoftTranslator - - - Сценарий читает исключение, проверьте синтаксис на наличие ошибок: {0} - Comment=;Author=MicrosoftTranslator - - - Повторите попытку, если сохраненные данные неверна - Comment=;Author=MicrosoftTranslator - - - Добавление выполнено успешно - Comment=;Author=MicrosoftTranslator - - - Не удалось загрузить пакет обновления, откройте официальный сайт для обновления вручную - Comment=;Author=MicrosoftTranslator - - - Проверка файлов завершается неудачей, откройте официальный сайт, чтобы обновить вручную - Comment=;Author=MicrosoftTranslator - - - Уведомление о ходе выполнения при загрузке новой версии, когда доступна новая версия. - Comment=;Author=MicrosoftTranslator - - - Уведомление о объявлении - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/Properties/SR.zh-Hant.resx b/src/ST.Client/Properties/SR.zh-Hant.resx deleted file mode 100644 index 0270b2064..000000000 --- a/src/ST.Client/Properties/SR.zh-Hant.resx +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - 正在驗證({1}/{2}):{0}% - Comment=;Author=MicrosoftTranslator - - - 正在檢查:{0}% - Comment=;Author=MicrosoftTranslator - - - 建立證書失敗 - Comment=Fail;Author=MicrosoftTranslator - - - 解壓:{0}% - Comment=;Author=MicrosoftTranslator - - - 下載({1}/{2}):{0}% - Comment=;Author=MicrosoftTranslator - - - 正在下載:{0}% - Comment=;Author=MicrosoftTranslator - - - 下載更新包失敗,請稍後重試 - Comment=;Author=MicrosoftTranslator - - - 當前已是最新版本 - Comment=;Author=MicrosoftTranslator - - - 新版本更新 - Comment=;Author=MicrosoftTranslator - - - Steam++ v{0} 版本更新 - Comment=;Author=MicrosoftTranslator - - - 當有新公告時的提示通知。 - Comment=;Author=MicrosoftTranslator - - - 新版本通知 - Comment=;Author=MicrosoftTranslator - - - 腳本依賴下載出錯:[{0}]_{1} - Comment=;Author=MicrosoftTranslator - - - 文本繫結錯誤:{0} - Comment=;Author=MicrosoftTranslator - - - 快取檔案刪除失敗:{0} - Comment=;Author=MicrosoftTranslator - - - 刪除失敗 - Comment=;Author=MicrosoftTranslator - - - 刪除成功 - Comment=;Author=MicrosoftTranslator - - - 檔案刪除失敗:{0} - Comment=;Author=MicrosoftTranslator - - - 腳本重複 - Comment=;Author=MicrosoftTranslator - - - 文本:{0}_檔丟失已刪除 - Comment=;Author=MicrosoftTranslator - - - 文本:{0}_檔丟失,刪除失敗去嘗試手動刪除 - Comment=;Author=MicrosoftTranslator - - - 程序異常 主鍵為空 - Comment=;Author=MicrosoftTranslator - - - 文稿讀取異常請檢查語法是否有錯誤:{0} - Comment=;Author=MicrosoftTranslator - - - 保存數據出錯請重試 - Comment=;Author=MicrosoftTranslator - - - 添加成功 - Comment=;Author=MicrosoftTranslator - - - 下載更新包失敗,請打開官網手動更新 - Comment=;Author=MicrosoftTranslator - - - 文件校驗失敗,請打開官網手動更新 - Comment=;Author=MicrosoftTranslator - - - 當有新版本可用時的提示通知與下載新版本時的進度通知。 - Comment=;Author=MicrosoftTranslator - - - 公告通知 - Comment=;Author=MicrosoftTranslator - - diff --git a/src/ST.Client/ST.Client.csproj b/src/ST.Client/ST.Client.csproj index 4be7f03a1..1a18a5134 100644 --- a/src/ST.Client/ST.Client.csproj +++ b/src/ST.Client/ST.Client.csproj @@ -32,7 +32,6 @@ - @@ -75,11 +74,4 @@ AppResources.Designer.cs - - - - - - - \ No newline at end of file diff --git a/src/ST.Client/ServiceCollectionExtensions.cs b/src/ST.Client/ServiceCollectionExtensions.cs index a62ca9c84..c9fe962b0 100644 --- a/src/ST.Client/ServiceCollectionExtensions.cs +++ b/src/ST.Client/ServiceCollectionExtensions.cs @@ -5,6 +5,8 @@ using System.Application.Repositories; using System.Application.Repositories.Implementation; using System.Application.Services; using System.Application.Services.Implementation; +using System.Net.Http; +using System.Windows; // ReSharper disable once CheckNamespace namespace Microsoft.Extensions.DependencyInjection @@ -83,5 +85,101 @@ namespace Microsoft.Extensions.DependencyInjection services.AddSingleton(); return services; } + + /// + /// 尝试添加使用 实现的 + /// + /// + /// + public static IServiceCollection TryAddToast(this IServiceCollection services) + => ToastImpl.TryAddToast(services); + + /// + /// 添加 hosts 文件助手服务 + /// + /// + /// + public static IServiceCollection AddHostsFileService(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } + + /// + /// 添加 Steam 相关助手、工具类服务 + /// + /// + /// + public static IServiceCollection AddSteamService(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } + + /// + /// 尝试添加 Steamworks LocalApi Service + /// + /// + /// + public static IServiceCollection TryAddSteamworksLocalApiService(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } + + /// + /// 添加 SteamDb WebApi Service + /// + /// + /// + public static IServiceCollection AddSteamDbWebApiService(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } + + /// + /// 添加 Steamworks WebApi Service + /// + /// + /// + public static IServiceCollection AddSteamworksWebApiService(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } + + /// + /// 添加适用于客户端的 + /// + /// + /// + public static IServiceCollection TryAddClientHttpPlatformHelperService(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } + + /// + /// 添加 + /// + /// + /// + public static IServiceCollection AddViewModelManager(this IServiceCollection services) + { + services.AddSingleton(); + return services; + } + + /// + /// 尝试添加由 实现的 + /// + /// + /// + public static IServiceCollection TryAddNotificationService(this IServiceCollection services) + { + services.TryAddSingleton(); + return services; + } } } \ No newline at end of file diff --git a/src/ST.Client/Services/IAnnouncementService.cs b/src/ST.Client/Services/IAnnouncementService.cs index 4878d9de8..d3f2718db 100644 --- a/src/ST.Client/Services/IAnnouncementService.cs +++ b/src/ST.Client/Services/IAnnouncementService.cs @@ -5,10 +5,8 @@ namespace System.Application.Services /// /// 公告服务 /// - public interface IAnnouncementService + public interface IAnnouncementService : IService { - static IAnnouncementService Instance => DI.Get(); - /// /// 显示公告,返回是否显示 /// diff --git a/src/ST.Client/Services/IApplicationUpdateService.cs b/src/ST.Client/Services/IApplicationUpdateService.cs index b694ab3b6..bb7332f6f 100644 --- a/src/ST.Client/Services/IApplicationUpdateService.cs +++ b/src/ST.Client/Services/IApplicationUpdateService.cs @@ -9,9 +9,9 @@ namespace System.Application.Services /// /// 应用程序更新服务 /// - public interface IApplicationUpdateService + public interface IApplicationUpdateService : IService { - static IApplicationUpdateService Instance => DI.Get(); + new static IApplicationUpdateService Instance => IService.Instance; /// /// 升级包存放文件夹名称 diff --git a/src/ST.Client/Services/IArchiSteamFarmService.cs b/src/ST.Client/Services/IArchiSteamFarmService.cs index f2a24019c..1b096aa1f 100644 --- a/src/ST.Client/Services/IArchiSteamFarmService.cs +++ b/src/ST.Client/Services/IArchiSteamFarmService.cs @@ -9,9 +9,12 @@ using System.Threading.Tasks; namespace System.Application.Services { - public interface IArchiSteamFarmService + /// + /// ASF 服务 + /// + public interface IArchiSteamFarmService : IService { - static IArchiSteamFarmService Instance => DI.Get(); + new static IArchiSteamFarmService Instance => IService.Instance; static Action? InitCoreLoggers { protected get; set; } @@ -23,7 +26,7 @@ namespace System.Application.Services DateTimeOffset? StartTime { get; } - public Version CurrentVersion { get; } + Version CurrentVersion { get; } /// /// 启动ASF diff --git a/src/ST.Client/Services/IBiometricService.cs b/src/ST.Client/Services/IBiometricService.cs index 67065b0ae..b9fb52084 100644 --- a/src/ST.Client/Services/IBiometricService.cs +++ b/src/ST.Client/Services/IBiometricService.cs @@ -8,10 +8,8 @@ namespace System.Application.Services /// /// 生物识别,例如指纹,人脸,虹膜等 /// - public interface IBiometricService + public interface IBiometricService : IService { - static IBiometricService Instance => DI.Get(); - /// /// 当前设备是否支持生物识别 /// diff --git a/src/ST.Client/Services/IFontManager.cs b/src/ST.Client/Services/IFontManager.cs index 4ccc8f7f4..c95b6130f 100644 --- a/src/ST.Client/Services/IFontManager.cs +++ b/src/ST.Client/Services/IFontManager.cs @@ -5,10 +5,11 @@ using System.Text; namespace System.Application.Services { - public interface IFontManager + /// + /// 字体管理 + /// + public interface IFontManager : IService { - public static IFontManager Instance => DI.Get(); - public static KeyValuePair Default { get; } = KeyValuePair.Create(AppResources.Default, "Default"); IReadOnlyCollection> GetFonts(); diff --git a/src/ST.Client.Desktop/Services/IHostsFileService.cs b/src/ST.Client/Services/IHostsFileService.cs similarity index 83% rename from src/ST.Client.Desktop/Services/IHostsFileService.cs rename to src/ST.Client/Services/IHostsFileService.cs index ef8cfb8dd..3ac714c0c 100644 --- a/src/ST.Client.Desktop/Services/IHostsFileService.cs +++ b/src/ST.Client/Services/IHostsFileService.cs @@ -5,12 +5,10 @@ namespace System.Application.Services /// /// hosts 文件助手服务 /// - public interface IHostsFileService + public interface IHostsFileService : IService { protected const string TAG = "HostsFileS"; - public static IHostsFileService Instance => DI.Get(); - /// /// 打开 hosts 文件 /// @@ -58,21 +56,10 @@ namespace System.Application.Services /// OperationResult RemoveHostsByTag(); - private static bool mOnExitRestoreHosts; - private static readonly object mOnExitRestoreHostsLock = new(); - /// /// 当程序退出时还原 hosts 文件 /// - static void OnExitRestoreHosts() - { - lock (mOnExitRestoreHostsLock) - { - if (mOnExitRestoreHosts) return; - Instance.RemoveHostsByTag(); - mOnExitRestoreHosts = true; - } - } + void OnExitRestoreHosts(); bool ContainsHostsByTag(); diff --git a/src/ST.Client/Services/IHttpProxyService.cs b/src/ST.Client/Services/IHttpProxyService.cs index 9a2497e1a..f23b8f7ad 100644 --- a/src/ST.Client/Services/IHttpProxyService.cs +++ b/src/ST.Client/Services/IHttpProxyService.cs @@ -17,10 +17,11 @@ using Titanium.Web.Proxy.Network; namespace System.Application.Services { - public interface IHttpProxyService : IDisposable + /// + /// Http 代理服务 + /// + public interface IHttpProxyService : IService, IDisposable { - static IHttpProxyService Instance => DI.Get(); - bool IsCertificate { get; } void TrustCer(); @@ -43,6 +44,9 @@ namespace System.Application.Services bool IsSystemProxy { get; set; } + [Obsolete("use IsSystemProxy", true)] + bool IsWindowsProxy { get => IsSystemProxy; set => IsSystemProxy = value; } + bool IsProxyGOG { get; set; } bool OnlyEnableProxyScript { get; set; } diff --git a/src/ST.Client/Services/IJumpListService.cs b/src/ST.Client/Services/IJumpListService.cs new file mode 100644 index 000000000..0574fec80 --- /dev/null +++ b/src/ST.Client/Services/IJumpListService.cs @@ -0,0 +1,15 @@ +namespace System.Application.Services +{ + /// + /// 表示作为菜单显示在 Windows 7 任务栏按钮上的项和任务的列表。 + /// + /// Taskbar Extensions + /// + /// + public interface IJumpListService : IService + { + void InitJumpList(); + + void AddJumpTask(string title, string applicationPath, string iconResourcePath, string arguments = "", string description = "", string customCategory = ""); + } +} \ No newline at end of file diff --git a/src/ST.Client/Services/IMessageBoxService.cs b/src/ST.Client/Services/IMessageBoxService.cs index e996432f7..1ea128a7a 100644 --- a/src/ST.Client/Services/IMessageBoxService.cs +++ b/src/ST.Client/Services/IMessageBoxService.cs @@ -5,7 +5,10 @@ using System.Threading.Tasks; namespace System.Application.Services { - public interface IMessageBoxService + /// + /// MessageBox 自定义实现服务(可选) + /// + public interface IMessageBoxService : IOptionalService { /// /// 显示一个消息框,该消息框包含消息、标题栏标题、按钮和图标,并且返回结果 diff --git a/src/ST.Client.Desktop/Services/INativeWindowApiService.cs b/src/ST.Client/Services/INativeWindowApiService.cs similarity index 93% rename from src/ST.Client.Desktop/Services/INativeWindowApiService.cs rename to src/ST.Client/Services/INativeWindowApiService.cs index c6e1be47b..79333086d 100644 --- a/src/ST.Client.Desktop/Services/INativeWindowApiService.cs +++ b/src/ST.Client/Services/INativeWindowApiService.cs @@ -2,10 +2,11 @@ using System.Application.Models; namespace System.Application.Services { - public interface INativeWindowApiService + /// + /// 平台 Window API 服务 + /// + public interface INativeWindowApiService : IService { - static INativeWindowApiService Instance => DI.Get(); - /// /// 拖拽指针获取目标窗口 /// diff --git a/src/ST.Client/Services/INotificationService.cs b/src/ST.Client/Services/INotificationService.cs index 88ec628d7..60f9ce835 100644 --- a/src/ST.Client/Services/INotificationService.cs +++ b/src/ST.Client/Services/INotificationService.cs @@ -5,7 +5,7 @@ using static System.Application.KeyConstants; namespace System.Application.Services { - /// + /// public interface INotificationService : INotificationService { /// diff --git a/src/ST.Client/Services/IPlatformService.MacOS.cs b/src/ST.Client/Services/IPlatformService.MacOS.cs new file mode 100644 index 000000000..7235dc041 --- /dev/null +++ b/src/ST.Client/Services/IPlatformService.MacOS.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; +#if NETSTANDARD +using JustArchiNET.Madness; +#else +using System.Runtime.Versioning; +#endif + +namespace System.Application.Services +{ + partial interface IPlatformService + { + [SupportedOSPlatform("MacOS")] + string[] GetMacNetworkSetup() => throw new PlatformNotSupportedException(); + } +} diff --git a/src/ST.Client.Desktop/Services/IDesktopPlatformService.SystemBootRunArguments.cs b/src/ST.Client/Services/IPlatformService.SystemBootRunArguments.cs similarity index 90% rename from src/ST.Client.Desktop/Services/IDesktopPlatformService.SystemBootRunArguments.cs rename to src/ST.Client/Services/IPlatformService.SystemBootRunArguments.cs index 97d2b1316..9c060dd30 100644 --- a/src/ST.Client.Desktop/Services/IDesktopPlatformService.SystemBootRunArguments.cs +++ b/src/ST.Client/Services/IPlatformService.SystemBootRunArguments.cs @@ -9,7 +9,7 @@ namespace System.Application.Services #else interface #endif - IDesktopPlatformService + IPlatformService { #if NETFRAMEWORK public diff --git a/src/ST.Client.Desktop/Services/IDesktopPlatformService.UnixSetFileAccess.cs b/src/ST.Client/Services/IPlatformService.UnixSetFileAccess.cs similarity index 95% rename from src/ST.Client.Desktop/Services/IDesktopPlatformService.UnixSetFileAccess.cs rename to src/ST.Client/Services/IPlatformService.UnixSetFileAccess.cs index b4535139e..7570583bb 100644 --- a/src/ST.Client.Desktop/Services/IDesktopPlatformService.UnixSetFileAccess.cs +++ b/src/ST.Client/Services/IPlatformService.UnixSetFileAccess.cs @@ -1,10 +1,14 @@ using System.IO; using System.Runtime.InteropServices; +#if NETSTANDARD +using JustArchiNET.Madness; +#else using System.Runtime.Versioning; +#endif namespace System.Application.Services { - partial interface IDesktopPlatformService + partial interface IPlatformService { [Flags] [SupportedOSPlatform("FreeBSD")] @@ -55,7 +59,9 @@ namespace System.Application.Services return (UnixSetFileAccessResult)result; } +#if !NETSTANDARD #pragma warning disable CA2101 // False positive, we can't use unicode charset on Unix, and it uses UTF-8 by default anyway +#endif /// /// /// @@ -68,7 +74,9 @@ namespace System.Application.Services [SupportedOSPlatform("Linux")] [SupportedOSPlatform("MacOS")] private static extern int Chmod(string path, int mode); +#if !NETSTANDARD #pragma warning restore CA2101 // False positive, we can't use unicode charset on Unix, and it uses UTF-8 by default anyway +#endif [SupportedOSPlatform("FreeBSD")] [SupportedOSPlatform("Linux")] diff --git a/src/ST.Client/Services/IPlatformService.Windows.cs b/src/ST.Client/Services/IPlatformService.Windows.cs new file mode 100644 index 000000000..4bc138754 --- /dev/null +++ b/src/ST.Client/Services/IPlatformService.Windows.cs @@ -0,0 +1,66 @@ +using System.Diagnostics; +#if NETSTANDARD +using JustArchiNET.Madness; +#else +using System.Runtime.Versioning; +#endif + +namespace System.Application.Services +{ + partial interface IPlatformService + { + /// + /// 打开桌面图标设置 + /// + [SupportedOSPlatform("Windows")] + void OpenDesktopIconsSettings() => throw new PlatformNotSupportedException(); + + [SupportedOSPlatform("Windows")] + void OpenGameControllers() => throw new PlatformNotSupportedException(); + + /// + /// 已正常权限启动进程 + /// + /// + /// + [SupportedOSPlatform("Windows")] + Process StartAsInvoker(string fileName) => throw new PlatformNotSupportedException(); + + /// + /// 获取占用端口的进程 + /// + /// + /// + /// + [SupportedOSPlatform("Windows")] + Process? GetProcessByPortOccupy(ushort port, bool isTCPorUDP = true) => throw new PlatformNotSupportedException(); + + /// + /// 从管理员权限进程中降权到普通权限启动进程 + /// + /// + [SupportedOSPlatform("Windows")] + void UnelevatedProcessStart(string cmdArgs) => throw new PlatformNotSupportedException(); + + [SupportedOSPlatform("Windows")] + void FixAvaloniaFluentWindowStyleOnWin7(IntPtr hWnd) => throw new PlatformNotSupportedException(); + + /// + /// 获取当前 Windows 系统产品名称,例如 Windows 10 Pro + /// + [SupportedOSPlatform("Windows")] + string WindowsProductName => throw new PlatformNotSupportedException(); + + /// + /// 获取当前 Windows 系统第四位版本号 + /// + [SupportedOSPlatform("Windows")] + int WindowsVersionRevision => throw new PlatformNotSupportedException(); + + /// + /// 获取当前 Windows 10/11 系统显示版本,例如 21H1 + /// + [SupportedOSPlatform("Windows")] + string WindowsReleaseIdOrDisplayVersion => throw new PlatformNotSupportedException(); + } +} diff --git a/src/ST.Client/Services/IPlatformService.cs b/src/ST.Client/Services/IPlatformService.cs index 0af9c8ff9..87887e944 100644 --- a/src/ST.Client/Services/IPlatformService.cs +++ b/src/ST.Client/Services/IPlatformService.cs @@ -2,17 +2,26 @@ using System.Diagnostics; using System.Net; using System.Text; using System.Threading.Tasks; +using System.Collections.Generic; +using System.IO; +using System.Security.Cryptography; +using System.Application.Models; +using System.Application.Settings; +#if NETSTANDARD +using JustArchiNET.Madness; +#else +using System.Runtime.Versioning; +#endif namespace System.Application.Services { - public partial interface IPlatformService + /// + /// 由平台实现的服务 + /// + public partial interface IPlatformService : IService { protected const string TAG = "PlatformS"; - public static IPlatformService Instance => DI.Get(); - - string[] GetMacNetworkSetup() => throw new PlatformNotSupportedException(); - /// /// 运行 Shell 脚本 /// @@ -27,7 +36,71 @@ namespace System.Application.Services /// 使用文本阅读器打开文件 /// /// - void OpenFileByTextReader(string filePath); + void OpenFileByTextReader(string filePath) + { + TextReaderProvider? userProvider = null; + var p = GeneralSettings.TextReaderProvider.Value; + if (p != null) + { + var platform = DeviceInfo2.Platform; + if (p.ContainsKey(platform)) + { + var value = p[platform]; + if (!string.IsNullOrWhiteSpace(value)) + { + if (Enum.TryParse(value, out var enumValue)) + { + userProvider = enumValue; + } + else + { + try + { + Process2.StartPath(value, filePath); + return; + } + catch (Exception e) + { + Log.Error(TAG, e, "UserSettings OpenFileByTextReader Fail."); + } + } + } + } + } + + var providers = new List() { + TextReaderProvider.VSCode, + TextReaderProvider.Notepad }; + + if (userProvider.HasValue) + { + providers.Remove(userProvider.Value); + providers.Insert(0, userProvider.Value); + } + + foreach (var item in providers) + { + if (item == TextReaderProvider.VSCode && !OperatingSystem2.IsWindows) + { + // 其他平台的 VSCode 打开方式尚未实现 + continue; + } + try + { + var fileName = GetFileName(item); + if (fileName == null) continue; + Process2.StartPath(fileName, filePath); + return; + } + catch (Exception e) + { + if (item == TextReaderProvider.Notepad) + { + Log.Error(TAG, e, "OpenFileByTextReader Fail."); + } + } + } + } /// /// 在 Windows 上时使用 .NET Framework 中 行为。 @@ -52,17 +125,153 @@ namespace System.Application.Services /// /// 一个正在运行的进程 /// 表示应用程序运行命令行参数的字符串 - string GetCommandLineArgs(Process process); + string GetCommandLineArgs(Process process) => string.Empty; - bool IsMobile { get; } + void SetResizeMode(IntPtr hWnd, ResizeMode value) { } - ApplicationModel AppModel { get; } + /// + /// hosts 文件所在目录 + /// + string HostsFilePath => string.Format("{0}etc{0}hosts", Path.DirectorySeparatorChar); - public enum ApplicationModel + /// + /// 使用资源管理器打开某个路径 + /// + /// + void OpenFolder(string path) { - Avalonia, - Maui, - Uno, + sbyte isDirectory = -1; + FileInfo? fileInfo; + DirectoryInfo directoryInfo = new(path); + if (directoryInfo.Exists) // 路径为文件夹,则打开文件夹 + { + fileInfo = null; + isDirectory = 1; + } + else + { + fileInfo = new(path); + if (fileInfo.Exists) // 路径为文件,则打开文件 + { + isDirectory = 0; + } + else if (fileInfo.DirectoryName != null) + { + directoryInfo = new(fileInfo.DirectoryName); + fileInfo = null; + if (directoryInfo.Exists) // 路径为文件但文件不存在,文件夹存在,则打开文件夹 + { + fileInfo = null; + isDirectory = 1; + } + } + } + + switch (isDirectory) + { + case 1: + if (directoryInfo != null) OpenFolderByDirectoryPath(directoryInfo); + break; + case 0: + if (fileInfo != null) OpenFolderSelectFilePath(fileInfo); + break; + } } + + /// + /// 使用资源管理器打开文件夹路径 + /// + /// + void OpenFolderByDirectoryPath(DirectoryInfo info) => throw new PlatformNotSupportedException(); + + /// + /// 使用资源管理器选中文件路径 + /// + /// + void OpenFolderSelectFilePath(FileInfo info) => throw new PlatformNotSupportedException(); + + /// + /// 设置系统关闭时任务 + /// + void SetSystemSessionEnding(Action action) => throw new PlatformNotSupportedException(); + + /// + /// 获取文本阅读器提供商程序文件路径或文件名(如果提供程序已注册环境变量) + /// + /// + /// + string? GetFileName(TextReaderProvider provider) => throw new PlatformNotSupportedException(); + + /// + /// 设置开机自启动 + /// + /// 开启、关闭 + /// + void SetBootAutoStart(bool isAutoStart, string name) => throw new PlatformNotSupportedException(); + + #region Steam + + /// + string? GetSteamDirPath(); + + /// + string? GetSteamProgramPath(); + + string? GetRegistryVdfPath(); + + /// + string GetLastSteamLoginUserName(); + + /// + void SetCurrentUser(string userName); + + #endregion + + #region MachineUniqueIdentifier + + private static (byte[] key, byte[] iv) GetMachineSecretKey(string? value) + { + value ??= string.Empty; + var result = AESUtils.GetParameters(value); + return result; + } + + protected static Lazy<(byte[] key, byte[] iv)> GetMachineSecretKey(Func action) => new(() => + { + string? value = null; + try + { + value = action(); + } + catch (Exception e) + { + Log.Warn(TAG, e, "GetMachineSecretKey Fail."); + } + if (string.IsNullOrWhiteSpace(value)) + { + value = Environment.MachineName; + } + return GetMachineSecretKey(value); + }); + + (byte[] key, byte[] iv) MachineSecretKey { get; } + + #endregion + + /// + /// 是否应使用 亮色主题 / 暗色主题 + /// + bool? IsLightOrDarkTheme { get; } + + /// + /// 设置亮色或暗色主题跟随系统 + /// + /// + void SetLightOrDarkThemeFollowingSystem(bool enable); + + /// + /// 当前程序是否以 Administrator 或 Root 权限运行 + /// + bool IsAdministrator => false; } } \ No newline at end of file diff --git a/src/ST.Client/Services/IScriptManager.cs b/src/ST.Client/Services/IScriptManager.cs index 1d23e6126..16494c0aa 100644 --- a/src/ST.Client/Services/IScriptManager.cs +++ b/src/ST.Client/Services/IScriptManager.cs @@ -11,7 +11,7 @@ namespace System.Application.Services /// /// 脚本管理 /// - public interface IScriptManager + public interface IScriptManager : IService { /// /// 绑定JS diff --git a/src/ST.Client.Desktop/Services/ISteamDbWebApiService.cs b/src/ST.Client/Services/ISteamDbWebApiService.cs similarity index 69% rename from src/ST.Client.Desktop/Services/ISteamDbWebApiService.cs rename to src/ST.Client/Services/ISteamDbWebApiService.cs index 217ea56a1..99cc4080a 100644 --- a/src/ST.Client.Desktop/Services/ISteamDbWebApiService.cs +++ b/src/ST.Client/Services/ISteamDbWebApiService.cs @@ -4,10 +4,11 @@ using System.Threading.Tasks; namespace System.Application.Services { - public interface ISteamDbWebApiService + /// + /// SteamDb WebApi 服务 + /// + public interface ISteamDbWebApiService : IService { - public static ISteamDbWebApiService Instance => DI.Get(); - Task GetUserInfo(long steamId64); Task> GetUserInfo(IEnumerable steamId64s); diff --git a/src/ST.Client.Desktop/Services/ISteamService.cs b/src/ST.Client/Services/ISteamService.cs similarity index 77% rename from src/ST.Client.Desktop/Services/ISteamService.cs rename to src/ST.Client/Services/ISteamService.cs index ba115f8e6..60a49d728 100644 --- a/src/ST.Client.Desktop/Services/ISteamService.cs +++ b/src/ST.Client/Services/ISteamService.cs @@ -8,19 +8,17 @@ namespace System.Application.Services /// /// Steam 相关助手、工具类服务 /// - public interface ISteamService + public interface ISteamService : IService { - public const int IPC_Call_GetLoginUsingSteamClient_Timeout_MS = 6500; + const int IPC_Call_GetLoginUsingSteamClient_Timeout_MS = 6500; protected const string url_localhost_auth_public = Prefix_HTTP + "127.0.0.1:27060/auth/?u=public"; - public const string url_steamcommunity_ = "steamcommunity.com"; - public const string url_store_steampowered_ = "store.steampowered.com"; - public const string url_steamcommunity = Prefix_HTTPS + url_steamcommunity_; - public const string url_store_steampowered = Prefix_HTTPS + url_store_steampowered_; - public const string url_store_steampowered_checkclientautologin = url_store_steampowered + "/login/checkclientautologin"; - public const string url_steamcommunity_checkclientautologin = url_steamcommunity + "/login/checkclientautologin"; - public static readonly Uri uri_store_steampowered_checkclientautologin = new(url_store_steampowered_checkclientautologin); - - public static ISteamService Instance => DI.Get(); + const string url_steamcommunity_ = "steamcommunity.com"; + const string url_store_steampowered_ = "store.steampowered.com"; + const string url_steamcommunity = Prefix_HTTPS + url_steamcommunity_; + const string url_store_steampowered = Prefix_HTTPS + url_store_steampowered_; + const string url_store_steampowered_checkclientautologin = url_store_steampowered + "/login/checkclientautologin"; + const string url_steamcommunity_checkclientautologin = url_steamcommunity + "/login/checkclientautologin"; + static readonly Uri uri_store_steampowered_checkclientautologin = new(url_store_steampowered_checkclientautologin); /// /// Steam 文件夹目录 diff --git a/src/ST.Client.Desktop/Services/ISteamworksLocalApiService.cs b/src/ST.Client/Services/ISteamworksLocalApiService.cs similarity index 89% rename from src/ST.Client.Desktop/Services/ISteamworksLocalApiService.cs rename to src/ST.Client/Services/ISteamworksLocalApiService.cs index 9d61034a8..8695002c2 100644 --- a/src/ST.Client.Desktop/Services/ISteamworksLocalApiService.cs +++ b/src/ST.Client/Services/ISteamworksLocalApiService.cs @@ -3,12 +3,13 @@ using System.Collections.Generic; namespace System.Application.Services { - public interface ISteamworksLocalApiService + /// + /// Steamworks 本地 API 服务 + /// + public interface ISteamworksLocalApiService : IService { protected const string TAG = "SteamworksLocalApiS"; - public static ISteamworksLocalApiService Instance => DI.Get(); - /// /// 当前平台是否支持 /// @@ -68,7 +69,7 @@ namespace System.Application.Services void RunCallbacks(bool server); - public interface IUserStatsReceived + interface IUserStatsReceived { ulong GameId { get; } diff --git a/src/ST.Client.Desktop/Services/ISteamworksWebApiService.cs b/src/ST.Client/Services/ISteamworksWebApiService.cs similarity index 64% rename from src/ST.Client.Desktop/Services/ISteamworksWebApiService.cs rename to src/ST.Client/Services/ISteamworksWebApiService.cs index 128930918..44f5df545 100644 --- a/src/ST.Client.Desktop/Services/ISteamworksWebApiService.cs +++ b/src/ST.Client/Services/ISteamworksWebApiService.cs @@ -1,13 +1,14 @@ -using System.Application.Models; +using System.Application.Models; using System.Collections.Generic; using System.Threading.Tasks; namespace System.Application.Services { - public interface ISteamworksWebApiService + /// + /// Steamworks Web API 服务 + /// + public interface ISteamworksWebApiService : IService { - public static ISteamworksWebApiService Instance => DI.Get(); - Task GetAllSteamAppsString(); Task> GetAllSteamAppList(); diff --git a/src/ST.Client/Services/IUserManager.cs b/src/ST.Client/Services/IUserManager.cs index ef943e74e..dad9a99b6 100644 --- a/src/ST.Client/Services/IUserManager.cs +++ b/src/ST.Client/Services/IUserManager.cs @@ -6,10 +6,8 @@ namespace System.Application.Services /// /// 用户管理 /// - public interface IUserManager : IAuthHelper + public interface IUserManager : IService, IAuthHelper { - public static IUserManager Instance => DI.Get(); - /// CurrentUser? GetCurrentUser(); diff --git a/src/ST.Client.Desktop/Services/IDesktopWindowViewModelManager.cs b/src/ST.Client/Services/IViewModelManager.cs similarity index 82% rename from src/ST.Client.Desktop/Services/IDesktopWindowViewModelManager.cs rename to src/ST.Client/Services/IViewModelManager.cs index e3840f41e..74c413879 100644 --- a/src/ST.Client.Desktop/Services/IDesktopWindowViewModelManager.cs +++ b/src/ST.Client/Services/IViewModelManager.cs @@ -10,10 +10,8 @@ using System.Threading.Tasks; namespace System.Application.Services { - public interface IDesktopWindowViewModelManager : IDisposableHolder + public interface IViewModelManager : IService, IDisposableHolder, IDisposable { - static IDesktopWindowViewModelManager Instance => DI.Get(); - /// /// 获取为当前主窗口提供的数据 /// diff --git a/src/ST.Client/Services/IWindowManager.cs b/src/ST.Client/Services/IWindowManager.cs index 97570eea6..0466ee5a2 100644 --- a/src/ST.Client/Services/IWindowManager.cs +++ b/src/ST.Client/Services/IWindowManager.cs @@ -3,16 +3,15 @@ using System.Collections.Generic; using System.Text; using System.Threading.Tasks; using System.Application.UI.ViewModels; +using System.Reflection; namespace System.Application.Services { /// - /// 窗口服务 + /// 窗口管理 /// - public interface IWindowManager + public interface IWindowManager : IService { - static IWindowManager Instance => DI.Get(); - /// /// 显示一个窗口 /// @@ -30,12 +29,12 @@ namespace System.Application.Services ResizeMode resizeMode = ResizeMode.NoResize, bool isDialog = false, bool isParent = true) - where TWindowViewModel : PageViewModel, new(); + where TWindowViewModel : WindowViewModel, new(); /// Task Show(Type typeWindowViewModel, CustomWindow customWindow, - PageViewModel? viewModel = null, + WindowViewModel? viewModel = null, string title = "", ResizeMode resizeMode = ResizeMode.NoResize, bool isDialog = false, @@ -43,7 +42,7 @@ namespace System.Application.Services /// Task Show(CustomWindow customWindow, - PageViewModel? viewModel = null, + WindowViewModel? viewModel = null, string title = "", ResizeMode resizeMode = ResizeMode.NoResize, bool isDialog = false, @@ -66,19 +65,19 @@ namespace System.Application.Services ResizeMode resizeMode = ResizeMode.NoResize, bool isDialog = true, bool isParent = true) - where TWindowViewModel : PageViewModel, new(); + where TWindowViewModel : WindowViewModel, new(); /// Task ShowDialog(Type typeWindowViewModel, CustomWindow customWindow, - PageViewModel? viewModel = null, + WindowViewModel? viewModel = null, string title = "", ResizeMode resizeMode = ResizeMode.NoResize, bool isDialog = true); /// Task ShowDialog(CustomWindow customWindow, - PageViewModel? viewModel = null, + WindowViewModel? viewModel = null, string title = "", ResizeMode resizeMode = ResizeMode.NoResize, bool isDialog = true); @@ -87,7 +86,7 @@ namespace System.Application.Services /// 根据视图模型关闭窗口 /// /// - void CloseWindow(PageViewModel vm) + void CloseWindow(WindowViewModel vm) { } @@ -97,7 +96,7 @@ namespace System.Application.Services /// /// /// - bool IsVisibleWindow(PageViewModel vm) + bool IsVisibleWindow(WindowViewModel vm) { return default; } @@ -106,7 +105,7 @@ namespace System.Application.Services /// 根据视图模型隐藏窗口 /// /// - void HideWindow(PageViewModel vm) + void HideWindow(WindowViewModel vm) { } @@ -114,9 +113,60 @@ namespace System.Application.Services /// 根据视图模型显示窗口 /// /// - void ShowWindow(PageViewModel vm) + void ShowWindow(WindowViewModel vm) { } } + + /// + public interface IWindowManagerImpl : IWindowManager + { + Type WindowType { get; } + + Type GetWindowType(CustomWindow customWindow, params Assembly[]? assemblies) + { + IEnumerable? assemblies_ = assemblies; + return GetWindowType(customWindow, assemblies_); + } + + Type GetWindowType(CustomWindow customWindow, IEnumerable? assemblies) + { + var typeName = $"System.Application.UI.Views.Windows.{customWindow}Window"; + const string errMsg = "GetWindowType fail."; + return GetType(typeName, WindowType, errMsg, customWindow, assemblies); + } + + Type GetWindowViewModelType(CustomWindow customWindow, params Assembly[]? assemblies) + { + IEnumerable? assemblies_ = assemblies; + return GetWindowViewModelType(customWindow, assemblies_); + } + + Type GetWindowViewModelType(CustomWindow customWindow, IEnumerable? assemblies) + { + var typeName = $"System.Application.UI.ViewModels.{customWindow}WindowViewModel"; + const string errMsg = "GetWindowViewModelType fail."; + return GetType(typeName, typeof(WindowViewModel), errMsg, customWindow, assemblies); + } + + private Type GetType(string typeName, Type baseType, string errMsg, CustomWindow customWindow, IEnumerable? assemblies) + { + Type? type = null; + if (assemblies.Any_Nullable()) + { + foreach (var item in assemblies!) + { + type = item.GetType(typeName); + if (type != null) break; + } + } + else + { + type = Type.GetType(typeName); + } + if (type != null && baseType.IsAssignableFrom(type)) return type; + throw new ArgumentOutOfRangeException(nameof(customWindow), customWindow, errMsg); + } + } } diff --git a/src/ST.Client/Services/Implementation/ApplicationUpdateServiceImpl.cs b/src/ST.Client/Services/Implementation/ApplicationUpdateServiceImpl.cs index c01c4fbbe..e9c92cd08 100644 --- a/src/ST.Client/Services/Implementation/ApplicationUpdateServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/ApplicationUpdateServiceImpl.cs @@ -2,11 +2,17 @@ using Microsoft.Extensions.Options; using ReactiveUI; using System.Application.Models; using System.Application.Properties; +using System.Application.Settings; +using System.Application.UI; +using System.Application.UI.Resx; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Properties; using System.Runtime.InteropServices; using System.Security.Cryptography; +using System.Text; using System.Threading.Tasks; using System.Windows.Input; using static System.Application.Browser2; @@ -43,7 +49,14 @@ namespace System.Application.Services.Implementation protected ArchitectureFlags SupportedAbis { get; } - protected abstract Version OSVersion { get; } + protected virtual Version OSVersion => Environment.OSVersion.Version; + + /// + /// 当更新下载完毕并校验完成时,即将退出程序之前 + /// + protected virtual void OnExit() + { + } public virtual bool IsSupportedServerDistribution { @@ -536,12 +549,88 @@ namespace System.Application.Services.Implementation /// /// /// - protected abstract void OverwriteUpgrade(string value, bool isIncrement, AppDownloadType downloadType = default); + protected virtual async void OverwriteUpgrade(string value, bool isIncrement, AppDownloadType downloadType = default) + { + if (isIncrement) // 增量更新 + { + OverwriteUpgradePrivate(value); + } + else // 全量更新 + { + var dirPath = Path.Combine(IOPath.BaseDirectory, Path.GetFileNameWithoutExtension(value)); + + if (Directory.Exists(dirPath)) + { + Directory.Delete(dirPath, true); + } + + var isOK = await Task.Run(() => downloadType switch + { + AppDownloadType.Compressed_GZip + => TarGZipHelper.Unpack(value, dirPath, + progress: new Progress(OnReportDecompressing), + maxProgress: CC.MaxProgress), + AppDownloadType.Compressed_7z + => SevenZipHelper.Unpack(value, dirPath, + progress: new Progress(OnReportDecompressing), + maxProgress: CC.MaxProgress), + _ => false, + }); + if (isOK) + { + OnReport(CC.MaxProgress); + IOPath.FileTryDelete(value); + OverwriteUpgradePrivate(dirPath); + } + else + { + toast.Show(SR.UpdateUnpackFail); + OnReport(CC.MaxProgress); + IsNotStartUpdateing = true; + } + } + + void OverwriteUpgradePrivate(string dirPath) + { + OnExit(); + + var updateCommandPath = Path.Combine(IOPath.CacheDirectory, "update.cmd"); + IOPath.FileIfExistsItDelete(updateCommandPath); + + var updateCommand = string.Format( + SR.ProgramUpdateCmd_, + IApplication.ProgramName, + dirPath.TrimEnd(Path.DirectorySeparatorChar), + IOPath.BaseDirectory, + IApplication.ProgramPath); + + updateCommand = "chcp 65001" + Environment.NewLine + updateCommand; + + File.WriteAllText(updateCommandPath, updateCommand, Encoding.Default); + + using var p = new Process(); + p.StartInfo.FileName = updateCommandPath; + p.StartInfo.UseShellExecute = false; + p.StartInfo.CreateNoWindow = !ThisAssembly.Debuggable; // 不显示程序窗口 + p.StartInfo.Verb = "runas"; // 管理员权限运行 + p.Start(); // 启动程序 + } + } /// /// 在应用商店中打开 /// - protected virtual async void OpenInAppStore() => await OpenAsync(UrlConstants.OfficialWebsite); + protected virtual async void OpenInAppStore() + { + if (DesktopBridge.IsRunningAsUwp) + { + await OpenAsync(UrlConstants.MicrosoftStoreProtocolLink); + } + else + { + await OpenAsync(UrlConstants.OfficialWebsite); + } + } void StartUpdate() { @@ -558,6 +647,20 @@ namespace System.Application.Services.Implementation } } - protected abstract AppVersionDTO.Download? GetByDownloadChannelSettings(IEnumerable downloads); + protected virtual AppVersionDTO.Download? GetByDownloadChannelSettings(IEnumerable downloads) + { + var channel = GeneralSettings.UpdateChannel.Value; + switch (channel) + { + case UpdateChannelType.GitHub: + case UpdateChannelType.Gitee: + break; + default: + channel = R.Language.StartsWith("zh") ? UpdateChannelType.Gitee : UpdateChannelType.GitHub; + break; + } + return downloads.FirstOrDefault(x => x.DownloadChannelType == channel) + ?? downloads.FirstOrDefault(); + } } -} \ No newline at end of file +} diff --git a/src/ST.Client/Services/Implementation/ArchiSteamFarmServiceImpl.cs b/src/ST.Client/Services/Implementation/ArchiSteamFarmServiceImpl.cs index 051f17b03..859e05392 100644 --- a/src/ST.Client/Services/Implementation/ArchiSteamFarmServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/ArchiSteamFarmServiceImpl.cs @@ -57,12 +57,12 @@ namespace System.Application.Services.Implementation return result; }; - await ArchiSteamFarm.Program.Init(args).ConfigureAwait(false); + await Program.Init(args).ConfigureAwait(false); isFirstStart = false; } else { - if (!await ArchiSteamFarm.Program.InitASF().ConfigureAwait(false)) + if (!await Program.InitASF().ConfigureAwait(false)) { await Stop().ConfigureAwait(false); } @@ -78,8 +78,8 @@ namespace System.Application.Services.Implementation public async Task Stop() { - IArchiSteamFarmService.Instance.ReadLineTask?.TrySetResult(""); - await ArchiSteamFarm.Program.InitShutdownSequence(); + ReadLineTask?.TrySetResult(""); + await Program.InitShutdownSequence(); StartTime = null; } @@ -87,7 +87,7 @@ namespace System.Application.Services.Implementation { ArchiSteamFarm.NLog.Logging.InitHistoryLogger(); - HistoryTarget? historyTarget = ArchiSteamFarm.LogManager.Configuration.AllTargets.OfType().FirstOrDefault(); + HistoryTarget? historyTarget = LogManager.Configuration.AllTargets.OfType().FirstOrDefault(); if (historyTarget != null) historyTarget.NewHistoryEntry += (object? sender, HistoryTarget.NewHistoryEntryArgs newHistoryEntryArgs) => @@ -114,7 +114,7 @@ namespace System.Application.Services.Implementation ASF.ArchiLogger.LogGenericInfo(Strings.Executing); - ulong steamOwnerID = ASF.GlobalConfig?.SteamOwnerID ?? ArchiSteamFarm.Storage.GlobalConfig.DefaultSteamOwnerID; + ulong steamOwnerID = ASF.GlobalConfig?.SteamOwnerID ?? GlobalConfig.DefaultSteamOwnerID; string? response = await targetBot.Commands.Response(steamOwnerID, command!); diff --git a/src/ST.Client.Desktop/Services/Implementation/DesktopHttpPlatformHelper.cs b/src/ST.Client/Services/Implementation/ClientHttpPlatformHelperServiceImpl.cs similarity index 81% rename from src/ST.Client.Desktop/Services/Implementation/DesktopHttpPlatformHelper.cs rename to src/ST.Client/Services/Implementation/ClientHttpPlatformHelperServiceImpl.cs index 323c79714..cfa839748 100644 --- a/src/ST.Client.Desktop/Services/Implementation/DesktopHttpPlatformHelper.cs +++ b/src/ST.Client/Services/Implementation/ClientHttpPlatformHelperServiceImpl.cs @@ -3,7 +3,7 @@ using System.Net.Http; namespace System.Application.Services.Implementation { - public class DesktopHttpPlatformHelper : HttpPlatformHelper + public class ClientHttpPlatformHelperServiceImpl : ClientHttpPlatformHelperService { protected const string ChromiumVersion = "90.0.4430.93"; protected const string AppleWebKitCompatVersion = "537.36"; diff --git a/src/ST.Client/Services/Implementation/CloudServiceClient.cs b/src/ST.Client/Services/Implementation/CloudServiceClient.cs index 449fe8d55..19e0ed01c 100644 --- a/src/ST.Client/Services/Implementation/CloudServiceClient.cs +++ b/src/ST.Client/Services/Implementation/CloudServiceClient.cs @@ -15,7 +15,7 @@ namespace System.Application.Services.Implementation public CloudServiceClient( ILoggerFactory loggerFactory, IHttpClientFactory clientFactory, - IHttpPlatformHelper httpPlatformHelper, + IHttpPlatformHelperService httpPlatformHelper, IUserManager userManager, IToast toast, IOptions options, diff --git a/src/ST.Client.Desktop/Services/Implementation/HostsFileServiceImpl.cs b/src/ST.Client/Services/Implementation/HostsFileServiceImpl.cs similarity index 98% rename from src/ST.Client.Desktop/Services/Implementation/HostsFileServiceImpl.cs rename to src/ST.Client/Services/Implementation/HostsFileServiceImpl.cs index ed3efc5e2..7f58dc0d6 100644 --- a/src/ST.Client.Desktop/Services/Implementation/HostsFileServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/HostsFileServiceImpl.cs @@ -14,10 +14,10 @@ namespace System.Application.Services.Implementation { internal sealed class HostsFileServiceImpl : IHostsFileService { - readonly IDesktopPlatformService s; + readonly IPlatformService s; readonly object lockObj = new(); - public HostsFileServiceImpl(IDesktopPlatformService s) + public HostsFileServiceImpl(IPlatformService s) { this.s = s; } @@ -631,5 +631,17 @@ namespace System.Application.Services.Implementation } return false; } + + bool mOnExitRestoreHosts; + readonly object mOnExitRestoreHostsLock = new(); + public void OnExitRestoreHosts() + { + lock (mOnExitRestoreHostsLock) + { + if (mOnExitRestoreHosts) return; + RemoveHostsByTag(); + mOnExitRestoreHosts = true; + } + } } } \ No newline at end of file diff --git a/src/ST.Client/Services/Implementation/HttpProxyServiceImpl.cs b/src/ST.Client/Services/Implementation/HttpProxyServiceImpl.cs index ef4a0c696..907c98444 100644 --- a/src/ST.Client/Services/Implementation/HttpProxyServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/HttpProxyServiceImpl.cs @@ -242,6 +242,7 @@ namespace System.Application.Services.Implementation //e.HttpClient.Request.Host = item.ForwardDomainName ?? e.HttpClient.Request.Host; if (e.HttpClient.ConnectRequest?.ClientHelloInfo?.Extensions != null) { + //Logger.Info("ClientHelloInfo Info: " + e.HttpClient.ConnectRequest.ClientHelloInfo); #if DEBUG Debug.WriteLine("ClientHelloInfo Info: " + e.HttpClient.ConnectRequest.ClientHelloInfo); #endif diff --git a/src/ST.Client/Services/Implementation/HttpServiceImpl.cs b/src/ST.Client/Services/Implementation/HttpServiceImpl.cs index 09c29863a..b812fb27f 100644 --- a/src/ST.Client/Services/Implementation/HttpServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/HttpServiceImpl.cs @@ -27,11 +27,11 @@ namespace System.Application.Services.Implementation IHttpClientFactory IHttpService.Factory => _clientFactory; - IHttpPlatformHelper IHttpService.PlatformHelper => http_helper; + IHttpPlatformHelperService IHttpService.PlatformHelper => http_helper; public HttpServiceImpl( ILoggerFactory loggerFactory, - IHttpPlatformHelper http_helper, + IHttpPlatformHelperService http_helper, IHttpClientFactory clientFactory) : base(loggerFactory.CreateLogger(TAG), http_helper, clientFactory) { diff --git a/src/ST.Client.Desktop/Services/Implementation/LocalDataProtectionProvider.cs b/src/ST.Client/Services/Implementation/LocalDataProtectionProvider.cs similarity index 69% rename from src/ST.Client.Desktop/Services/Implementation/LocalDataProtectionProvider.cs rename to src/ST.Client/Services/Implementation/LocalDataProtectionProvider.cs index 68c89afcb..cc041fa22 100644 --- a/src/ST.Client.Desktop/Services/Implementation/LocalDataProtectionProvider.cs +++ b/src/ST.Client/Services/Implementation/LocalDataProtectionProvider.cs @@ -1,16 +1,16 @@ -using static System.Application.Services.ILocalDataProtectionProvider; +using static System.Application.Services.ILocalDataProtectionProvider; namespace System.Application.Services.Implementation { /// public class LocalDataProtectionProvider : LocalDataProtectionProviderBase { - readonly IDesktopPlatformService platformService; + readonly IPlatformService platformService; public LocalDataProtectionProvider( IProtectedData protectedData, IDataProtectionProvider dataProtectionProvider, - IDesktopPlatformService platformService) : base(protectedData, dataProtectionProvider) + IPlatformService platformService) : base(protectedData, dataProtectionProvider) { this.platformService = platformService; } diff --git a/src/ST.Client.Desktop/Services/Implementation/PlatformNotificationServiceImpl.cs b/src/ST.Client/Services/Implementation/NotificationServiceImpl.cs similarity index 86% rename from src/ST.Client.Desktop/Services/Implementation/PlatformNotificationServiceImpl.cs rename to src/ST.Client/Services/Implementation/NotificationServiceImpl.cs index 4269dd50f..7d972930b 100644 --- a/src/ST.Client.Desktop/Services/Implementation/PlatformNotificationServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/NotificationServiceImpl.cs @@ -1,14 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Text; using System.Properties; using System.Windows; namespace System.Application.Services.Implementation { - /// - internal sealed class PlatformNotificationServiceImpl : INotificationService + /// + internal sealed class NotificationServiceImpl : INotificationService { readonly NotifyIcon notifyIcon; - public PlatformNotificationServiceImpl(NotifyIcon notifyIcon) + public NotificationServiceImpl(NotifyIcon notifyIcon) { this.notifyIcon = notifyIcon; } @@ -47,4 +50,4 @@ namespace System.Application.Services.Implementation throw new PlatformNotSupportedException(); } } -} \ No newline at end of file +} diff --git a/src/ST.Client.Desktop/Services/Implementation/SteamDbWebApiServiceImpl.cs b/src/ST.Client/Services/Implementation/SteamDbWebApiServiceImpl.cs similarity index 100% rename from src/ST.Client.Desktop/Services/Implementation/SteamDbWebApiServiceImpl.cs rename to src/ST.Client/Services/Implementation/SteamDbWebApiServiceImpl.cs diff --git a/src/ST.Client.Desktop/Services/Implementation/SteamServiceImpl.cs b/src/ST.Client/Services/Implementation/SteamServiceImpl.cs similarity index 99% rename from src/ST.Client.Desktop/Services/Implementation/SteamServiceImpl.cs rename to src/ST.Client/Services/Implementation/SteamServiceImpl.cs index 7a4721761..ef28a7da7 100644 --- a/src/ST.Client.Desktop/Services/Implementation/SteamServiceImpl.cs +++ b/src/ST.Client/Services/Implementation/SteamServiceImpl.cs @@ -2,7 +2,7 @@ using Gameloop.Vdf.Linq; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Application.Models; -using System.Application.Models.Settings; +using System.Application.Settings; using System.Application.UI; using System.Collections.Generic; using System.Diagnostics; @@ -40,7 +40,7 @@ namespace System.Application.Services.Implementation readonly string? AppInfoPath; readonly string? LibrarycacheDirPath; const string UserDataDirectory = "userdata"; - readonly IDesktopPlatformService platformService; + readonly IPlatformService platformService; readonly string? mSteamDirPath; readonly string? mSteamProgramPath; readonly string? mRegistryVdfPath; @@ -48,7 +48,7 @@ namespace System.Application.Services.Implementation readonly Lazy _http = new(() => DI.Get()); IHttpService Http => _http.Value; - public SteamServiceImpl(IDesktopPlatformService platformService) + public SteamServiceImpl(IPlatformService platformService) { this.platformService = platformService; mSteamDirPath = platformService.GetSteamDirPath(); @@ -501,7 +501,7 @@ namespace System.Application.Services.Implementation public /*async*/ ValueTask LoadAppImageAsync(SteamApp app) { - return ValueTask.CompletedTask; + return new ValueTask(); //if (app.LibraryLogoStream == null) //{ // app.LibraryLogoStream = await GetAppImageAsync(app, SteamApp.LibCacheType.Library_600x900); diff --git a/src/ST.Client.Desktop/Services/Implementation/SteamworksLocalApiServiceImpl.cs b/src/ST.Client/Services/Implementation/SteamworksLocalApiServiceImpl.cs similarity index 100% rename from src/ST.Client.Desktop/Services/Implementation/SteamworksLocalApiServiceImpl.cs rename to src/ST.Client/Services/Implementation/SteamworksLocalApiServiceImpl.cs diff --git a/src/ST.Client.Desktop/Services/Implementation/SteamworksWebApiServiceImpl.cs b/src/ST.Client/Services/Implementation/SteamworksWebApiServiceImpl.cs similarity index 100% rename from src/ST.Client.Desktop/Services/Implementation/SteamworksWebApiServiceImpl.cs rename to src/ST.Client/Services/Implementation/SteamworksWebApiServiceImpl.cs diff --git a/src/ST.Client.Desktop/Services/Implementation/PlatformToastImpl.cs b/src/ST.Client/Services/Implementation/ToastImpl.cs similarity index 66% rename from src/ST.Client.Desktop/Services/Implementation/PlatformToastImpl.cs rename to src/ST.Client/Services/Implementation/ToastImpl.cs index 89ad240e7..18356a498 100644 --- a/src/ST.Client.Desktop/Services/Implementation/PlatformToastImpl.cs +++ b/src/ST.Client/Services/Implementation/ToastImpl.cs @@ -2,9 +2,12 @@ using Microsoft.Extensions.DependencyInjection; namespace System.Application.Services.Implementation { - internal sealed class PlatformToastImpl : ToastImpl + /// + /// 使用 实现的 + /// + internal sealed class ToastImpl : ToastBaseImpl { - public PlatformToastImpl(IToastIntercept intercept) : base(intercept) + public ToastImpl(IToastIntercept intercept) : base(intercept) { } @@ -18,6 +21,6 @@ namespace System.Application.Services.Implementation } internal static IServiceCollection TryAddToast(IServiceCollection services) - => TryAddToast(services); + => TryAddToast(services); } } \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/Implementation/DesktopWindowViewModelManager.cs b/src/ST.Client/Services/Implementation/ViewModelManager.cs similarity index 81% rename from src/ST.Client.Desktop/Services/Implementation/DesktopWindowViewModelManager.cs rename to src/ST.Client/Services/Implementation/ViewModelManager.cs index a4648760e..8d38d92fe 100644 --- a/src/ST.Client.Desktop/Services/Implementation/DesktopWindowViewModelManager.cs +++ b/src/ST.Client/Services/Implementation/ViewModelManager.cs @@ -1,5 +1,4 @@ using ReactiveUI; -using System; using System.Application.Mvvm; using System.Reactive.Disposables; using System.Application.UI.ViewModels; @@ -10,7 +9,7 @@ using System.Threading.Tasks; namespace System.Application.Services.Implementation { - public class DesktopWindowViewModelManager : ReactiveObject, IDesktopWindowViewModelManager + internal sealed class ViewModelManager : ReactiveObject, IViewModelManager { MainWindowViewModel? mainWindow; AchievementWindowViewModel? achievementWindow; @@ -43,7 +42,7 @@ namespace System.Application.Services.Implementation } catch (Exception ex) { - Log.Error(nameof(DesktopWindowViewModelManager), ex, "Init WindowViewModel"); + Log.Error(nameof(ViewModelManager), ex, "Init WindowViewModel"); throw; } finally @@ -54,6 +53,7 @@ namespace System.Application.Services.Implementation int appidUnlockAchievement; bool appidUnlockAchievementHasValue; + public void InitUnlockAchievement(int appid) { appidUnlockAchievement = appid; @@ -103,9 +103,27 @@ namespace System.Application.Services.Implementation ICollection IDisposableHolder.CompositeDisposable => compositeDisposable; + bool disposedValue; + void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: 释放托管状态(托管对象) + compositeDisposable.Dispose(); + } + + // TODO: 释放未托管的资源(未托管的对象)并重写终结器 + // TODO: 将大型字段设置为 null + disposedValue = true; + } + } + public void Dispose() { - compositeDisposable.Dispose(); + // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 + Dispose(disposing: true); GC.SuppressFinalize(this); } diff --git a/src/ST.Client.Desktop/Services/Mvvm/ASFService.cs b/src/ST.Client/Services/Mvvm/ASFService.cs similarity index 91% rename from src/ST.Client.Desktop/Services/Mvvm/ASFService.cs rename to src/ST.Client/Services/Mvvm/ASFService.cs index e0756277c..70330563f 100644 --- a/src/ST.Client.Desktop/Services/Mvvm/ASFService.cs +++ b/src/ST.Client/Services/Mvvm/ASFService.cs @@ -8,15 +8,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +// ReSharper disable once CheckNamespace namespace System.Application.Services { - public class ASFService : ReactiveObject + public sealed class ASFService : MvvmService { - #region static members - public static ASFService Current { get; } = new(); - #endregion - - private readonly IArchiSteamFarmService archiSteamFarmService = IArchiSteamFarmService.Instance; + readonly IArchiSteamFarmService archiSteamFarmService = IArchiSteamFarmService.Instance; string? _IPCUrl; public string? IPCUrl @@ -46,6 +43,7 @@ namespace System.Application.Services public ASFService() { SteamBotsSourceList = new SourceCache(t => t.BotName); + //InitASF(); } diff --git a/src/ST.Client/Services/Mvvm/Abstractions/ASFService.cs b/src/ST.Client/Services/Mvvm/Abstractions/ASFService.cs deleted file mode 100644 index bf1002847..000000000 --- a/src/ST.Client/Services/Mvvm/Abstractions/ASFService.cs +++ /dev/null @@ -1,125 +0,0 @@ -using ArchiSteamFarm.Steam; -using ArchiSteamFarm.Storage; -using DynamicData; -using ReactiveUI; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Interface = System.Application.Services.ASFService; -using BaseClass = System.Application.Services.Abstractions.ASFService; - -namespace System.Application.Services -{ -#pragma warning disable IDE1006 // 命名样式 - internal interface ASFService -#pragma warning restore IDE1006 // 命名样式 - { - static BaseClass Current => mCurrent is BaseClass i ? i : throw new NullReferenceException("ASFService is null."); - - static BaseClass? mCurrent; - } -} - -namespace System.Application.Services.Abstractions -{ - public abstract class ASFService : ReactiveObject, Interface - { - protected readonly IArchiSteamFarmService archiSteamFarmService = IArchiSteamFarmService.Instance; - - string _IPCUrl = string.Empty; - public string IPCUrl - { - get => _IPCUrl; - set => this.RaiseAndSetIfChanged(ref _IPCUrl, value); - } - - string? _ConsoleLogText; - public string? ConsoleLogText - { - get => _ConsoleLogText; - set => this.RaiseAndSetIfChanged(ref _ConsoleLogText, value); - } - - public SourceCache SteamBotsSourceList; - - public bool IsASFRuning => archiSteamFarmService.StartTime != null; - - GlobalConfig? _GlobalConfig; - public GlobalConfig? GlobalConfig - { - get => _GlobalConfig; - set => this.RaiseAndSetIfChanged(ref _GlobalConfig, value); - } - - public ASFService() - { - SteamBotsSourceList = new SourceCache(t => t.BotName); - - //InitASF(); - } - - public async void InitASF() - { - IArchiSteamFarmService.Instance.GetConsoleWirteFunc = (message) => - { - if (!string.IsNullOrEmpty(ConsoleLogText)) - { - var lines = ConsoleLogText.Split(Environment.NewLine, StringSplitOptions.None).ToList(); - if (lines.Count >= 200) - { - lines.RemoveAt(0); - lines.Add(message); - ConsoleLogText = string.Join(Environment.NewLine, lines); - return; - } - } - ConsoleLogText += Environment.NewLine + message; - }; - - await IArchiSteamFarmService.Instance.Start(); - - RefreshBots(); - - IPCUrl = archiSteamFarmService.GetIPCUrl(); - - this.RaisePropertyChanged(nameof(IsASFRuning)); - } - - public async void StopASF() - { - await IArchiSteamFarmService.Instance.Stop(); - - this.RaisePropertyChanged(nameof(IsASFRuning)); - } - - public void RefreshBots() - { - SteamBotsSourceList.Clear(); - - var bots = archiSteamFarmService.GetReadOnlyAllBots(); - if (bots.Any_Nullable()) - SteamBotsSourceList.AddOrUpdate(bots!.Values); - } - - public void RefreshConfig() - { - GlobalConfig = archiSteamFarmService.GetGlobalConfig(); - } - } - - public abstract class ASFService : BaseClass, Interface where T : ASFService, new() - { - public static T Current - { - get => ((T)Interface.Current)!; - protected set => Interface.mCurrent = value; - } - - static ASFService() - { - Current = new(); - } - } -} diff --git a/src/ST.Client/Services/Mvvm/Abstractions/AuthService.cs b/src/ST.Client/Services/Mvvm/AuthService.cs similarity index 94% rename from src/ST.Client/Services/Mvvm/Abstractions/AuthService.cs rename to src/ST.Client/Services/Mvvm/AuthService.cs index b10daf9ff..43ba21b37 100644 --- a/src/ST.Client/Services/Mvvm/Abstractions/AuthService.cs +++ b/src/ST.Client/Services/Mvvm/AuthService.cs @@ -3,7 +3,6 @@ using Newtonsoft.Json.Linq; using ReactiveUI; using System.Application.Entities; using System.Application.Models; -using System.Application.Models.Abstractions; using System.Application.UI; using System.Application.UI.Resx; using System.Application.UI.ViewModels; @@ -19,28 +18,12 @@ using System.Xml; using WinAuth; using static System.Application.Models.GAPAuthenticatorValueDTO; using GAPRepository = System.Application.Repositories.IGameAccountPlatformAuthenticatorRepository; -using Interface = System.Application.Services.AuthService; -using BaseClass = System.Application.Services.Abstractions.AuthService; -using static System.Application.Services.AuthService; +// ReSharper disable once CheckNamespace namespace System.Application.Services { -#pragma warning disable IDE1006 // 命名样式 - internal interface AuthService -#pragma warning restore IDE1006 // 命名样式 + public sealed class AuthService : MvvmService { - static BaseClass Current => mCurrent is BaseClass i ? i : throw new NullReferenceException("AuthService is null."); - - static BaseClass? mCurrent; - } -} - -namespace System.Application.Services.Abstractions -{ - public abstract class AuthService : ReactiveObject, Interface - { - public static BaseClass Current => Interface.Current; - public static async Task GetQrCodeStreamAsync(IEnumerable datas) { var qrCode = await Task.Run(() => @@ -75,10 +58,6 @@ namespace System.Application.Services.Abstractions return GetQrCodeStreamAsync(datas_); } - protected abstract MyAuthenticator GetMyAuthenticator(IGAPAuthenticatorDTO dto); - - protected abstract MyAuthenticator GetMyAuthenticator(); - private readonly GAPRepository repository = DI.Get(); public SourceCache Authenticators { get; } @@ -115,7 +94,7 @@ namespace System.Application.Services.Abstractions } if (list.Any_Nullable()) { - var authenticators = list.Select(s => GetMyAuthenticator(s)); + var authenticators = list.Select(s => new MyAuthenticator(s)); //MainThread2.BeginInvokeOnMainThread(() => //{ @@ -569,7 +548,7 @@ namespace System.Application.Services.Abstractions { foreach (var item in result.result) { - AddOrUpdateSaveAuthenticators(GetMyAuthenticator(item), isLocal, password); + AddOrUpdateSaveAuthenticators(new MyAuthenticator(item), isLocal, password); } Toast.Show(AppResources.LocalAuth_AddAuthSuccess); @@ -578,7 +557,7 @@ namespace System.Application.Services.Abstractions { foreach (var item in result.result) { - AddOrUpdateSaveAuthenticators(GetMyAuthenticator(item), isLocal, password); + AddOrUpdateSaveAuthenticators(new MyAuthenticator(item), isLocal, password); } Toast.Show(AppResources.LocalAuth_AddAuth_PartSuccess); } @@ -644,7 +623,7 @@ namespace System.Application.Services.Abstractions } if (reader.Name == "WinAuthAuthenticator") { - var wa = GetMyAuthenticator(); + var wa = new MyAuthenticator(); wa.ReadXml(reader, null); AddOrUpdateSaveAuthenticators(wa, isLocal, password); } @@ -661,18 +640,18 @@ namespace System.Application.Services.Abstractions public void AddOrUpdateSaveAuthenticators(GAPAuthenticatorDTO auth, bool isLocal, string? password) { - AddOrUpdateSaveAuthenticators(GetMyAuthenticator(auth), isLocal, password); + AddOrUpdateSaveAuthenticators(new MyAuthenticator(auth), isLocal, password); } public async void AddOrUpdateSaveAuthenticators(MyAuthenticator auth, bool isLocal, string? password) { var repository = DI.Get(); await repository.InsertOrUpdateAsync(auth.AuthenticatorData, isLocal, password); - if (Current.Authenticators.Items.Any(s => s.Id == auth.Id)) + if (Authenticators.Items.Any(s => s.Id == auth.Id)) { return; } - Current.Authenticators.AddOrUpdate(auth); + Authenticators.AddOrUpdate(auth); } public async void AddOrUpdateSaveAuthenticators(IEnumerable auths) @@ -770,18 +749,4 @@ namespace System.Application.Services.Abstractions } } } - - public abstract class AuthService : BaseClass, Interface where T : AuthService, new() - { - public new static T Current - { - get => ((T)Interface.Current)!; - protected set => Interface.mCurrent = value; - } - - static AuthService() - { - Current = new(); - } - } } \ No newline at end of file diff --git a/src/ST.Client/Services/Mvvm/Abstractions/ProxyService.cs b/src/ST.Client/Services/Mvvm/ProxyService.cs similarity index 75% rename from src/ST.Client/Services/Mvvm/Abstractions/ProxyService.cs rename to src/ST.Client/Services/Mvvm/ProxyService.cs index 7bf22bb97..bbba699f7 100644 --- a/src/ST.Client/Services/Mvvm/Abstractions/ProxyService.cs +++ b/src/ST.Client/Services/Mvvm/ProxyService.cs @@ -18,46 +18,34 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Titanium.Web.Proxy.Models; -using Interface = System.Application.Services.ProxyService; -using BaseClass = System.Application.Services.Abstractions.ProxyService; -using static System.Application.Services.ProxyService; +// ReSharper disable once CheckNamespace namespace System.Application.Services { -#pragma warning disable IDE1006 // 命名样式 - internal interface ProxyService -#pragma warning restore IDE1006 // 命名样式 + public sealed class ProxyService : MvvmService, IDisposable { - static BaseClass Current => mCurrent is BaseClass i ? i : throw new NullReferenceException("ProxyService is null."); - - static BaseClass? mCurrent; - } -} - -namespace System.Application.Services.Abstractions -{ - public abstract class ProxyService : ReactiveObject, Interface - { - protected readonly IHttpProxyService httpProxyService = DI.Get(); - protected readonly IScriptManager scriptManager = DI.Get(); + readonly IHttpProxyService httpProxyService = IHttpProxyService.Instance; + readonly IScriptManager scriptManager = IScriptManager.Instance; + readonly IHostsFileService hostsFileService = IHostsFileService.Instance; + readonly IPlatformService platformService = IPlatformService.Instance; public ProxyService() { ProxyDomains = new SourceList(); ProxyScripts = new SourceList(); - this.ProxyDomains - .Connect() - //.Filter(scriptFilter) - .ObserveOn(RxApp.MainThreadScheduler) - .Sort(SortExpressionComparer.Ascending(x => x.Order).ThenBy(x => x.Name)) - .Bind(out _ProxyDomainsList) - .Subscribe(_ => SelectGroup = ProxyDomains.Items.FirstOrDefault()); + ProxyDomains + .Connect() + //.Filter(scriptFilter) + .ObserveOn(RxApp.MainThreadScheduler) + .Sort(SortExpressionComparer.Ascending(x => x.Order).ThenBy(x => x.Name)) + .Bind(out _ProxyDomainsList) + .Subscribe(_ => SelectGroup = ProxyDomains.Items.FirstOrDefault()); } public SourceList ProxyDomains { get; } - private ReadOnlyObservableCollection? _ProxyDomainsList; + private readonly ReadOnlyObservableCollection? _ProxyDomainsList; public ReadOnlyObservableCollection? ProxyDomainsList => _ProxyDomainsList; bool _IsLoading; @@ -93,8 +81,8 @@ namespace System.Application.Services.Abstractions { get { - if (!IsEnableScript) - return null; + //if (!IsEnableScript) + //return null; if (!ProxyScripts.Items.Any_Nullable()) return null; return ProxyScripts.Items!.Where(w => w.Enable).ToArray(); @@ -103,8 +91,8 @@ namespace System.Application.Services.Abstractions private DateTimeOffset _StartAccelerateTime; - private DateTimeOffset _AccelerateTime; - public DateTimeOffset AccelerateTime + private TimeSpan _AccelerateTime; + public TimeSpan AccelerateTime { get => _AccelerateTime; set @@ -129,6 +117,20 @@ namespace System.Application.Services.Abstractions } } + public bool IsOnlyWorkSteamBrowser + { + get => ProxySettings.IsOnlyWorkSteamBrowser.Value; + set + { + if (ProxySettings.IsOnlyWorkSteamBrowser.Value != value) + { + ProxySettings.IsOnlyWorkSteamBrowser.Value = value; + httpProxyService.IsOnlyWorkSteamBrowser = value; + this.RaisePropertyChanged(); + } + } + } + #region HOSTS_PROXY_RUNNING_STATUS //const string KEY_HOSTS_PROXY_RUNNING_STATUS = "KEY_HOSTS_PROXY_RUNNING_STATUS"; @@ -145,28 +147,6 @@ namespace System.Application.Services.Abstractions #endregion - protected virtual void ConfigProxyService() - { - - } - - protected virtual bool EnableSystemProxy => true; - - protected virtual void OnHostProxy() - { - - } - - protected virtual void OnRunHostProxy(IEnumerable<(string, string)> hosts) - { - - } - - protected virtual void OnStopRemoveHostsByTag() - { - - } - #region 代理状态启动退出 public bool ProxyStatus { @@ -184,9 +164,11 @@ namespace System.Application.Services.Abstractions //httpProxyService.ProxyDomains = EnableProxyDomains; //} httpProxyService.ProxyDomains = EnableProxyDomains; - httpProxyService.Scripts = EnableProxyScripts; httpProxyService.IsEnableScript = ProxySettings.IsEnableScript.Value; - httpProxyService.IsSystemProxy = EnableSystemProxy; + httpProxyService.Scripts = EnableProxyScripts; + httpProxyService.IsOnlyWorkSteamBrowser = ProxySettings.IsOnlyWorkSteamBrowser.Value; + httpProxyService.IsSystemProxy = ProxySettings.EnableWindowsProxy.Value; + httpProxyService.IsProxyGOG = ProxySettings.IsProxyGOG.Value; // macOS 上目前因权限问题仅支持 0.0.0.0(IPAddress.Any) httpProxyService.ProxyIp = (!OperatingSystem2.IsMacOS && IPAddress2.TryParse(ProxySettings.SystemProxyIp.Value, out var ip)) ? ip : IPAddress.Any; @@ -194,6 +176,7 @@ namespace System.Application.Services.Abstractions httpProxyService.Socks5ProxyEnable = ProxySettings.Socks5ProxyEnable.Value; httpProxyService.Socks5ProxyPortId = ProxySettings.Socks5ProxyPortId.Value; + httpProxyService.HostProxyPortId = ProxySettings.HostProxyPortId; httpProxyService.TwoLevelAgentEnable = ProxySettings.TwoLevelAgentEnable.Value; httpProxyService.TwoLevelAgentProxyType = (ExternalProxyType)ProxySettings.TwoLevelAgentProxyType.Value; @@ -204,14 +187,38 @@ namespace System.Application.Services.Abstractions httpProxyService.TwoLevelAgentUserName = ProxySettings.TwoLevelAgentUserName.Value; httpProxyService.TwoLevelAgentPassword = ProxySettings.TwoLevelAgentPassword.Value; - ConfigProxyService(); - this.RaisePropertyChanged(nameof(EnableProxyDomains)); this.RaisePropertyChanged(nameof(EnableProxyScripts)); if (!httpProxyService.IsSystemProxy) { - OnHostProxy(); + //if (OperatingSystem2.IsWindows) + //{ + // var inUse = httpProxyService.PortInUse(443); + // if (inUse) + // { + // var p = DI.Get().GetProcessByPortOccupy(443, true); + // if (p != null) + // { + // Toast.Show(string.Format(AppResources.CommunityFix_StartProxyFaild443, p.ProcessName)); + // return; + // } + // } + //} + //else + //{ + if (OperatingSystem2.IsLinux && ProxySettings.HostProxyPortId == 443 && Environment.UserName != "root") + { + Toast.Show("Liunx Hosts 代理模式 需要 Root 权限,或使用 “sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443” 映射到其他端口且修改代理设置监听端口"); + return; + } + var inUse = httpProxyService.PortInUse(ProxySettings.HostProxyPortId); + if (inUse) + { + Toast.Show(string.Format(AppResources.CommunityFix_StartProxyFaild443, ProxySettings.HostProxyPortId, "")); + return; + } + //} } var isRun = httpProxyService.StartProxy(); @@ -236,7 +243,22 @@ namespace System.Application.Services.Abstractions }); }).Where(w => !string.IsNullOrEmpty(w.Item1)); - OnRunHostProxy(hosts); + var r = hostsFileService.UpdateHosts(hosts); + + if (r.ResultType != OperationResultType.Success) + { + Toast.Show(SR.OperationHostsError_.Format(r.Message)); + httpProxyService.StopProxy(); + return; + } + else if (OperatingSystem2.IsMacOS) + { + platformService.RunShell($" \\cp \"{Path.Combine(IOPath.CacheDirectory, "hosts")}\" \"{platformService.HostsFilePath}\"", true); + } + else if (OperatingSystem2.IsLinux && Environment.UserName.ToLower() != "root") + { + platformService.RunShell($" \\cp \"{Path.Combine(IOPath.CacheDirectory, "hosts")}\" \"{platformService.HostsFilePath}\"", true); + } } } _StartAccelerateTime = DateTimeOffset.Now; @@ -252,6 +274,24 @@ namespace System.Application.Services.Abstractions { httpProxyService.StopProxy(); StopTimer(); + void OnStopRemoveHostsByTag() + { + var needClear = hostsFileService.ContainsHostsByTag(); + if (needClear) + { + var r = hostsFileService.RemoveHostsByTag(); + + if (r.ResultType != OperationResultType.Success) + { + Toast.Show(SR.OperationHostsError_.Format(r.Message)); + //return; + } + else if (OperatingSystem2.IsMacOS && !ProxySettings.EnableWindowsProxy.Value) + { + platformService.RunShell($" \\cp \"{Path.Combine(IOPath.CacheDirectory, "hosts")}\" \"{platformService.HostsFilePath}\"", true); + } + } + } OnStopRemoveHostsByTag(); //Toast.Show(SteamTools.Properties.Resources.ProxyStop); } @@ -356,7 +396,8 @@ namespace System.Application.Services.Abstractions .WhenPropertyChanged(x => x.Enable, false) .Subscribe(_ => { - ProxySettings.ScriptsStatus.Value = EnableProxyScripts?.Where(w => w?.LocalId > 0).Select(k => k.LocalId).ToList(); + //ProxySettings.ScriptsStatus.Value = EnableProxyScripts?.Where(w => w?.LocalId > 0).Select(k => k.LocalId).ToList(); + ProxySettings.ScriptsStatus.Value = ProxyScripts.Items.Where(x => x?.LocalId > 0).Select(k => k.LocalId).ToList(); httpProxyService.Scripts = EnableProxyScripts; this.RaisePropertyChanged(nameof(EnableProxyScripts)); })); @@ -432,14 +473,12 @@ namespace System.Application.Services.Abstractions public void StartTimer() { - AccelerateTime = new DateTimeOffset().Add((DateTimeOffset.Now - _StartAccelerateTime)); - if (timer == null) { timer = new Timer((state) => { Thread.CurrentThread.IsBackground = true; - AccelerateTime = AccelerateTime.AddSeconds(1); + AccelerateTime = DateTimeOffset.Now - _StartAccelerateTime; }, nameof(AccelerateTime), 1000, 1000); } } @@ -453,18 +492,17 @@ namespace System.Application.Services.Abstractions } } - protected virtual void OnExitRestoreHostsCore() + public static void OnExitRestoreHosts() { - - } - - public static void OnExitRestoreHosts() => Current.OnExitRestoreHostsCore(); - - public void Dispose() - { - httpProxyService.StopProxy(); - OnExitRestoreHostsCore(); - httpProxyService.Dispose(); + var s = DI.Get_Nullable(); + if (s != null) + { + var needClear = s.ContainsHostsByTag(); + if (needClear) + { + s.OnExitRestoreHosts(); + } + } } public async Task AddNewScript(string filename) @@ -627,19 +665,31 @@ namespace System.Application.Services.Abstractions Toast.Show(AppResources.FixNetworkComplete); } - } - public abstract class ProxyService : BaseClass, Interface where T : ProxyService, new() - { - public static T Current + bool disposedValue; + void Dispose(bool disposing) { - get => ((T)Interface.Current)!; - protected set => Interface.mCurrent = value; + if (!disposedValue) + { + if (disposing) + { + // TODO: 释放托管状态(托管对象) + httpProxyService.StopProxy(); + OnExitRestoreHosts(); + httpProxyService.Dispose(); + } + + // TODO: 释放未托管的资源(未托管的对象)并重写终结器 + // TODO: 将大型字段设置为 null + disposedValue = true; + } } - static ProxyService() + public void Dispose() { - Current = new(); + // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 + Dispose(disposing: true); + GC.SuppressFinalize(this); } } } \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/Mvvm/SteamConnectService.cs b/src/ST.Client/Services/Mvvm/SteamConnectService.cs similarity index 89% rename from src/ST.Client.Desktop/Services/Mvvm/SteamConnectService.cs rename to src/ST.Client/Services/Mvvm/SteamConnectService.cs index 053fa5e98..daa5f787d 100644 --- a/src/ST.Client.Desktop/Services/Mvvm/SteamConnectService.cs +++ b/src/ST.Client/Services/Mvvm/SteamConnectService.cs @@ -14,18 +14,15 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +// ReSharper disable once CheckNamespace namespace System.Application.Services { - public class SteamConnectService : ReactiveObject + public sealed class SteamConnectService : MvvmService, IDisposable { - #region static members - public static SteamConnectService Current { get; } = new(); - #endregion - - private readonly ISteamworksLocalApiService ApiService = ISteamworksLocalApiService.Instance; - //private readonly ISteamworksWebApiService SteamworksWebApiService = ISteamworksWebApiService.Instance; - //private readonly ISteamDbWebApiService steamDbApiService = ISteamDbWebApiService.Instance; - private readonly ISteamService SteamTool = ISteamService.Instance; + readonly ISteamworksLocalApiService ApiService = ISteamworksLocalApiService.Instance; + //readonly ISteamworksWebApiService SteamworksWebApiService = ISteamworksWebApiService.Instance; + //readonly ISteamDbWebApiService steamDbApiService = ISteamDbWebApiService.Instance; + readonly ISteamService SteamTool = ISteamService.Instance; public const int SteamAFKMaxCount = 32; public SteamConnectService() @@ -215,7 +212,7 @@ namespace System.Application.Services IsConnectToSteam = true; CurrentSteamUser = await DI.Get().GetUserInfo(id); CurrentSteamUser.AvatarStream = IHttpService.Instance.GetImageAsync(CurrentSteamUser.AvatarFull, ImageChannelType.SteamAvatars); - AvaterPath = ImageSouceHelper.TryParse(await CurrentSteamUser.AvatarStream, isCircle: true); + AvaterPath = ImageSouce.TryParse(await CurrentSteamUser.AvatarStream, isCircle: true); CurrentSteamUser.IPCountry = ApiService.GetIPCountry(); IsSteamChinaLauncher = ApiService.IsSteamChinaLauncher(); @@ -241,7 +238,6 @@ namespace System.Application.Services //await mainViewModel.SteamAppPage.Initialize(); //await mainViewModel.AccountPage.Initialize(id); #endregion - if (!IsDisposedClient) { DisposeSteamClient(); @@ -305,6 +301,7 @@ namespace System.Application.Services } private bool _IsRefreshing; + public /*async*/ void RefreshGamesList() { if (_IsRefreshing == false) @@ -358,21 +355,40 @@ namespace System.Application.Services } } - public void Dispose() - { - foreach (var app in Current.RuningSteamApps.Values) - { - if (app.Process != null) - if (!app.Process.HasExited) - app.Process.Kill(); - } - DisposeSteamClient(); - } - public void DisposeSteamClient() { ApiService.DisposeSteamClient(); IsDisposedClient = true; } + + bool disposedValue; + private void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: 释放托管状态(托管对象) + foreach (var app in Current.RuningSteamApps.Values) + { + if (app.Process != null) + if (!app.Process.HasExited) + app.Process.Kill(); + } + DisposeSteamClient(); + } + + // TODO: 释放未托管的资源(未托管的对象)并重写终结器 + // TODO: 将大型字段设置为 null + disposedValue = true; + } + } + + public void Dispose() + { + // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 + Dispose(disposing: true); + GC.SuppressFinalize(this); + } } } diff --git a/src/ST.Client/Services/Mvvm/Abstractions/ToastService.cs b/src/ST.Client/Services/Mvvm/ToastService.cs similarity index 68% rename from src/ST.Client/Services/Mvvm/Abstractions/ToastService.cs rename to src/ST.Client/Services/Mvvm/ToastService.cs index 9f9d9a7a9..a139187c6 100644 --- a/src/ST.Client/Services/Mvvm/Abstractions/ToastService.cs +++ b/src/ST.Client/Services/Mvvm/ToastService.cs @@ -4,30 +4,21 @@ using System.Text; using ReactiveUI; using System.Reactive.Subjects; using System.Reactive.Linq; -using Interface = System.Application.Services.ToastService; -using BaseClass = System.Application.Services.Abstractions.ToastService; +using System.Application.UI; +// ReSharper disable once CheckNamespace namespace System.Application.Services -{ -#pragma warning disable IDE1006 // 命名样式 - /// - internal interface ToastService -#pragma warning restore IDE1006 // 命名样式 - { - static BaseClass Current => mCurrent is BaseClass i ? i : throw new NullReferenceException("AuthService is null."); - - static BaseClass? mCurrent; - } -} - -namespace System.Application.Services.Abstractions { /// /// 提供对显示在主窗口底部的状态栏的访问 /// - public abstract class ToastService : ReactiveObject, Interface + public sealed class ToastService : MvvmService { - public static BaseClass Current => Interface.Current; + public static bool IsSupported => IApplication.Type switch + { + IApplication.AppType.Avalonia => true, + _ => false, + }; private readonly Subject notifier; private string persisitentMessage = ""; @@ -61,7 +52,7 @@ namespace System.Application.Services.Abstractions set => this.RaiseAndSetIfChanged(ref _IsVisible, value); } - protected ToastService() + public ToastService() { notifier = new Subject(); notifier @@ -85,6 +76,7 @@ namespace System.Application.Services.Abstractions { CloseBtn_Click(); } + public void Set(string message) { MainThread2.BeginInvokeOnMainThread(() => Message = message); @@ -106,19 +98,4 @@ namespace System.Application.Services.Abstractions IsVisible = false; } } - - /// - public abstract class ToastService : BaseClass, Interface where T : ToastService, new() - { - public new static T Current - { - get => ((T)Interface.Current)!; - protected set => Interface.mCurrent = value; - } - - static ToastService() - { - Current = new(); - } - } } diff --git a/src/ST.Client/Services/Mvvm/Abstractions/UserService.cs b/src/ST.Client/Services/Mvvm/UserService.cs similarity index 70% rename from src/ST.Client/Services/Mvvm/Abstractions/UserService.cs rename to src/ST.Client/Services/Mvvm/UserService.cs index f2c99eb04..49f0fee3f 100644 --- a/src/ST.Client/Services/Mvvm/Abstractions/UserService.cs +++ b/src/ST.Client/Services/Mvvm/UserService.cs @@ -5,26 +5,18 @@ using System.Application.UI.ViewModels; using System.Properties; using System.Linq; using System.Threading.Tasks; -using Interface = System.Application.Services.UserService; -using BaseClass = System.Application.Services.Abstractions.UserService; +using System.Application.UI; +// ReSharper disable once CheckNamespace namespace System.Application.Services { -#pragma warning disable IDE1006 // 命名样式 - internal interface UserService -#pragma warning restore IDE1006 // 命名样式 + public sealed class UserService : MvvmService { - static BaseClass Current => mCurrent is BaseClass i ? i : throw new NullReferenceException("UserService is null."); - - static BaseClass? mCurrent; - } -} - -namespace System.Application.Services.Abstractions -{ - public abstract class UserService : ReactiveObject, Interface - { - protected readonly IUserManager userManager = DI.Get(); + readonly IUserManager userManager = IUserManager.Instance; + readonly ICloudServiceClient csc = ICloudServiceClient.Instance; + readonly IHttpService httpService = IHttpService.Instance; + readonly ISteamworksWebApiService steamworksWebApiService = ISteamworksWebApiService.Instance; + readonly IWindowManager windowManager = IWindowManager.Instance; public async void ShowWindow(CustomWindow windowName) { @@ -45,11 +37,7 @@ namespace System.Application.Services.Abstractions if (!cUser.HasValue()) return; if (string.IsNullOrWhiteSpace(cUser!.PhoneNumber)) return; } - var vmType = Type.GetType($"System.Application.UI.ViewModels.{windowName}WindowViewModel"); - if (vmType != null && typeof(WindowViewModel).IsAssignableFrom(vmType)) - { - await IWindowManager.Instance.ShowDialog(vmType, windowName, isDialog: isDialog); - } + await windowManager.ShowDialog(windowName, isDialog: isDialog); } public async Task SignOutAsync(Func>? apiCall = null, string? message = null) @@ -77,7 +65,7 @@ namespace System.Application.Services.Abstractions var r = await MessageBox.ShowAsync(AppResources.User_SignOutTip, ThisAssembly.AssemblyTrademark, MessageBox.Button.OKCancel); if (r == MessageBox.Result.OK) { - await SignOutAsync(ICloudServiceClient.Instance.Manage.SignOut); + await SignOutAsync(csc.Manage.SignOut); } } @@ -85,7 +73,7 @@ namespace System.Application.Services.Abstractions { if (!IsAuthenticated) return; var msg = AppResources.Success_.Format(AppResources.DelAccount); - await SignOutAsync(ICloudServiceClient.Instance.Manage.DeleteAccount, msg); + await SignOutAsync(csc.Manage.DeleteAccount, msg); } public async Task SignOutUserManagerAsync() @@ -105,7 +93,24 @@ namespace System.Application.Services.Abstractions /// public bool IsAuthenticated => User != null; - protected abstract string DefaultAvaterPath { get; } + SteamUser? _SteamUser; + public SteamUser? CurrentSteamUser + { + get => _SteamUser; + set => this.RaiseAndSetIfChanged(ref _SteamUser, value); + } + + public string DefaultAvaterPath + { + get + { + if (IApplication.Type == IApplication.AppType.Avalonia) + { + return "avares://System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Assets/AppResources/avater_default.png"; + } + return string.Empty; + } + } object? _AvaterPath; @@ -123,17 +128,13 @@ namespace System.Application.Services.Abstractions userManager.OnSignOut += () => { User = null; + CurrentSteamUser = null; AvaterPath = DefaultAvaterPath; - OnSignOut(); }; Task.Run(Initialize).ForgetAndDispose(); } - protected virtual void OnSignOut() - { - } - async void Initialize() { await RefreshUserAsync(); @@ -189,9 +190,62 @@ namespace System.Application.Services.Abstractions await RefreshUserAsync(user); } - public virtual Task RefreshUserAvaterAsync() + public async Task RefreshUserAvaterAsync() { - return Task.CompletedTask; + if (User != null) + { + if (User.AvatarUrl.Any_Nullable()) + { + var settingPriority = FastLoginChannel.Steam; // 设置中优先选取头像渠道配置项 + var order = new[] { settingPriority }.Concat(new[] { + FastLoginChannel.Steam, + FastLoginChannel.QQ, + FastLoginChannel.Apple, + FastLoginChannel.Microsoft, + }.Where(x => x != settingPriority)); + foreach (var item in order) + { + if (User.AvatarUrl!.ContainsKey(item)) + { + var avatarUrl = User.AvatarUrl[item]; + if (!string.IsNullOrWhiteSpace(avatarUrl)) + { + var avatarLocalFilePath = await httpService.GetImageAsync(avatarUrl, ImageChannelType.SteamAvatars); + var avaterSouce = ImageSouce.TryParse(avatarLocalFilePath, isCircle: true); + AvaterPath = avaterSouce ?? DefaultAvaterPath; + } + return; + } + else if (item == FastLoginChannel.Steam + && await RefreshSteamUserAvaterAsync()) + { + return; + } + } + } + else if (await RefreshSteamUserAvaterAsync()) + { + return; + } + + async Task RefreshSteamUserAvaterAsync() + { + if (User != null && User.SteamAccountId.HasValue) + { + CurrentSteamUser = await steamworksWebApiService.GetUserInfo(User.SteamAccountId.Value); + CurrentSteamUser.AvatarStream = httpService.GetImageAsync(CurrentSteamUser.AvatarFull, ImageChannelType.SteamAvatars); + var avaterSouce = ImageSouce.TryParse(await CurrentSteamUser.AvatarStream, isCircle: true); + AvaterPath = avaterSouce ?? DefaultAvaterPath; + return true; + } + else + { + return false; + } + } + } + + AvaterPath = DefaultAvaterPath; } /// @@ -297,18 +351,4 @@ namespace System.Application.Services.Abstractions await RefreshUserAsync(user); } } - - public abstract class UserService : BaseClass, Interface where T : UserService, new() - { - public static T Current - { - get => ((T)Interface.Current)!; - protected set => Interface.mCurrent = value; - } - - static UserService() - { - Current = new(); - } - } } \ No newline at end of file diff --git a/src/ST.Client.Desktop/Services/OperationResult.cs b/src/ST.Client/Services/OperationResult.cs similarity index 100% rename from src/ST.Client.Desktop/Services/OperationResult.cs rename to src/ST.Client/Services/OperationResult.cs diff --git a/src/ST.Client.Desktop/Services/OperationResultType.cs b/src/ST.Client/Services/OperationResultType.cs similarity index 100% rename from src/ST.Client.Desktop/Services/OperationResultType.cs rename to src/ST.Client/Services/OperationResultType.cs diff --git a/src/ST.Client.Desktop/Settings/ASFSettings.cs b/src/ST.Client/Settings/ASFSettings.cs similarity index 82% rename from src/ST.Client.Desktop/Settings/ASFSettings.cs rename to src/ST.Client/Settings/ASFSettings.cs index abed3e267..8010b6927 100644 --- a/src/ST.Client.Desktop/Settings/ASFSettings.cs +++ b/src/ST.Client/Settings/ASFSettings.cs @@ -1,3 +1,9 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; +using System.Threading.Tasks; + namespace System.Application.Settings { public sealed class ASFSettings : SettingsHost2 diff --git a/src/ST.Client.Desktop/Settings/GameLibrarySettings.cs b/src/ST.Client/Settings/GameLibrarySettings.DefaultIgnoreList.cs similarity index 78% rename from src/ST.Client.Desktop/Settings/GameLibrarySettings.cs rename to src/ST.Client/Settings/GameLibrarySettings.DefaultIgnoreList.cs index 64a02f23a..16413d121 100644 --- a/src/ST.Client.Desktop/Settings/GameLibrarySettings.cs +++ b/src/ST.Client/Settings/GameLibrarySettings.DefaultIgnoreList.cs @@ -1,9 +1,12 @@ +using System; using System.Collections.Generic; using System.Collections.ObjectModel; +using System.Text; +using System.Threading.Tasks; namespace System.Application.Settings { - public sealed class GameLibrarySettings : SettingsHost2 + partial class GameLibrarySettings { public static readonly Lazy> DefaultIgnoreList = new(new ReadOnlyCollection(new uint[] { @@ -150,24 +153,6 @@ namespace System.Application.Settings 605470, 654310, 700580 - })); - - /// - /// 隐藏的游戏列表 - /// - public static SerializableProperty> HideGameList { get; } - = GetProperty(defaultValue: new Dictionary(), autoSave: true); - - /// - /// 挂时长游戏列表 - /// - public static SerializableProperty> AFKAppList { get; } - = GetProperty(defaultValue: new Dictionary(), autoSave: true); - - /// - /// 启用自动挂机 - /// - public static SerializableProperty IsAutoAFKApps { get; } - = GetProperty(defaultValue: true, autoSave: true); + })); } -} \ No newline at end of file +} diff --git a/src/ST.Client/Settings/GameLibrarySettings.cs b/src/ST.Client/Settings/GameLibrarySettings.cs new file mode 100644 index 000000000..6becb63d9 --- /dev/null +++ b/src/ST.Client/Settings/GameLibrarySettings.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Text; +using System.Threading.Tasks; + +namespace System.Application.Settings +{ + public sealed partial class GameLibrarySettings : SettingsHost2 + { + /// + /// 隐藏的游戏列表 + /// + public static SerializableProperty> HideGameList { get; } + = GetProperty(defaultValue: new Dictionary(), autoSave: true); + + /// + /// 挂时长游戏列表 + /// + public static SerializableProperty> AFKAppList { get; } + = GetProperty(defaultValue: new Dictionary(), autoSave: true); + + /// + /// 启用自动挂机 + /// + public static SerializableProperty IsAutoAFKApps { get; } + = GetProperty(defaultValue: true, autoSave: true); + } +} \ No newline at end of file diff --git a/src/ST.Client/Settings/GeneralSettings.cs b/src/ST.Client/Settings/GeneralSettings.cs index d70722a3f..f23fe45b0 100644 --- a/src/ST.Client/Settings/GeneralSettings.cs +++ b/src/ST.Client/Settings/GeneralSettings.cs @@ -1,19 +1,32 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Text; +using System.Threading.Tasks; +using System.Properties; +using System.Application.Services; +using System.Application.UI; namespace System.Application.Settings { - internal sealed class GeneralSettings : Abstractions.GeneralSettings + public sealed class GeneralSettings : SettingsHost2 { + static GeneralSettings() + { + WindowsStartupAutoRun.ValueChanged += WindowsStartupAutoRun_ValueChanged; + //CreateDesktopShortcut.ValueChanged += CreateDesktopShortcut_ValueChanged; + } - } -} + static void WindowsStartupAutoRun_ValueChanged(object? sender, ValueChangedEventArgs e) + { + IApplication.SetBootAutoStart(e.NewValue); + } + + public static void InitWindowsStartupAutoRun() + { + WindowsStartupAutoRun_ValueChanged(null, new(default, WindowsStartupAutoRun.Value)); + } -namespace System.Application.Settings.Abstractions -{ - public abstract class GeneralSettings : SettingsHost2 where TSettings : GeneralSettings, new() - { /// /// 自动检查更新 /// @@ -25,5 +38,71 @@ namespace System.Application.Settings.Abstractions /// public static SerializableProperty UpdateChannel { get; } = GetProperty(defaultValue: (UpdateChannelType)default, autoSave: true); + + /// + /// 程序是否开机自启动 + /// + public static SerializableProperty WindowsStartupAutoRun { get; } + = GetProperty(defaultValue: false, autoSave: true); + + ///// + ///// 创建桌面快捷方式 + ///// + //public static SerializableProperty CreateDesktopShortcut { get; } + // = new SerializableProperty(GetKey(), Providers.Roaming, false) { AutoSave = true }; + + /// + /// 程序启动时最小化 + /// + public static SerializableProperty IsStartupAppMinimized { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 是否显示起始页 + /// + public static SerializableProperty IsShowStartPage { get; } + = GetProperty(defaultValue: true, autoSave: true); + + /// + /// 启用游戏列表本地缓存 + /// + public static SerializableProperty IsSteamAppListLocalCache { get; } + = GetProperty(defaultValue: true, autoSave: true); + + /// + /// 启用错误日志记录 + /// + public static SerializableProperty IsEnableLogRecord { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 用户设置的文本阅读器提供商,根据平台值不同,值格式为 枚举字符串 或 程序路径 + /// + public static SerializableProperty> TextReaderProvider { get; } + = GetProperty(defaultValue: (IReadOnlyDictionary?)null, autoSave: true); + + /// + /// 使用硬件加速(仅macOS) + /// + public static SerializableProperty UseGPURendering { get; } + = GetProperty(defaultValue: true, autoSave: true); + + /// + /// Hosts 文件编码类型 + /// + public static SerializableProperty HostsEncodingType { get; } + = GetProperty(defaultValue: default(IHostsFileService.EncodingType), autoSave: true); + + ///// + ///// 使用 Direct2D1 渲染(仅 Windows) + ///// + //public static SerializableProperty UseDirect2D1 { get; } + // = GetProperty(defaultValue: false, autoSave: true); + + /// + /// Avalonia would try to use native Widows OpenGL when set to true. The default value is false.(仅 Windows) + /// + public static SerializableProperty UseOpenGL { get; } + = GetProperty(defaultValue: OperatingSystem2.IsWindows7, autoSave: true); } } diff --git a/src/ST.Client/Settings/ProxySettings.cs b/src/ST.Client/Settings/ProxySettings.cs index 2b595a6bd..745d30d3a 100644 --- a/src/ST.Client/Settings/ProxySettings.cs +++ b/src/ST.Client/Settings/ProxySettings.cs @@ -6,15 +6,7 @@ using IPAddress = System.Net.IPAddress; namespace System.Application.Settings { - internal sealed class ProxySettings : Abstractions.ProxySettings - { - - } -} - -namespace System.Application.Settings.Abstractions -{ - public abstract class ProxySettings : SettingsHost2 where TSettings : ProxySettings, new() + public sealed class ProxySettings : SettingsHost2 { /// /// 启用脚本自动检查更新 @@ -46,8 +38,32 @@ namespace System.Application.Settings.Abstractions public static SerializableProperty> ScriptsStatus { get; } = GetProperty(defaultValue: (IReadOnlyCollection)new List(), autoSave: true); + /// + /// 启用GOG插件代理 + /// + public static SerializableProperty IsProxyGOG { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 启用系统代理模式 + /// + public static SerializableProperty EnableWindowsProxy { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 是否只针对Steam内置浏览器启用脚本 + /// + public static SerializableProperty IsOnlyWorkSteamBrowser { get; } + = GetProperty(defaultValue: false, autoSave: true); + #region 代理设置 + /// + /// Host代理模式端口 + /// + public static SerializableProperty HostProxyPortId { get; } + = GetProperty(defaultValue: 443, autoSave: false); + /// /// 系统代理模式端口 /// diff --git a/src/ST.Client.Desktop/Settings/SteamAccountSettings.cs b/src/ST.Client/Settings/SteamAccountSettings.cs similarity index 100% rename from src/ST.Client.Desktop/Settings/SteamAccountSettings.cs rename to src/ST.Client/Settings/SteamAccountSettings.cs diff --git a/src/ST.Client.Desktop/Settings/SteamSettings.cs b/src/ST.Client/Settings/SteamSettings.cs similarity index 91% rename from src/ST.Client.Desktop/Settings/SteamSettings.cs rename to src/ST.Client/Settings/SteamSettings.cs index ed1d6046c..c3208fb78 100644 --- a/src/ST.Client.Desktop/Settings/SteamSettings.cs +++ b/src/ST.Client/Settings/SteamSettings.cs @@ -8,7 +8,7 @@ namespace System.Application.Settings IsRunSteamNoCheckUpdate.ValueChanged += IsRunSteamNoCheckUpdate_ValueChanged; } - private static void IsRunSteamNoCheckUpdate_ValueChanged(object? sender, ValueChangedEventArgs e) + static void IsRunSteamNoCheckUpdate_ValueChanged(object? sender, ValueChangedEventArgs e) { if (e.NewValue) SteamStratParameter.Value += " -noverifyfiles"; @@ -16,7 +16,7 @@ namespace System.Application.Settings SteamStratParameter.Value = SteamStratParameter.Value.Replace("-noverifyfiles", "").Trim(); } - private static void IsRunSteamMinimized_ValueChanged(object? sender, ValueChangedEventArgs e) + static void IsRunSteamMinimized_ValueChanged(object? sender, ValueChangedEventArgs e) { if (e.NewValue) SteamStratParameter.Value += " -silent"; diff --git a/src/ST.Client/Settings/UISettings.cs b/src/ST.Client/Settings/UISettings.cs index 92833b36c..b415ff856 100644 --- a/src/ST.Client/Settings/UISettings.cs +++ b/src/ST.Client/Settings/UISettings.cs @@ -1,30 +1,61 @@ using System; using System.Application.Models; +using System.Application.UI; using System.Application.UI.ViewModels; +using System.Application.Services; using System.Collections.Concurrent; using System.Collections.Generic; using System.Text; +using DynamicData; namespace System.Application.Settings { - internal sealed class UISettings : Abstractions.UISettings - { - - } -} - -namespace System.Application.Settings.Abstractions -{ - public abstract class UISettings : SettingsHost2 where TSettings : UISettings, new() + public sealed class UISettings : SettingsHost2 { static UISettings() { + //Theme.ValueChanged += Theme_ValueChanged; + AppGridSize.ValueChanged += AppGridSize_ValueChanged; + EnableDesktopBackground.ValueChanged += EnableDesktopBackground_ValueChanged; + if (WindowViewModel.IsSupportedSizePosition) { _WindowSizePositions = GetProperty(defaultValue: new ConcurrentDictionary(), autoSave: false); } } + static void EnableDesktopBackground_ValueChanged(object? sender, ValueChangedEventArgs e) + { + if (OperatingSystem2.IsWindows) + { + if (e.NewValue) + { + IApplication.Instance.SetDesktopBackgroundWindow(); + } + else + { + INativeWindowApiService.Instance.ResetWallerpaper(); + } + } + } + + static void AppGridSize_ValueChanged(object? sender, ValueChangedEventArgs e) + { + SteamConnectService.Current.SteamApps.Refresh(); + } + + //static void Theme_ValueChanged(object sender, ValueChangedEventArgs e) + //{ + // if (e.NewValue != e.OldValue) + // { + // var value = (AppTheme)e.NewValue; + // if (value.IsDefined()) + // { + // AppHelper.Current.Theme = value; + // } + // } + //} + /// /// 主题 /// @@ -48,5 +79,65 @@ namespace System.Application.Settings.Abstractions /// 所有窗口位置记忆字典集合 /// public static SerializableProperty> WindowSizePositions => _WindowSizePositions ?? throw new PlatformNotSupportedException(); + + /// + /// 字体 + /// + public static SerializableProperty FontName { get; } + = GetProperty(defaultValue: "Default", autoSave: true); + + /// + /// 窗口毛玻璃背景透明度 + /// + public static SerializableProperty AcrylicOpacity { get; } + = GetProperty(defaultValue: .8, autoSave: true); + + /// + /// 库存游戏封面大小 + /// + public static SerializableProperty AppGridSize { get; } + = GetProperty(defaultValue: 150, autoSave: true); + + /// + /// Steam账号备注替换名称显示 + /// + public static SerializableProperty SteamAccountRemarkReplaceName { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 启用圆角界面 + /// + public static SerializableProperty EnableFilletUI { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 启用动态桌面背景 + /// + public static SerializableProperty EnableDesktopBackground { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 启用自定义背景图片 + /// + public static SerializableProperty EnableCustomBackgroundImage { get; } + = GetProperty(defaultValue: false, autoSave: true); + + /// + /// 背景图片路径 + /// + public static SerializableProperty BackgroundImagePath { get; } + = GetProperty(defaultValue: "avares://System.Application.SteamTools.Client.Desktop.Avalonia/Application/UI/Assets/AppResources/Placeholders/0.png", autoSave: true); + + /// + /// 主题颜色(十六进制字符串) + /// + public static SerializableProperty ThemeAccent { get; } + = GetProperty(defaultValue: "#FF0078D7", autoSave: true); + + /// + /// 主题颜色从系统获取 + /// + public static SerializableProperty GetUserThemeAccent { get; } + = GetProperty(defaultValue: true, autoSave: true); } } diff --git a/src/ST.Client.Desktop/SevenZipHelper.cs b/src/ST.Client/SevenZipHelper.cs similarity index 100% rename from src/ST.Client.Desktop/SevenZipHelper.cs rename to src/ST.Client/SevenZipHelper.cs diff --git a/src/ST.Client.Desktop/SteamAppPropertyHelper.cs b/src/ST.Client/SteamAppPropertyHelper.cs similarity index 100% rename from src/ST.Client.Desktop/SteamAppPropertyHelper.cs rename to src/ST.Client/SteamAppPropertyHelper.cs diff --git a/src/ST.Client.Desktop/TarGZipHelper.cs b/src/ST.Client/TarGZipHelper.cs similarity index 100% rename from src/ST.Client.Desktop/TarGZipHelper.cs rename to src/ST.Client/TarGZipHelper.cs diff --git a/src/ST.Client.Desktop/Services/IDesktopApplication.cs b/src/ST.Client/UI/IApplication.Desktop.cs similarity index 71% rename from src/ST.Client.Desktop/Services/IDesktopApplication.cs rename to src/ST.Client/UI/IApplication.Desktop.cs index 7c3b219df..7b9563ffe 100644 --- a/src/ST.Client.Desktop/Services/IDesktopApplication.cs +++ b/src/ST.Client/UI/IApplication.Desktop.cs @@ -1,14 +1,14 @@ -using System.Application.Models; +using System; using System.Collections.Generic; +using System.Text; +using System.Application.Models; using System.Reactive.Disposables; using System.Windows.Input; -namespace System.Application.Services +namespace System.Application.UI { - public interface IDesktopApplication : IApplication, IClipboardPlatformService + partial interface IApplication { - new static IDesktopApplication Instance => DI.Get(); - /// /// 切换当前桌面应用的主题而不改变设置值 /// @@ -30,8 +30,6 @@ namespace System.Application.Services ///
IReadOnlyDictionary NotifyIconMenus { get; } - //bool IsCefInitComplete { get; } - CompositeDisposable CompositeDisposable { get; } /// @@ -41,10 +39,5 @@ namespace System.Application.Services bool HasActiveWindow(); void SetDesktopBackgroundWindow(); - - /// - /// 获取当前渲染子系统名称 - /// - string RenderingSubsystemName => string.Empty; } } diff --git a/src/ST.Client.Desktop/UI/AppHelper.cs b/src/ST.Client/UI/IApplication.Helper.cs similarity index 69% rename from src/ST.Client.Desktop/UI/AppHelper.cs rename to src/ST.Client/UI/IApplication.Helper.cs index 36ca59c76..70318056f 100644 --- a/src/ST.Client.Desktop/UI/AppHelper.cs +++ b/src/ST.Client/UI/IApplication.Helper.cs @@ -1,12 +1,24 @@ -using System.Application.Services; -using System.Diagnostics; -using System.IO; using System.Properties; +using System.IO; +using System.Diagnostics; +using System.Application.Services; namespace System.Application.UI { - public static partial class AppHelper + partial interface IApplication { + static readonly Lazy mType = new(() => Instance.GetType()); + public static AppType Type => mType.Value; + + /// + /// 是否使用移动端布局 + /// + public static bool IsMobileLayout => Type switch + { + AppType.Maui or AppType.PlatformUI_Android => true, + _ => false, + }; + public static bool EnableDevtools { get; set; } = ThisAssembly.Debuggable; /// @@ -19,7 +31,7 @@ namespace System.Application.UI /// public static bool UseOpenGL { get; set; } - static AppHelper() + static IApplication() { var mainModule = Process.GetCurrentProcess().MainModule; if (mainModule == null) @@ -43,11 +55,10 @@ namespace System.Application.UI /// public static string ProgramName { get; } - /// + /// public static void SetBootAutoStart(bool isAutoStart) { - var s = DI.Get(); - s.SetBootAutoStart(isAutoStart, Constants.HARDCODED_APP_NAME); + IPlatformService.Instance.SetBootAutoStart(isAutoStart, Constants.HARDCODED_APP_NAME); } } -} \ No newline at end of file +} diff --git a/src/ST.Client/Services/IApplication.cs b/src/ST.Client/UI/IApplication.Log.cs similarity index 89% rename from src/ST.Client/Services/IApplication.cs rename to src/ST.Client/UI/IApplication.Log.cs index 0d535bf11..eaf0cb940 100644 --- a/src/ST.Client/Services/IApplication.cs +++ b/src/ST.Client/UI/IApplication.Log.cs @@ -4,47 +4,18 @@ using Microsoft.Extensions.Options; using NLog.Config; using NLog.Extensions.Logging; using NLog.Targets; -using System.Application.Models; using System.IO; using System.Properties; +using System.Application.Services; using LogLevel = Microsoft.Extensions.Logging.LogLevel; using NInternalLogger = NLog.Common.InternalLogger; using NLogLevel = NLog.LogLevel; using NLogManager = NLog.LogManager; -namespace System.Application.Services +namespace System.Application.UI { - public interface IApplication + partial interface IApplication { - static IApplication Instance => DI.Get(); - - /// - /// 获取或设置当前应用的主题 - /// - AppTheme Theme { get; set; } - - /// - /// 获取当前应用的实际主题 - /// - AppTheme ActualTheme => Theme switch - { - AppTheme.FollowingSystem => GetActualThemeByFollowingSystem(), - AppTheme.Light => AppTheme.Light, - AppTheme.Dark => AppTheme.Dark, - _ => DefaultActualTheme, - }; - - /// - /// 获取当前应用的默认主题 - /// - protected AppTheme DefaultActualTheme { get; } - - /// - /// 获取当前应用主题跟随系统时的实际主题 - /// - /// - protected AppTheme GetActualThemeByFollowingSystem(); - #region Logger const LogLevel DefaultLoggerMinLevel = ThisAssembly.Debuggable ? LogLevel.Debug : LogLevel.Error; @@ -276,4 +247,4 @@ namespace System.Application.Services #endregion } -} \ No newline at end of file +} diff --git a/src/ST.Client/UI/IApplication.SingletonInstance.cs b/src/ST.Client/UI/IApplication.SingletonInstance.cs new file mode 100644 index 000000000..7c2517b1c --- /dev/null +++ b/src/ST.Client/UI/IApplication.SingletonInstance.cs @@ -0,0 +1,181 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.IO.Pipes; +using System.Linq; +using System.Security.Cryptography; +using System.Security.Principal; +using System.Threading; +using System.Threading.Tasks; + +namespace System.Application.UI +{ + partial interface IApplication + { + /// + /// 检测应用程序的多次启动以及在正在运行的实例之间发送和接收消息 + /// + sealed class SingletonInstance : IDisposable + { + private bool disposedValue; + + /// + /// 获取一个值,该值指示此实例是否是第一个要启动的实例 + /// + public bool IsFirst { get; } + + /// + /// 在接收新启动的实例的消息时发生 + /// + public event Action? MessageReceived; + + public SingletonInstance() + { + IsFirst = GetIsFirst(); + if (IsFirst) + { + Task.Run(RunPipeServer); + } + } + + static IEnumerable GetCurrentAllProcess() + { + var current = Process.GetCurrentProcess(); +#if DEBUG + if (string.Equals("dotnet", Path.GetFileNameWithoutExtension(current.MainModule?.FileName), StringComparison.OrdinalIgnoreCase)) + { + return Array.Empty(); + } +#endif + var currentMainModule = current.TryGetMainModule(); + var query = from p in Process.GetProcessesByName(current.ProcessName) + let pMainModule = p.TryGetMainModule() + where p.Id != current.Id && + p.ProcessName == current.ProcessName && + (currentMainModule == null || + (pMainModule != null && + pMainModule.FileName == currentMainModule.FileName && + pMainModule.ModuleName == currentMainModule.ModuleName)) + select p; + return query; + } + + public static bool TryKillCurrentAllProcess() + { + foreach (var p in GetCurrentAllProcess()) + { + try + { +#if NETSTANDARD + p.Kill(); +#else + p.Kill(true); +#endif + p.WaitForExit(500); + } + catch + { + } + } + return GetIsFirst(); + } + + static bool GetIsFirst() + { + var query = GetCurrentAllProcess(); + var r = query.Any(); + return !r; + } + + #region Pipes + + static string GetPipeName() => BuildConfig.APPLICATION_ID + "_" + Hashs.String.Crc32(ProgramPath); + + CancellationTokenSource? cts; + void RunPipeServer() + { + cts = new CancellationTokenSource(); + var name = GetPipeName(); + while (true) + { + using var pipeServer = new NamedPipeServerStream(name, PipeDirection.In, 1); + try + { + pipeServer.WaitForConnection(); + using var sr = new StreamReader(pipeServer); + //int i = 0; + try + { + var line = sr.ReadLine(); + //Console.WriteLine($"({i++})RunPipeServer line: {line ?? "null"}, name: {name}"); + if (line != null) + { + MessageReceived?.Invoke(line); + } + } + catch (IOException) + { + } + pipeServer.Close(); + cts.Token.ThrowIfCancellationRequested(); + } + catch (OperationCanceledException) + { + } + catch (Exception e) + { + Log.Error(nameof(SingletonInstance), e, nameof(RunPipeServer)); + return; + } + } + } + + /// + /// 给主进程发送消息 + /// + /// + public static bool SendMessage(string value) + { + var name = GetPipeName(); + try + { + using var pipeClient = new NamedPipeClientStream(".", name, PipeDirection.Out, PipeOptions.None, TokenImpersonationLevel.Impersonation); + pipeClient.Connect(1000); + using StreamWriter sw = new StreamWriter(pipeClient); + sw.WriteLine(value); + return true; + } + catch + { + return false; + } + } + + #endregion + + private void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + // TODO: 释放托管状态(托管对象) + cts?.Cancel(); + MessageReceived = null; + } + + // TODO: 释放未托管的资源(未托管的对象)并替代终结器 + // TODO: 将大型字段设置为 null + disposedValue = true; + } + } + + public void Dispose() + { + // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中 + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } + } +} diff --git a/src/ST.Client/UI/IApplication.cs b/src/ST.Client/UI/IApplication.cs new file mode 100644 index 000000000..fa1c18533 --- /dev/null +++ b/src/ST.Client/UI/IApplication.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Application.Models; +using System.Application.Services; + +namespace System.Application.UI +{ + /// + /// 当前应用程序 + /// + public partial interface IApplication : IService + { + /// + /// 获取或设置当前应用的主题 + /// + AppTheme Theme { get; set; } + + /// + /// 获取当前应用的实际主题 + /// + AppTheme ActualTheme => Theme switch + { + AppTheme.FollowingSystem => GetActualThemeByFollowingSystem(), + AppTheme.Light => AppTheme.Light, + AppTheme.Dark => AppTheme.Dark, + _ => DefaultActualTheme, + }; + + /// + /// 获取当前应用的默认主题 + /// + protected AppTheme DefaultActualTheme { get; } + + /// + /// 获取当前应用主题跟随系统时的实际主题 + /// + /// + protected AppTheme GetActualThemeByFollowingSystem(); + + protected AppType GetType(); + + enum AppType + { + /// + /// https://github.com/AvaloniaUI/Avalonia + /// + Avalonia = 1, + + /// + /// https://github.com/dotnet/maui + /// + Maui, + + /// + /// https://github.com/unoplatform/uno + /// + Uno, + + /// + /// https://developer.android.google.cn/training/basics/firstapp/building-ui + /// + PlatformUI_Android, + + /// + /// https://docs.microsoft.com/zh-cn/xamarin/ios/user-interface/ios-ui + /// + [Obsolete] + PlatformUI_iOS, + + /// + /// https://github.com/dotnet/winforms + /// + /// https://github.com/mono/winforms + /// + [Obsolete] + WindowsForms, + + /// + /// https://github.com/dotnet/wpf + /// + [Obsolete] + WinUI1_WPF, + + /// + /// https://github.com/Microsoft/microsoft-ui-xaml + /// + /// https://docs.microsoft.com/zh-cn/windows/apps/winui/winui2 + /// + [Obsolete] + WinUI2_UWP, + + [Obsolete] + WinUI3_UWP, + + /// + /// https://docs.microsoft.com/zh-cn/windows/apps/winui/winui3/desktop-winui3-app-with-basic-interop + /// + [Obsolete] + WinUI3_Desktop, + } + } +} \ No newline at end of file diff --git a/src/ST.Client/UI/Resx/AppResources.en.resx b/src/ST.Client/UI/Resx/AppResources.en.resx index dacfe4197..05ac99867 100644 --- a/src/ST.Client/UI/Resx/AppResources.en.resx +++ b/src/ST.Client/UI/Resx/AppResources.en.resx @@ -2061,4 +2061,148 @@ Ratings and reviews Comment=;Author=MicrosoftTranslator + + Checking ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Checking: {0}% + Comment=;Author=MicrosoftTranslator + + + Failed to create the certificate + Comment=Fail;Author=MicrosoftTranslator + + + Decompressing: {0}% + Comment=;Author=MicrosoftTranslator + + + Downloading ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Downloading: {0}% + Comment=;Author=MicrosoftTranslator + + + The download of the update package failed, please try again later + Comment=;Author=MicrosoftTranslator + + + It is currently the latest version + Comment=;Author=MicrosoftTranslator + + + The new version is updated + Comment=;Author=MicrosoftTranslator + + + The {0} version of Steam?v is updated + Comment=;Author=MicrosoftTranslator + + + Prompt notification when a new announcement is made. + Comment=;Author=MicrosoftTranslator + + + New version notifications + Comment=;Author=MicrosoftTranslator + + + Script dependency download error: {0} {1} + Comment=;Author=MicrosoftTranslator + + + Script binding error: {0} + Comment=;Author=MicrosoftTranslator + + + Cache file deletion failed: {0} + Comment=;Author=MicrosoftTranslator + + + The deletion failed + Comment=;Author=MicrosoftTranslator + + + The deletion was successful + Comment=;Author=MicrosoftTranslator + + + File deletion failed: {0} + Comment=;Author=MicrosoftTranslator + + + The script repeats + Comment=;Author=MicrosoftTranslator + + + Script: {0} file is missing and deleted + Comment=;Author=MicrosoftTranslator + + + Script: {0} file is missing, deletion fails to attempt to delete manually + Comment=;Author=MicrosoftTranslator + + + Program Exception The primary key is empty + Comment=;Author=MicrosoftTranslator + + + Script read exception Check syntax for errors: {0} + Comment=;Author=MicrosoftTranslator + + + There was an error saving the data + Comment=;Author=MicrosoftTranslator + + + The addition was successful + Comment=;Author=MicrosoftTranslator + + + Failed to download the update package, please open the official website to manually update + Comment=;Author=MicrosoftTranslator + + + The file check failed, please open the official website to manually update + Comment=;Author=MicrosoftTranslator + + + Prompt notifications when a new version is available and progress notifications when a new version is downloaded. + Comment=;Author=MicrosoftTranslator + + + Announcement notification + Comment=;Author=MicrosoftTranslator + + + The file property is read-only and the modification fails + Comment=;Author=MicrosoftTranslator + + + The file size is too large + Comment=;Author=MicrosoftTranslator + + + File access was denied without permission + Comment=;Author=MicrosoftTranslator + + + Action hosts error {0} + Comment=;Author=MicrosoftTranslator + + + Steam?replacement upgrade... + Comment=;Author=MicrosoftTranslator + + + The Steam installation path could not be found + Comment=;Author=MicrosoftTranslator + + + The update package unzip failed, please open the official website to manually update + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/AppResources.es.resx b/src/ST.Client/UI/Resx/AppResources.es.resx index 764391b72..2277b2725 100644 --- a/src/ST.Client/UI/Resx/AppResources.es.resx +++ b/src/ST.Client/UI/Resx/AppResources.es.resx @@ -2062,4 +2062,148 @@ Valoraciones y reseñas Comment=;Author=MicrosoftTranslator + + Comprobación ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Comprobación: {0}% + Comment=;Author=MicrosoftTranslator + + + No se pudo crear el certificado + Comment=Fail;Author=MicrosoftTranslator + + + Descompresión: {0}% + Comment=;Author=MicrosoftTranslator + + + Descarga ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Descarga: {0}% + Comment=;Author=MicrosoftTranslator + + + Error en la descarga del paquete de actualización, inténtelo de nuevo más tarde + Comment=;Author=MicrosoftTranslator + + + Actualmente es la última versión + Comment=;Author=MicrosoftTranslator + + + Se actualiza la nueva versión + Comment=;Author=MicrosoftTranslator + + + Se actualiza la versión de la versión de Steam-v{0} + Comment=;Author=MicrosoftTranslator + + + Notificación inmediata cuando se realiza un nuevo anuncio. + Comment=;Author=MicrosoftTranslator + + + .. \Resources\OpenSourceLibraryList.mpo; System.Byte[], mscorlib, versión = 4.0.0.0, referencia cultural = neutral, PublicKeyToken = b77a5c561934e089 + Comment=;Author=MicrosoftTranslator + + + Error de descarga de dependencia de script: {0} {1} + Comment=;Author=MicrosoftTranslator + + + Error de enlace de script: {0} + Comment=;Author=MicrosoftTranslator + + + Error al eliminar el archivo de caché: {0} + Comment=;Author=MicrosoftTranslator + + + Error al eliminar + Comment=;Author=MicrosoftTranslator + + + La eliminación se realizó correctamente + Comment=;Author=MicrosoftTranslator + + + Error al eliminar el archivo: {0} + Comment=;Author=MicrosoftTranslator + + + El script se repite + Comment=;Author=MicrosoftTranslator + + + Script: falta {0} archivo y se elimina + Comment=;Author=MicrosoftTranslator + + + Script: {0} falta el archivo, la eliminación no puede intentar eliminar manualmente + Comment=;Author=MicrosoftTranslator + + + Excepción de programa La clave principal está vacía + Comment=;Author=MicrosoftTranslator + + + Excepción de lectura de script Compruebe la sintaxis de los errores: {0} + Comment=;Author=MicrosoftTranslator + + + Se ha producido un error al guardar los datos + Comment=;Author=MicrosoftTranslator + + + La adición fue exitosa + Comment=;Author=MicrosoftTranslator + + + No se pudo descargar el paquete de actualización, abra el sitio web oficial para actualizar manualmente + Comment=;Author=MicrosoftTranslator + + + Error en la verificación de archivos, abra la actualización del manual del sitio web oficial + Comment=;Author=MicrosoftTranslator + + + Notificaciones de solicitud cuando hay una nueva versión disponible y notificaciones de progreso cuando se descarga una nueva versión. + Comment=;Author=MicrosoftTranslator + + + Notificación de anuncio + Comment=;Author=MicrosoftTranslator + + + La propiedad file es de sólo lectura y se produce un error en la modificación + Comment=;Author=MicrosoftTranslator + + + El tamaño del archivo es demasiado grande + Comment=;Author=MicrosoftTranslator + + + Se denegó el acceso a archivos sin permiso + Comment=;Author=MicrosoftTranslator + + + {0} de error de hosts de acción + Comment=;Author=MicrosoftTranslator + + + Actualización de reemplazo de Steam... + Comment=;Author=MicrosoftTranslator + + + No se pudo encontrar la ruta de instalación de Steam + Comment=;Author=MicrosoftTranslator + + + El paquete de actualización descomprimir falló, por favor abra el sitio web oficial para actualizar manualmente + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/AppResources.it.resx b/src/ST.Client/UI/Resx/AppResources.it.resx index 49aa492b3..1d34ebc3e 100644 --- a/src/ST.Client/UI/Resx/AppResources.it.resx +++ b/src/ST.Client/UI/Resx/AppResources.it.resx @@ -2062,4 +2062,148 @@ Sicuro di voler continuare? Valutazioni e recensioni Comment=;Author=MicrosoftTranslator + + Controllo ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Controllo: {0}% + Comment=;Author=MicrosoftTranslator + + + Impossibile creare il certificato + Comment=Fail;Author=MicrosoftTranslator + + + Decompressione: {0}% + Comment=;Author=MicrosoftTranslator + + + Download ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Download: {0}% + Comment=;Author=MicrosoftTranslator + + + Il download del pacchetto di aggiornamento non è riuscito, riprovare più tardi + Comment=;Author=MicrosoftTranslator + + + Attualmente è l'ultima versione + Comment=;Author=MicrosoftTranslator + + + La nuova versione viene aggiornata + Comment=;Author=MicrosoftTranslator + + + La versione di Steam-v{0} viene aggiornata + Comment=;Author=MicrosoftTranslator + + + Richiedi notifica quando viene fatto un nuovo annuncio. + Comment=;Author=MicrosoftTranslator + + + .. \Resources\OpenSourceLibraryList.mpo; System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + Comment=;Author=MicrosoftTranslator + + + Errore di download della dipendenza da script: {0} {1} + Comment=;Author=MicrosoftTranslator + + + Errore di associazione script: {0} + Comment=;Author=MicrosoftTranslator + + + Eliminazione file cache non riuscita: {0} + Comment=;Author=MicrosoftTranslator + + + Eliminazione non riuscita + Comment=;Author=MicrosoftTranslator + + + L'eliminazione è stata esito positivo + Comment=;Author=MicrosoftTranslator + + + Eliminazione file non riuscita: {0} + Comment=;Author=MicrosoftTranslator + + + Lo script si ripete + Comment=;Author=MicrosoftTranslator + + + Script: {0} file mancante ed eliminato + Comment=;Author=MicrosoftTranslator + + + Script: {0} file mancante, l'eliminazione non riesce a tentare di eliminarlo manualmente + Comment=;Author=MicrosoftTranslator + + + Eccezione programma La chiave primaria è vuota + Comment=;Author=MicrosoftTranslator + + + Eccezione di lettura script Controllare la sintassi degli errori: {0} + Comment=;Author=MicrosoftTranslator + + + Si è verificato un errore durante il salvataggio dei dati + Comment=;Author=MicrosoftTranslator + + + L'aggiunta ha avuto successo + Comment=;Author=MicrosoftTranslator + + + Impossibile scaricare il pacchetto di aggiornamento, aprire il sito Web ufficiale per aggiornare manualmente + Comment=;Author=MicrosoftTranslator + + + Verifica del file non riuscita, aprire l'aggiornamento manuale ufficiale del sito Web + Comment=;Author=MicrosoftTranslator + + + Richiedi notifiche quando è disponibile una nuova versione e notifiche sullo stato di avanzamento quando viene scaricata una nuova versione. + Comment=;Author=MicrosoftTranslator + + + Notifica annuncio + Comment=;Author=MicrosoftTranslator + + + La proprietà del file è di sola lettura e la modifica non riesce + Comment=;Author=MicrosoftTranslator + + + Le dimensioni del file sono troppo grandi + Comment=;Author=MicrosoftTranslator + + + L'accesso ai file è stato negato senza autorizzazione + Comment=;Author=MicrosoftTranslator + + + L'azione ospita l'{0} + Comment=;Author=MicrosoftTranslator + + + Steam?aggiornamento sostitutivo... + Comment=;Author=MicrosoftTranslator + + + Impossibile trovare il percorso di installazione di Steam + Comment=;Author=MicrosoftTranslator + + + Il pacchetto di aggiornamento decomprime non è riuscito, aprire il sito Web ufficiale per aggiornare manualmente + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/AppResources.ja.resx b/src/ST.Client/UI/Resx/AppResources.ja.resx index e73c64688..b75cada90 100644 --- a/src/ST.Client/UI/Resx/AppResources.ja.resx +++ b/src/ST.Client/UI/Resx/AppResources.ja.resx @@ -2057,4 +2057,148 @@ 採点&評価 Comment=;Author=MicrosoftTranslator + + 検証中 ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + 検証中: {0}% + Comment=;Author=MicrosoftTranslator + + + 証明書の作成に失敗しました + Comment=Fail;Author=MicrosoftTranslator + + + 解凍中: {0}% + Comment=;Author=MicrosoftTranslator + + + ダウンロード中 ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + ダウンロード中: {0}% + Comment=;Author=MicrosoftTranslator + + + アップデートパッケージのダウンロードに失敗しました。しばらくしてからもう一度お試しください + Comment=;Author=MicrosoftTranslator + + + 現在最新バージョン + Comment=;Author=MicrosoftTranslator + + + 新しいバージョンの更新 + Comment=;Author=MicrosoftTranslator + + + Steam++ v{0}更新されました + Comment=;Author=MicrosoftTranslator + + + 新しいアナウンスがある場合のプロンプト通知。 + Comment=;Author=MicrosoftTranslator + + + 新しいバージョンの通知 + Comment=;Author=MicrosoftTranslator + + + スクリプト依存ダウンロード エラー: [{0}]_{1} + Comment=;Author=MicrosoftTranslator + + + スクリプト バインド エラー: {0} + Comment=;Author=MicrosoftTranslator + + + キャッシュ ファイルの削除に失敗しました: {0} + Comment=;Author=MicrosoftTranslator + + + 削除に失敗しました + Comment=;Author=MicrosoftTranslator + + + 削除は成功しました + Comment=;Author=MicrosoftTranslator + + + ファイルの削除に失敗しました: {0} + Comment=;Author=MicrosoftTranslator + + + スクリプトが繰り返されます + Comment=;Author=MicrosoftTranslator + + + スクリプト: {0}_ファイルが見つからない場合は削除されました + Comment=;Author=MicrosoftTranslator + + + スクリプト: {0}_ファイルが見つからない場合、削除は手動で削除しようとして失敗します + Comment=;Author=MicrosoftTranslator + + + プログラム例外 主キーが空です + Comment=;Author=MicrosoftTranslator + + + スクリプトは例外を読み取り、構文にエラーがないか確認してください{0} + Comment=;Author=MicrosoftTranslator + + + データの保存中にエラーが発生しました + Comment=;Author=MicrosoftTranslator + + + 追加は成功しました + Comment=;Author=MicrosoftTranslator + + + 更新プログラム パッケージのダウンロードに失敗しました + Comment=;Author=MicrosoftTranslator + + + ファイルの確認に失敗しました。公式ウェブサイトを開いて手動で更新してください + Comment=;Author=MicrosoftTranslator + + + 新しいバージョンが利用可能になったときのプロンプト通知と、新しいバージョンがダウンロードされたときの進行状況の通知。 + Comment=;Author=MicrosoftTranslator + + + お知らせのお知らせ + Comment=;Author=MicrosoftTranslator + + + ファイルの属性が読み取り専用のため、修正に失敗 + Comment=;Author=MicrosoftTranslator + + + ファイルサイズが大きすぎる + Comment=;Author=MicrosoftTranslator + + + ファイル アクセスが拒否され、アクセス許可がありません + Comment=;Author=MicrosoftTranslator + + + 操作 hosts エラー{0} + Comment=;Author=MicrosoftTranslator + + + Steam++ は交換およびアップグレードされています... + Comment=;Author=MicrosoftTranslator + + + Steamインストールパスが見つかりませんでした + Comment=;Author=MicrosoftTranslator + + + 更新パッケージの解凍に失敗しました。公式Webサイトを開いて手動で更新してください + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/AppResources.ko.resx b/src/ST.Client/UI/Resx/AppResources.ko.resx index 07c82be57..2a0b02749 100644 --- a/src/ST.Client/UI/Resx/AppResources.ko.resx +++ b/src/ST.Client/UI/Resx/AppResources.ko.resx @@ -2057,4 +2057,148 @@ 점수&평가 Comment=;Author=MicrosoftTranslator + + 검증 중({1}/{2}):{0}% + Comment=;Author=MicrosoftTranslator + + + 확인 중: {0}% + Comment=;Author=MicrosoftTranslator + + + 인증서를 만들지 못했습니다 + Comment=Fail;Author=MicrosoftTranslator + + + 압축 해제 중: {0}% + Comment=;Author=MicrosoftTranslator + + + 다운로드 중({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + 다운로드 중: {0}% + Comment=;Author=MicrosoftTranslator + + + 업데이트 패키지를 다운로드하지 못했습니다 + Comment=;Author=MicrosoftTranslator + + + 현재 최신 버전입니다 + Comment=;Author=MicrosoftTranslator + + + 새 버전이 업데이트됩니다 + Comment=;Author=MicrosoftTranslator + + + Steam++ v{0} 업데이트됩니다 + Comment=;Author=MicrosoftTranslator + + + 새 공지가 있을 때 알림을 표시합니다. + Comment=;Author=MicrosoftTranslator + + + 새 버전 알림입니다 + Comment=;Author=MicrosoftTranslator + + + 스크립트 종속 다운로드 오류: [{0}]_{1} + Comment=;Author=MicrosoftTranslator + + + 스크립트 바인딩 오류: {0} + Comment=;Author=MicrosoftTranslator + + + 캐시 파일 삭제 실패: {0} + Comment=;Author=MicrosoftTranslator + + + 삭제에 실패했습니다 + Comment=;Author=MicrosoftTranslator + + + 삭제에 성공했습니다 + Comment=;Author=MicrosoftTranslator + + + 파일 삭제 실패: {0} + Comment=;Author=MicrosoftTranslator + + + 스크립트가 반복됩니다 + Comment=;Author=MicrosoftTranslator + + + 스크립트: {0}_파일 손실삭제가 삭제되었습니다 + Comment=;Author=MicrosoftTranslator + + + 스크립트: {0}_파일이 누락되어 삭제가 실패하여 수동으로 삭제를 시도합니다 + Comment=;Author=MicrosoftTranslator + + + 프로그램 예외 기본 키가 비어 있습니다 + Comment=;Author=MicrosoftTranslator + + + 스크립트 읽기 예외 구문에 오류가 있는지 확인합니다{0} + Comment=;Author=MicrosoftTranslator + + + 데이터를 저장하는 데 오류가 발생했습니다 + Comment=;Author=MicrosoftTranslator + + + 추가에 성공했습니다 + Comment=;Author=MicrosoftTranslator + + + 업데이트 패키지를 다운로드하지 못했습니다 + Comment=;Author=MicrosoftTranslator + + + 파일 유효성 검사에 실패했습니다. 공식 웹 사이트를 열어 수동으로 업데이트하십시오 + Comment=;Author=MicrosoftTranslator + + + 새 버전을 사용할 수 있는 경우 프롬프트 알림 및 새 버전을 다운로드할 때의 진행률 알림입니다. + Comment=;Author=MicrosoftTranslator + + + 공지 사항 + Comment=;Author=MicrosoftTranslator + + + 파일 속성이 읽기 전용이며 수정에 실패했습니다 + Comment=;Author=MicrosoftTranslator + + + 파일 크기가 너무 큽니다 + Comment=;Author=MicrosoftTranslator + + + 파일 액세스가 거부되고 권한이 없습니다 + Comment=;Author=MicrosoftTranslator + + + 작업 hosts 오류 {0} + Comment=;Author=MicrosoftTranslator + + + Steam++ 교체 업그레이드 중... + Comment=;Author=MicrosoftTranslator + + + Steam 설치 경로를 찾을 수 없습니다 + Comment=;Author=MicrosoftTranslator + + + 업데이트 패키지 압축을 풀지 못했습니다 + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/AppResources.resx b/src/ST.Client/UI/Resx/AppResources.resx index 8231bb124..ad5a58a71 100644 --- a/src/ST.Client/UI/Resx/AppResources.resx +++ b/src/ST.Client/UI/Resx/AppResources.resx @@ -1613,7 +1613,119 @@ 修复网络完成 + + 正在校验({1}/{2}):{0}% + + + 正在校验:{0}% + + + 创建证书失败 + Fail + + + 正在解压:{0}% + + + 正在下载({1}/{2}):{0}% + + + 正在下载:{0}% + + + 下载更新包失败,请稍后重试 + + + 文件属性为只读,修改失败 + + + 文件大小过大 + + + 文件访问被拒绝,没有权限 + + + 当前已是最新版本 + + + 新版本更新 + + + Steam++ v{0} 版本更新 + + + 当有新公告时的提示通知。 + + + 当有新版本可用时的提示通知与下载新版本时的进度通知。 + + + 公告通知 + + + 新版本通知 + + + 操作 hosts 错误 {0} + + + Steam++ 替换升级中... + + + 脚本依赖下载出错:[{0}]_{1} + + + 脚本绑定出错:{0} + + + 缓存文件删除失败:{0} + + + 删除失败 + + + 删除成功 + + + 文件删除失败:{0} + + + 脚本重复 + + + 脚本:{0}_文件丢失已删除 + + + 脚本:{0}_文件丢失,删除失败去尝试手动删除 + + + 程序异常 主键为空 + + + 脚本读取异常请检查语法是否有错误:{0} + + + 保存数据出错请重试 + + + 添加成功 + + + 找不到 Steam 安装路径 + + + 下载更新包失败,请打开官网手动更新 + + + 文件校验失败,请打开官网手动更新 + + + 更新包解压失败,请打开官网手动更新 + 全部启用 + + 在Steam客户端中查看 + \ No newline at end of file diff --git a/src/ST.Client/UI/Resx/AppResources.ru.resx b/src/ST.Client/UI/Resx/AppResources.ru.resx index e3e3b6a2a..35719246e 100644 --- a/src/ST.Client/UI/Resx/AppResources.ru.resx +++ b/src/ST.Client/UI/Resx/AppResources.ru.resx @@ -2057,4 +2057,148 @@ Оценка и оценка Comment=;Author=MicrosoftTranslator + + Проверка ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Проверка: {0}% + Comment=;Author=MicrosoftTranslator + + + Не удалось создать сертификат + Comment=Fail;Author=MicrosoftTranslator + + + Распаковка: {0}% + Comment=;Author=MicrosoftTranslator + + + Загрузка ({1}/{2}): {0}% + Comment=;Author=MicrosoftTranslator + + + Загрузка: {0}% + Comment=;Author=MicrosoftTranslator + + + Не удалось загрузить пакет обновления, повторите попытку позже + Comment=;Author=MicrosoftTranslator + + + В настоящее время это последняя версия + Comment=;Author=MicrosoftTranslator + + + Обновление новой версии + Comment=;Author=MicrosoftTranslator + + + Обновление версии Steam++ {0} версии + Comment=;Author=MicrosoftTranslator + + + Уведомление о подсказке при появлении нового объявления. + Comment=;Author=MicrosoftTranslator + + + Уведомление о новой версии + Comment=;Author=MicrosoftTranslator + + + Сценарий зависит от ошибки загрузки: [{0}]_{1} + Comment=;Author=MicrosoftTranslator + + + Ошибка привязки скрипта: {0} + Comment=;Author=MicrosoftTranslator + + + Сбой удаления кэшированных файлов: {0} + Comment=;Author=MicrosoftTranslator + + + Не удалось удалить + Comment=;Author=MicrosoftTranslator + + + Удаление выполнено успешно + Comment=;Author=MicrosoftTranslator + + + Сбой удаления файла: {0} + Comment=;Author=MicrosoftTranslator + + + Сценарий повторяется + Comment=;Author=MicrosoftTranslator + + + Сценарий: {0} файл был удален + Comment=;Author=MicrosoftTranslator + + + Сценарий: {0} файл отсутствует, удаление завершается неудачей, чтобы попытаться удалить вручную + Comment=;Author=MicrosoftTranslator + + + Основной ключ исключения программы пуст + Comment=;Author=MicrosoftTranslator + + + Сценарий читает исключение, проверьте синтаксис на наличие ошибок: {0} + Comment=;Author=MicrosoftTranslator + + + Повторите попытку, если сохраненные данные неверна + Comment=;Author=MicrosoftTranslator + + + Добавление выполнено успешно + Comment=;Author=MicrosoftTranslator + + + Не удалось загрузить пакет обновления, откройте официальный сайт для обновления вручную + Comment=;Author=MicrosoftTranslator + + + Проверка файлов завершается неудачей, откройте официальный сайт, чтобы обновить вручную + Comment=;Author=MicrosoftTranslator + + + Уведомление о ходе выполнения при загрузке новой версии, когда доступна новая версия. + Comment=;Author=MicrosoftTranslator + + + Уведомление о объявлении + Comment=;Author=MicrosoftTranslator + + + Свойства файла доступен только для чтения, и изменение завершается неудачей + Comment=;Author=MicrosoftTranslator + + + Размер файла слишком большой + Comment=;Author=MicrosoftTranslator + + + Доступ к файлам отклоняется без разрешений + Comment=;Author=MicrosoftTranslator + + + Ошибка действия hosts {0} + Comment=;Author=MicrosoftTranslator + + + В обновлении замены Steam++ ... + Comment=;Author=MicrosoftTranslator + + + Не удалось найти путь установки Steam + Comment=;Author=MicrosoftTranslator + + + Пакет обновления не удалось распаковки, пожалуйста, откройте официальный сайт для обновления вручную + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/AppResources.zh-Hant.resx b/src/ST.Client/UI/Resx/AppResources.zh-Hant.resx index d7d153c8a..f3a01abde 100644 --- a/src/ST.Client/UI/Resx/AppResources.zh-Hant.resx +++ b/src/ST.Client/UI/Resx/AppResources.zh-Hant.resx @@ -2057,4 +2057,148 @@ 打分&評價 Comment=;Author=MicrosoftTranslator + + 正在驗證({1}/{2}):{0}% + Comment=;Author=MicrosoftTranslator + + + 正在檢查:{0}% + Comment=;Author=MicrosoftTranslator + + + 建立證書失敗 + Comment=Fail;Author=MicrosoftTranslator + + + 解壓:{0}% + Comment=;Author=MicrosoftTranslator + + + 下載({1}/{2}):{0}% + Comment=;Author=MicrosoftTranslator + + + 正在下載:{0}% + Comment=;Author=MicrosoftTranslator + + + 下載更新包失敗,請稍後重試 + Comment=;Author=MicrosoftTranslator + + + 當前已是最新版本 + Comment=;Author=MicrosoftTranslator + + + 新版本更新 + Comment=;Author=MicrosoftTranslator + + + Steam++ v{0} 版本更新 + Comment=;Author=MicrosoftTranslator + + + 當有新公告時的提示通知。 + Comment=;Author=MicrosoftTranslator + + + 新版本通知 + Comment=;Author=MicrosoftTranslator + + + 腳本依賴下載出錯:[{0}]_{1} + Comment=;Author=MicrosoftTranslator + + + 文本繫結錯誤:{0} + Comment=;Author=MicrosoftTranslator + + + 快取檔案刪除失敗:{0} + Comment=;Author=MicrosoftTranslator + + + 刪除失敗 + Comment=;Author=MicrosoftTranslator + + + 刪除成功 + Comment=;Author=MicrosoftTranslator + + + 檔案刪除失敗:{0} + Comment=;Author=MicrosoftTranslator + + + 腳本重複 + Comment=;Author=MicrosoftTranslator + + + 文本:{0}_檔丟失已刪除 + Comment=;Author=MicrosoftTranslator + + + 文本:{0}_檔丟失,刪除失敗去嘗試手動刪除 + Comment=;Author=MicrosoftTranslator + + + 程序異常 主鍵為空 + Comment=;Author=MicrosoftTranslator + + + 文稿讀取異常請檢查語法是否有錯誤:{0} + Comment=;Author=MicrosoftTranslator + + + 保存數據出錯請重試 + Comment=;Author=MicrosoftTranslator + + + 添加成功 + Comment=;Author=MicrosoftTranslator + + + 下載更新包失敗,請打開官網手動更新 + Comment=;Author=MicrosoftTranslator + + + 文件校驗失敗,請打開官網手動更新 + Comment=;Author=MicrosoftTranslator + + + 當有新版本可用時的提示通知與下載新版本時的進度通知。 + Comment=;Author=MicrosoftTranslator + + + 公告通知 + Comment=;Author=MicrosoftTranslator + + + 文件屬性為只讀,修改失敗 + Comment=;Author=MicrosoftTranslator + + + 文件大小過大 + Comment=;Author=MicrosoftTranslator + + + 檔案訪問被拒絕,沒有許可權 + Comment=;Author=MicrosoftTranslator + + + 操作 hosts 錯誤 {0} + Comment=;Author=MicrosoftTranslator + + + Steam++ 替換升級中... + Comment=;Author=MicrosoftTranslator + + + 找不到 Steam 安裝路徑 + Comment=;Author=MicrosoftTranslator + + + 更新包解壓失敗,請打開官網手動更新 + Comment=;Author=MicrosoftTranslator + diff --git a/src/ST.Client/UI/Resx/R.cs b/src/ST.Client/UI/Resx/R.cs index f8a1736b3..7e59b76cc 100644 --- a/src/ST.Client/UI/Resx/R.cs +++ b/src/ST.Client/UI/Resx/R.cs @@ -1,41 +1,21 @@ using ReactiveUI; using System.Application.Services; using System.Application.UI.ViewModels; -using System.Application.UI.ViewModels.Abstractions; using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Linq; -using System.Properties; using System.Reactive.Linq; -using Interface = System.Application.UI.Resx.R; -using BaseClass = System.Application.UI.Resx.Abstractions.R; -using static System.Application.UI.Resx.R; namespace System.Application.UI.Resx { -#pragma warning disable IDE1006 // 命名样式 - internal interface R : IReactiveObject -#pragma warning restore IDE1006 // 命名样式 + public sealed class R : MvvmService { - static BaseClass Current => mCurrent is BaseClass i ? i : throw new NullReferenceException("R is null."); - - static BaseClass? mCurrent; - } -} - -namespace System.Application.UI.Resx.Abstractions -{ - public abstract class R : ReactiveObject, Interface - { - public static BaseClass Current => Interface.Current; - public static readonly IReadOnlyCollection> Languages; public static readonly Dictionary SteamLanguages; static readonly Lazy>> mFonts = new(() => IFontManager.Instance.GetFonts()); public static IReadOnlyCollection> Fonts => mFonts.Value; - public AppResources Res { get; protected set; } = new(); + public AppResources Res { get; private set; } = new(); public static CultureInfo DefaultCurrentUICulture { get; private set; } @@ -193,18 +173,4 @@ namespace System.Application.UI.Resx.Abstractions public static CultureInfo Culture => AppResources.Culture ?? DefaultCurrentUICulture; } - - public abstract class R : BaseClass where T : R, new() - { - public static T Current - { - get => ((T)Interface.Current)!; - protected set => Interface.mCurrent = value; - } - - static R() - { - Current = new(); - } - } } \ No newline at end of file diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/DebugPageViewModel.cs b/src/ST.Client/UI/ViewModels/Abstractions/Pages/DebugPageViewModel.cs deleted file mode 100644 index 34ea9baf5..000000000 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/DebugPageViewModel.cs +++ /dev/null @@ -1,24 +0,0 @@ -using ReactiveUI; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.IO.Pipes; -using System.Linq; -using System.Security; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ - public partial class DebugPageViewModel - { - public DebugPageViewModel() - { - } - } -} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/GameListPageViewModel.cs b/src/ST.Client/UI/ViewModels/Abstractions/Pages/GameListPageViewModel.cs deleted file mode 100644 index 35bfed527..000000000 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/GameListPageViewModel.cs +++ /dev/null @@ -1,25 +0,0 @@ -using ReactiveUI; -using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.IO; -using System.IO.Pipes; -using System.Linq; -using System.Security; -using System.Security.Cryptography.X509Certificates; -using System.Text; -using System.Threading; -using System.Threading.Tasks; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ - public partial class GameListPageViewModel - { - public GameListPageViewModel() - { - _IconKey = nameof(GameListPageViewModel); - } - } -} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/Settings/SettingsPageViewModel.cs b/src/ST.Client/UI/ViewModels/Abstractions/Pages/Settings/SettingsPageViewModel.cs deleted file mode 100644 index 8ec646e63..000000000 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/Settings/SettingsPageViewModel.cs +++ /dev/null @@ -1,98 +0,0 @@ -using DynamicData.Binding; -using ReactiveUI; -using System.Application.Settings; -using System.Application.Services; -using System.Application.UI.Resx; -using System.Collections.Generic; -using System.Linq; -using System.Reactive.Linq; -using System.Threading; -using System.Threading.Tasks; -using R = System.Application.UI.Resx.Abstractions.R; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ - public partial class SettingsPageViewModel - { - public SettingsPageViewModel() - { - IconKey = nameof(SettingsPageViewModel); - - - SelectLanguage = R.Languages.FirstOrDefault(x => x.Key == UISettings.Language.Value); - this.WhenValueChanged(x => x.SelectLanguage, false) - .Subscribe(x => UISettings.Language.Value = x.Key); - - UpdateChannels = Enum2.GetAll(); - } - - public static SettingsPageViewModel Instance => DI.Get(); - - KeyValuePair _SelectLanguage; - public KeyValuePair SelectLanguage - { - get => _SelectLanguage; - set => this.RaiseAndSetIfChanged(ref _SelectLanguage, value); - } - - IReadOnlyCollection? _UpdateChannels; - public IReadOnlyCollection? UpdateChannels - { - get => _UpdateChannels; - set => this.RaiseAndSetIfChanged(ref _UpdateChannels, value); - } - - public static string[] GetThemes() => new[] - { - AppResources.Settings_UI_SystemDefault, - AppResources.Settings_UI_Light, - AppResources.Settings_UI_Dark, - }; - - /// - /// 开始计算指定文件夹大小 - /// - /// - /// - /// - public static void StartCacheSizeCalc(ref bool isStartCacheSizeCalc, string sizeFormat, Action action, CancellationToken cancellationToken = default) - { - if (isStartCacheSizeCalc) return; - isStartCacheSizeCalc = true; - action(AppResources.Settings_General_Calcing); - string? dirPath; - if (sizeFormat == AppResources.Settings_General_CacheSize) - { - dirPath = IOPath.CacheDirectory; - } - else if (sizeFormat == AppResources.Settings_General_LogSize) - { - dirPath = IApplication.LogDirPath; - } - else - { - dirPath = null; - } - if (dirPath != null) - { - try - { - Task.Run(async () => - { - var length = IOPath.GetDirectorySize(dirPath); - var lenString = IOPath.GetSizeString(length); - await MainThread2.InvokeOnMainThreadAsync(() => - { - action(sizeFormat.Format(lenString)); - }); - }, cancellationToken); - } - catch (OperationCanceledException) - { - - } - } - } - } -} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/SteamAccountPageViewModel.cs b/src/ST.Client/UI/ViewModels/Abstractions/Pages/SteamAccountPageViewModel.cs deleted file mode 100644 index 752f5d8b6..000000000 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/SteamAccountPageViewModel.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Application.UI.Resx; - -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ - public partial class SteamAccountPageViewModel - { - public SteamAccountPageViewModel() - { - IconKey = nameof(SteamAccountPageViewModel); - } - } -} diff --git a/src/ST.Client/UI/ViewModels/AreaUIHelper.cs b/src/ST.Client/UI/ViewModels/AreaUIHelper.cs index 10662651e..1313ced66 100644 --- a/src/ST.Client/UI/ViewModels/AreaUIHelper.cs +++ b/src/ST.Client/UI/ViewModels/AreaUIHelper.cs @@ -246,11 +246,7 @@ namespace System.Application.UI.ViewModels /// public static IReadOnlyList Group2 => mGroup2.Value; } -} -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ partial class UserProfileWindowViewModel : AreaUIHelper.IViewModelField { IReadOnlyList? _AreaItems2; diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Base/ITextBoxWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Base/ITextBoxWindowViewModel.cs similarity index 100% rename from src/ST.Client/UI/ViewModels/Abstractions/Base/ITextBoxWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Base/ITextBoxWindowViewModel.cs diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Base/IViewModelBase.cs b/src/ST.Client/UI/ViewModels/Base/IViewModelBase.cs similarity index 90% rename from src/ST.Client/UI/ViewModels/Abstractions/Base/IViewModelBase.cs rename to src/ST.Client/UI/ViewModels/Base/IViewModelBase.cs index b299ea477..0c0659732 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Base/IViewModelBase.cs +++ b/src/ST.Client/UI/ViewModels/Base/IViewModelBase.cs @@ -20,7 +20,5 @@ namespace System.Application.UI.ViewModels /// 是否在设计器的上下文中运行 /// public static bool IsInDesignMode { protected get; set; } = true; - - public static bool IsMobile { get; } = IPlatformService.Instance.IsMobile; } } diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Base/RIdTitleIconViewModel.cs b/src/ST.Client/UI/ViewModels/Base/RIdTitleIconViewModel.cs similarity index 100% rename from src/ST.Client/UI/ViewModels/Abstractions/Base/RIdTitleIconViewModel.cs rename to src/ST.Client/UI/ViewModels/Base/RIdTitleIconViewModel.cs diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Base/TabItemViewModel.cs b/src/ST.Client/UI/ViewModels/Base/TabItemViewModel.cs similarity index 100% rename from src/ST.Client/UI/ViewModels/Abstractions/Base/TabItemViewModel.cs rename to src/ST.Client/UI/ViewModels/Base/TabItemViewModel.cs diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Base/ViewModelBase.cs b/src/ST.Client/UI/ViewModels/Base/ViewModelBase.cs similarity index 93% rename from src/ST.Client/UI/ViewModels/Abstractions/Base/ViewModelBase.cs rename to src/ST.Client/UI/ViewModels/Base/ViewModelBase.cs index 0056b1b8a..e6e268f08 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Base/ViewModelBase.cs +++ b/src/ST.Client/UI/ViewModels/Base/ViewModelBase.cs @@ -16,9 +16,6 @@ namespace System.Application.UI.ViewModels /// public static bool IsInDesignMode => IViewModelBase.IsInDesignMode; - /// - public static bool IsMobile => IViewModelBase.IsMobile; - public ViewModelActivator Activator { get; } public ViewModelBase() diff --git a/src/ST.Client/UI/ViewModels/Abstractions/CustomTabItemViewModel.cs b/src/ST.Client/UI/ViewModels/CustomTabItemViewModel.cs similarity index 81% rename from src/ST.Client/UI/ViewModels/Abstractions/CustomTabItemViewModel.cs rename to src/ST.Client/UI/ViewModels/CustomTabItemViewModel.cs index c87d6320e..a726620ba 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/CustomTabItemViewModel.cs +++ b/src/ST.Client/UI/ViewModels/CustomTabItemViewModel.cs @@ -3,6 +3,7 @@ using System.Application.UI.Resx; using System.Collections.Generic; using System.Text; +// ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { public abstract class TabItemViewModel : TabItemViewModel @@ -20,12 +21,8 @@ namespace System.Application.UI.ViewModels About, } } -} -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ - abstract partial class StartPageViewModel : TabItemViewModel + partial class StartPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.Welcome; @@ -36,7 +33,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class CommunityProxyPageViewModel : TabItemViewModel + partial class CommunityProxyPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.CommunityFix; @@ -49,7 +46,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class ProxyScriptManagePageViewModel : TabItemViewModel + partial class ProxyScriptManagePageViewModel : TabItemViewModel { public static string DisplayName => AppResources.ScriptConfig; @@ -62,7 +59,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class SteamAccountPageViewModel : TabItemViewModel + partial class SteamAccountPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.UserFastChange; @@ -75,7 +72,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class GameListPageViewModel : TabItemViewModel + partial class GameListPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.GameList; @@ -88,7 +85,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class LocalAuthPageViewModel : TabItemViewModel + partial class LocalAuthPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.LocalAuth; @@ -101,7 +98,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class ArchiSteamFarmPlusPageViewModel : TabItemViewModel + partial class ArchiSteamFarmPlusPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.ArchiSteamFarmPlus; @@ -114,7 +111,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class SettingsPageViewModel : TabItemViewModel + partial class SettingsPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.Settings; @@ -127,7 +124,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class AboutPageViewModel : TabItemViewModel + partial class AboutPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.About; @@ -140,7 +137,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class SteamIdlePageViewModel : TabItemViewModel + partial class SteamIdlePageViewModel : TabItemViewModel { public static string DisplayName => AppResources.IdleCard; @@ -151,7 +148,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class OtherPlatformPageViewModel : TabItemViewModel + partial class OtherPlatformPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.OtherGamePlaform; @@ -162,7 +159,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class DebugPageViewModel : TabItemViewModel + partial class DebugPageViewModel : TabItemViewModel { public const string DisplayName = "Debug"; @@ -173,7 +170,7 @@ namespace System.Application.UI.ViewModels.Abstractions } } - abstract partial class GameRelatedPageViewModel : TabItemViewModel + partial class GameRelatedPageViewModel : TabItemViewModel { public static string DisplayName => AppResources.GameRelated; diff --git a/src/ST.Client/UI/ViewModels/FastLRBHelper.cs b/src/ST.Client/UI/ViewModels/FastLRBHelper.cs index c5c9bf951..cb3ca4467 100644 --- a/src/ST.Client/UI/ViewModels/FastLRBHelper.cs +++ b/src/ST.Client/UI/ViewModels/FastLRBHelper.cs @@ -218,11 +218,7 @@ namespace System.Application.UI.ViewModels await Browser2.OpenAsync(url); } } -} -// ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions -{ partial class LoginOrRegisterWindowViewModel : IViewModel { WebSocketServer? IViewModel.WebSocketServer { get; set; } diff --git a/src/ST.Client/UI/ViewModels/General/PageViewModel.cs b/src/ST.Client/UI/ViewModels/General/PageViewModel.cs index 5bc0e159e..fc63d6a09 100644 --- a/src/ST.Client/UI/ViewModels/General/PageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/General/PageViewModel.cs @@ -13,21 +13,21 @@ namespace System.Application.UI.ViewModels { protected string title = string.Empty; [IgnoreDataMember] - public string Title + public virtual string Title { get => title; set => this.RaiseAndSetIfChanged(ref title, value); } - protected string GetTitleByDisplayName(string displayName) + protected static string GetTitleByDisplayName(string displayName) { - if (IsMobile) + if (IApplication.Type == IApplication.AppType.Avalonia) { - return displayName; + return Constants.HARDCODED_APP_NAME + " | " + displayName; } else { - return ThisAssembly.AssemblyTrademark + " | " + displayName; + return displayName; } } @@ -37,25 +37,5 @@ namespace System.Application.UI.ViewModels public virtual void Initialize() { } - - protected readonly IWindowManager windowManager = IWindowManager.Instance; - - [IgnoreDataMember] - public bool IsVisible => windowManager.IsVisibleWindow(this); - - /// - /// 关闭当前 ViewModel 绑定的窗口 - /// - public virtual void Close() => windowManager.CloseWindow(this); - - /// - /// 显示当前 ViewModel 绑定的窗口 - /// - public virtual void Show() => windowManager.ShowWindow(this); - - /// - /// 隐藏当前 ViewModel 绑定的窗口 - /// - public virtual void Hide() => windowManager.HideWindow(this); } } diff --git a/src/ST.Client/UI/ViewModels/General/WindowViewModel.cs b/src/ST.Client/UI/ViewModels/General/WindowViewModel.cs index e0461364b..4f221fe99 100644 --- a/src/ST.Client/UI/ViewModels/General/WindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/General/WindowViewModel.cs @@ -4,6 +4,7 @@ using System.Application.Models; using System.Application.Services; using System.Application.Settings; using System.Collections.Generic; +using System.Runtime.Serialization; using System.Text; // ReSharper disable once CheckNamespace @@ -48,5 +49,25 @@ namespace System.Application.UI.ViewModels }); } } + + protected readonly IWindowManager windowManager = IWindowManager.Instance; + + [IgnoreDataMember] + public bool IsVisible => windowManager.IsVisibleWindow(this); + + /// + /// 关闭当前 ViewModel 绑定的窗口 + /// + public virtual void Close() => windowManager.CloseWindow(this); + + /// + /// 显示当前 ViewModel 绑定的窗口 + /// + public virtual void Show() => windowManager.ShowWindow(this); + + /// + /// 隐藏当前 ViewModel 绑定的窗口 + /// + public virtual void Hide() => windowManager.HideWindow(this); } } diff --git a/src/ST.Client/UI/ViewModels/Abstractions/MainWindowViewModel.TabItems.cs b/src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs similarity index 96% rename from src/ST.Client/UI/ViewModels/Abstractions/MainWindowViewModel.TabItems.cs rename to src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs index ccf5f8ae2..45ec47671 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/MainWindowViewModel.TabItems.cs +++ b/src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { partial class MainWindowViewModel { @@ -39,7 +39,7 @@ namespace System.Application.UI.ViewModels.Abstractions //AddTabItem(); #if !TRAY_INDEPENDENT_PROGRAM - if (AppHelper.EnableDevtools) + if (IApplication.EnableDevtools) { AddTabItem(); //FooterTabItems.Add(new DebugPageViewModel().AddTo(this)); diff --git a/src/ST.Client/UI/ViewModels/Abstractions/MainWindowViewModel.cs b/src/ST.Client/UI/ViewModels/MainWindowViewModel.cs similarity index 98% rename from src/ST.Client/UI/ViewModels/Abstractions/MainWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/MainWindowViewModel.cs index 7f2e05d37..abbca8add 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/MainWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/MainWindowViewModel.cs @@ -7,7 +7,7 @@ using System.Reactive; using System.Threading.Tasks; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class MainWindowViewModel : WindowViewModel { diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/About/AboutPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/About/AboutPageViewModel.cs similarity index 97% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/About/AboutPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/About/AboutPageViewModel.cs index b4e80fb93..614f5ceea 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/About/AboutPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/About/AboutPageViewModel.cs @@ -7,10 +7,12 @@ using System.Reactive; using System.Runtime.InteropServices; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class AboutPageViewModel { + public static AboutPageViewModel Instance { get; } = new(); + public ReactiveCommand CheckUpdateCommand { get; } public ReactiveCommand OpenBrowserCommand { get; } diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/ArchiSteamFarmPlusPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/ArchiSteamFarmPlusPageViewModel.cs similarity index 68% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/ArchiSteamFarmPlusPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/ArchiSteamFarmPlusPageViewModel.cs index 288a9d2dd..0784c4e63 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/ArchiSteamFarmPlusPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/ArchiSteamFarmPlusPageViewModel.cs @@ -1,3 +1,4 @@ +using ArchiSteamFarm.Localization; using ArchiSteamFarm.Steam; using DynamicData; using DynamicData.Binding; @@ -5,10 +6,11 @@ using ReactiveUI; using System.Application.Services; using System.Application.UI.Resx; using System.Collections.ObjectModel; +using System.Globalization; using System.Reactive.Linq; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class ArchiSteamFarmPlusPageViewModel { @@ -50,5 +52,19 @@ namespace System.Application.UI.ViewModels.Abstractions { IWindowManager.Instance.Show(CustomWindow.ASF_AddBot, resizeMode: ResizeMode.CanResize); } + + public async void PauseOrResumeBotFarming(Bot bot) + { + if (bot.CardsFarmer.Paused) + { + (bool success, string message) = await bot.Actions.Pause(true).ConfigureAwait(false); + Toast.Show(success ? message : string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, message)); + } + else + { + (bool success, string message) = bot.Actions.Resume(); + Toast.Show(success ? message : string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, message)); + } + } } } diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/CommunityProxyPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs similarity index 92% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/CommunityProxyPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs index 1406e3bf7..3e008db95 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/CommunityProxyPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs @@ -15,10 +15,13 @@ using System.Reactive.Linq; using System.Threading.Tasks; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class CommunityProxyPageViewModel { + readonly IHostsFileService hostsFileService = IHostsFileService.Instance; + readonly IPlatformService platformService = IPlatformService.Instance; + public ReactiveCommand SetupCertificateCommand { get; } public ReactiveCommand DeleteCertificateCommand { get; } @@ -58,7 +61,11 @@ namespace System.Application.UI.ViewModels.Abstractions //{ // AutoRunProxy?.CheckmarkChange(ProxySettings.ProgramStartupRunProxy.Value = !ProxySettings.ProgramStartupRunProxy.Value); //}); - OpenCertificateDirCommand = ReactiveCommand.Create(OpenCertificateDir); + OpenCertificateDirCommand = ReactiveCommand.Create(() => + { + const string fileName = "SteamTools.Certificate.cer"; + platformService.OpenFolder(Path.Combine(IOPath.AppDataDirectory, fileName)); + }); ProxySettingsCommand = ReactiveCommand.Create(() => { IWindowManager.Instance.Show(CustomWindow.ProxySettings, resizeMode: ResizeMode.CanResize); @@ -154,8 +161,6 @@ namespace System.Application.UI.ViewModels.Abstractions public void EditHostsFile_OnClick() => EditHostsFile(); - protected abstract void OpenCertificateDir(); - - protected abstract void EditHostsFile(); + void EditHostsFile() => hostsFileService.OpenFile(); } } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs similarity index 93% rename from src/ST.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs index 15f42345c..5e0c5b645 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/DebugPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/DebugPageViewModel.cs @@ -10,7 +10,6 @@ using System.Application.UI.Resx; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; -using System.Drawing.Text; using System.Globalization; using System.IO; using System.IO.Pipes; @@ -25,9 +24,9 @@ using static Newtonsoft.Json.JsonConvert; // ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - partial class DebugPageViewModel + public partial class DebugPageViewModel { - private string _DebugString = string.Empty; + string _DebugString = string.Empty; public string DebugString { get => _DebugString; @@ -87,6 +86,15 @@ namespace System.Application.UI.ViewModels } } + static IEnumerable GetCertificates(X509Store store) + { +#if NETSTANDARD + return store.Certificates.Cast(); +#else + return store.Certificates; +#endif + } + public async void DebugButton_Click1() { Toast.Show(DateTime.Now.ToString()); @@ -121,18 +129,18 @@ namespace System.Application.UI.ViewModels @string.AppendFormatLine("{1}: {0}", Environment.GetFolderPath(folder), folder); } - var dps = DI.Get(); - @string.AppendFormatLine("SteamDirPath: {0}", dps.GetSteamDirPath()); - @string.AppendFormatLine("SteamProgramPath: {0}", dps.GetSteamProgramPath()); - @string.AppendFormatLine("LastSteamLoginUserName: {0}", dps.GetLastSteamLoginUserName()); + var platformS = DI.Get(); + @string.AppendFormatLine("SteamDirPath: {0}", platformS.GetSteamDirPath()); + @string.AppendFormatLine("SteamProgramPath: {0}", platformS.GetSteamProgramPath()); + @string.AppendFormatLine("LastSteamLoginUserName: {0}", platformS.GetLastSteamLoginUserName()); - (byte[] key, byte[] iv) = dps.MachineSecretKey; + (byte[] key, byte[] iv) = platformS.MachineSecretKey; @string.AppendFormatLine("MachineSecretKey.key: {0}", key.Base64UrlEncode()); @string.AppendFormatLine("MachineSecretKey.iv: {0}", iv.Base64UrlEncode()); - @string.AppendFormatLine("X509Store My: {0}", string.Join(",", new X509Store(StoreName.My, StoreLocation.CurrentUser).Certificates.Select(x => x.FriendlyName).ToArray())); - @string.AppendFormatLine("X509Store Root: {0}", string.Join(",", new X509Store(StoreName.Root, StoreLocation.CurrentUser).Certificates.Select(x => x.FriendlyName).ToArray())); - @string.AppendFormatLine("X509Store CertificateAuthority: {0}", string.Join(",", new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser).Certificates.Select(x => x.FriendlyName).ToArray())); + @string.AppendFormatLine("X509Store My: {0}", string.Join(",", GetCertificates(new X509Store(StoreName.My, StoreLocation.CurrentUser)).Select(x => x.FriendlyName).ToArray())); + @string.AppendFormatLine("X509Store Root: {0}", string.Join(",", GetCertificates(new X509Store(StoreName.Root, StoreLocation.CurrentUser)).Select(x => x.FriendlyName).ToArray())); + @string.AppendFormatLine("X509Store CertificateAuthority: {0}", string.Join(",", GetCertificates(new X509Store(StoreName.CertificateAuthority, StoreLocation.CurrentUser)).Select(x => x.FriendlyName).ToArray())); var stopwatch = Stopwatch.StartNew(); try @@ -292,9 +300,9 @@ namespace System.Application.UI.ViewModels #if DEBUG public void IPCTest() { - if (AppHelper.ProgramPath.EndsWith(FileEx.EXE)) + if (IApplication.ProgramPath.EndsWith(FileEx.EXE)) { - var consoleProgramPath = AppHelper.ProgramPath.Substring(0, AppHelper.ProgramPath.Length - FileEx.EXE.Length) + ".Console" + FileEx.EXE; + var consoleProgramPath = IApplication.ProgramPath.Substring(0, IApplication.ProgramPath.Length - FileEx.EXE.Length) + ".Console" + FileEx.EXE; if (File.Exists(consoleProgramPath)) { var pipeClient = new Process(); @@ -344,9 +352,9 @@ namespace System.Application.UI.ViewModels public void FileShareTest() { - if (AppHelper.ProgramPath.EndsWith(FileEx.EXE)) + if (IApplication.ProgramPath.EndsWith(FileEx.EXE)) { - var consoleProgramPath = AppHelper.ProgramPath.Substring(0, AppHelper.ProgramPath.Length - FileEx.EXE.Length) + ".Console" + FileEx.EXE; + var consoleProgramPath = IApplication.ProgramPath.Substring(0, IApplication.ProgramPath.Length - FileEx.EXE.Length) + ".Console" + FileEx.EXE; if (File.Exists(consoleProgramPath)) { var pipeClient = new Process(); @@ -584,7 +592,7 @@ namespace System.Application.UI.ViewModels public void TestFontsButton_Click() { - IDesktopWindowViewModelManager.Instance.ShowTaskBarWindow(0, 0); + IViewModelManager.Instance.ShowTaskBarWindow(0, 0); //InstalledFontCollection ifc = new(); //StringBuilder s = new(); //foreach (var item in ifc.Families) @@ -601,4 +609,4 @@ namespace System.Application.UI.ViewModels } #endif } -} \ No newline at end of file +} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/GameListPageViewModel.cs similarity index 98% rename from src/ST.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/GameListPageViewModel.cs index f4bccf986..6a10796d3 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameListPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/GameListPageViewModel.cs @@ -36,7 +36,6 @@ namespace System.Application.UI.ViewModels { return true; } - var pinyinArray = Pinyin.GetPinyin(s.DisplayName, dictPinYinArray); if (Pinyin.SearchCompare(text, s.DisplayName, pinyinArray)) { @@ -77,7 +76,8 @@ namespace System.Application.UI.ViewModels public GameListPageViewModel() { _IconKey = nameof(GameListPageViewModel); - AppTypeFiltres = new ObservableCollection>(EnumClass.GetEnums()); + + AppTypeFiltres = new ObservableCollection>(EnumModel.GetEnums()); AppTypeFiltres[1].Enable = true; AppTypeFiltres[2].Enable = true; @@ -254,6 +254,7 @@ namespace System.Application.UI.ViewModels url = string.Format(SteamApiUrls.STEAM_RUNGAME_URL, app.AppId); else url = string.Format(SteamApiUrls.STEAM_INSTALL_URL, app.AppId); + } Process2.Start(url, useShellExecute: true); } @@ -266,7 +267,7 @@ namespace System.Application.UI.ViewModels public void OpenFolder(SteamApp app) { if (!string.IsNullOrEmpty(app.InstalledDir)) - IDesktopPlatformService.Instance.OpenFolder(app.InstalledDir); + IPlatformService.Instance.OpenFolder(app.InstalledDir); } public async void OpenAppStoreUrl(SteamApp app) @@ -364,7 +365,7 @@ namespace System.Application.UI.ViewModels { Toast.Show(AppResources.GameList_RuningWait); app.Process = Process2.Start( - AppHelper.ProgramPath, + IApplication.ProgramPath, $"-clt app -id {app.AppId}"); SteamConnectService.Current.RuningSteamApps.TryAdd(app.AppId, app); } @@ -380,4 +381,4 @@ namespace System.Application.UI.ViewModels UISettings.AppGridSize.Value = UISettings.AppGridSize.Value == 200 ? 150 : 200; } } -} \ No newline at end of file +} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/GameRelated/GameRelatedPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.cs similarity index 83% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/GameRelated/GameRelatedPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.cs index 70a34fc75..8ffd67203 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/GameRelated/GameRelatedPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/GameRelated/GameRelatedPageViewModel.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Text; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class GameRelatedPageViewModel { diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelated_BorderlessPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/GameRelated/GameRelated_BorderlessPageViewModel.cs similarity index 82% rename from src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelated_BorderlessPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/GameRelated/GameRelated_BorderlessPageViewModel.cs index a048953e2..22d7e0fca 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/GameRelated/GameRelated_BorderlessPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/GameRelated/GameRelated_BorderlessPageViewModel.cs @@ -6,9 +6,9 @@ using System.Collections.ObjectModel; // ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - public class GameRelated_BorderlessPageViewModel : ViewModelBase + public sealed class GameRelated_BorderlessPageViewModel : ViewModelBase { - protected readonly INativeWindowApiService windowApi = INativeWindowApiService.Instance; + readonly INativeWindowApiService windowApi = INativeWindowApiService.Instance; #region SelectWindow 变更通知 @@ -16,12 +16,12 @@ namespace System.Application.UI.ViewModels public NativeWindowModel? SelectWindow { - get { return this._SelectWindow; } + get { return _SelectWindow; } set { - if (this._SelectWindow != value) + if (_SelectWindow != value) { - this._SelectWindow = value; + _SelectWindow = value; this.RaisePropertyChanged(); } } @@ -29,15 +29,15 @@ namespace System.Application.UI.ViewModels #endregion - private ObservableCollection _WindowList = new(); + ObservableCollection _WindowList = new(); public ObservableCollection WindowList { - get { return this._WindowList; } + get { return _WindowList; } set { - if (this._WindowList != value) + if (_WindowList != value) { - this._WindowList = value; + _WindowList = value; this.RaisePropertyChanged(); } } diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/LocalAuthPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/LocalAuthPageViewModel.cs similarity index 89% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/LocalAuthPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/LocalAuthPageViewModel.cs index f1db640b7..1176ff85a 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/LocalAuthPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/LocalAuthPageViewModel.cs @@ -2,7 +2,6 @@ using DynamicData; using DynamicData.Binding; using ReactiveUI; using System.Application.Models; -using System.Application.Models.Abstractions; using System.Application.Repositories; using System.Application.Security; using System.Application.Services; @@ -14,13 +13,35 @@ using System.Properties; using System.Reactive; using System.Reactive.Linq; using System.Threading.Tasks; -using AuthService = System.Application.Services.Abstractions.AuthService; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class LocalAuthPageViewModel { + readonly Dictionary dictPinYinArray = new(); + Func PredicateName(string? serachText) + { + return s => + { + if (s == null) + return false; + if (string.IsNullOrEmpty(serachText)) + return true; + if (s.Name.Contains(serachText, StringComparison.OrdinalIgnoreCase)) + { + return true; + } + var pinyinArray = Pinyin.GetPinyin(s.Name, dictPinYinArray); + if (Pinyin.SearchCompare(serachText, s.Name, pinyinArray)) + { + return true; + } + + return false; + }; + } + public LocalAuthPageViewModel() { IconKey = nameof(LocalAuthPageViewModel); @@ -75,9 +96,10 @@ namespace System.Application.UI.ViewModels.Abstractions // //}, //}; + var textFilter = this.WhenAnyValue(x => x.SearchText).Select(PredicateName); AuthService.Current.Authenticators .Connect() - //.Filter(scriptFilter) + .Filter(textFilter) .ObserveOn(RxApp.MainThreadScheduler) .Sort(SortExpressionComparer.Ascending(x => x.Index).ThenBy(x => x.Name)) .Bind(out _Authenticators) @@ -110,6 +132,16 @@ namespace System.Application.UI.ViewModels.Abstractions public ReactiveCommand OpenBrowserCommand { get; } + private string _SearchText; + /// + /// 搜索文本 + /// + public string SearchText + { + get => _SearchText; + set => this.RaiseAndSetIfChanged(ref _SearchText, value); + } + private bool _IsFirstLoadedAuthenticatorsEmpty; /// /// 是否第一次加载完成时令牌集合数据为空 @@ -209,10 +241,6 @@ namespace System.Application.UI.ViewModels.Abstractions } } - protected abstract ShowAuthWindowViewModel GetShowAuthWVM(MyAuthenticator auth); - - protected abstract AuthTradeWindowViewModel GetAuthTradeWVM(MyAuthenticator auth); - public async void ShowSteamAuthData(MyAuthenticator auth) { var (success, _) = await AuthService.Current.HasPasswordEncryptionShowPassWordWindow(); @@ -222,7 +250,7 @@ namespace System.Application.UI.ViewModels.Abstractions case GamePlatform.Steam: await IWindowManager.Instance.Show( CustomWindow.ShowAuth, - GetShowAuthWVM(auth), + new ShowAuthWindowViewModel(auth), resizeMode: ResizeMode.CanResize); break; } @@ -235,7 +263,7 @@ namespace System.Application.UI.ViewModels.Abstractions case GamePlatform.Steam: IWindowManager.Instance.Show( CustomWindow.AuthTrade, - GetAuthTradeWVM(auth), + new AuthTradeWindowViewModel(auth), resizeMode: ResizeMode.CanResize); break; } diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/OtherPlatformPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/OtherPlatformPageViewModel.cs similarity index 85% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/OtherPlatformPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/OtherPlatformPageViewModel.cs index 3ee5d3ce9..2f1949bbd 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/OtherPlatformPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/OtherPlatformPageViewModel.cs @@ -4,7 +4,7 @@ using System.Text; using System.Application.UI.Resx; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class OtherPlatformPageViewModel { diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/ProxyScriptManagePageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/ProxyScriptManagePageViewModel.cs similarity index 88% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/ProxyScriptManagePageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/ProxyScriptManagePageViewModel.cs index 0b47c5888..247634337 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/ProxyScriptManagePageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/ProxyScriptManagePageViewModel.cs @@ -16,7 +16,7 @@ using System.Windows.Input; using Xamarin.Essentials; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class ProxyScriptManagePageViewModel { @@ -28,6 +28,11 @@ namespace System.Application.UI.ViewModels.Abstractions IconKey = "JavaScriptDrawing", Command = ScriptStoreCommand }; + yield return new MenuItemViewModel(nameof(AppResources.Script_AllEnable)) + { + IconKey = "JavaScriptDrawing", + Command = AllEnableScriptCommand, + }; yield return new MenuItemViewModel(); if (OnlySteamBrowser != null) yield return OnlySteamBrowser; } @@ -37,10 +42,15 @@ namespace System.Application.UI.ViewModels.Abstractions IconKey = nameof(ProxyScriptManagePageViewModel); ScriptStoreCommand = ReactiveCommand.Create(OpenScriptStoreWindow); + AllEnableScriptCommand = ReactiveCommand.Create(AllEnableScript); EnableScriptAutoUpdateCommand = ReactiveCommand.Create(() => { ScriptAutoUpdate?.CheckmarkChange(ProxySettings.IsAutoCheckScriptUpdate.Value = !ProxySettings.IsAutoCheckScriptUpdate.Value); }); + OnlySteamBrowserCommand = ReactiveCommand.Create(() => + { + OnlySteamBrowser?.CheckmarkChange(ProxyService.Current.IsOnlyWorkSteamBrowser = !ProxyService.Current.IsOnlyWorkSteamBrowser); + }); AddNewScriptButton_Click = ReactiveCommand.CreateFromTask(async () => { var fileTypes = !FilePicker2.IsSupportedFileExtensionFilter ? (FilePickerFileType?)null : new FilePicker2.FilePickerFilter(new (string, IEnumerable)[] { @@ -55,7 +65,10 @@ namespace System.Application.UI.ViewModels.Abstractions { Command = EnableScriptAutoUpdateCommand, }; - OnlySteamBrowser = GetOnlySteamBrowser(); + OnlySteamBrowser = new(nameof(AppResources.CommunityFix_OnlySteamBrowser)) + { + Command = OnlySteamBrowserCommand, + }; MenuItems = new ObservableCollection(GetMenuItems()); ScriptAutoUpdate?.CheckmarkChange(ProxySettings.IsAutoCheckScriptUpdate.Value); @@ -69,6 +82,8 @@ namespace System.Application.UI.ViewModels.Abstractions .Sort(SortExpressionComparer.Ascending(x => x.Order).ThenBy(x => x.Name)) .Bind(out _ProxyScripts) .Subscribe(_ => this.RaisePropertyChanged(nameof(IsProxyScriptsEmpty))); + + OnlySteamBrowser?.CheckmarkChange(ProxyService.Current.IsOnlyWorkSteamBrowser); } public override void Activation() @@ -113,10 +128,12 @@ namespace System.Application.UI.ViewModels.Abstractions public MenuItemViewModel? OnlySteamBrowser { get; } - protected virtual MenuItemViewModel? GetOnlySteamBrowser() => null; + public ReactiveCommand OnlySteamBrowserCommand { get; } public ReactiveCommand ScriptStoreCommand { get; } + public ReactiveCommand AllEnableScriptCommand { get; } + string? _SearchText; public string? SearchText { @@ -258,6 +275,12 @@ namespace System.Application.UI.ViewModels.Abstractions } } + public void AllEnableScript() + { + ProxyService.Current.ProxyScripts.Edit(x => x.All(e => e.Enable = true)); + // ProxyService.Current.ProxyScripts= ProxyService.Current.ProxyScripts.Items.Select(x=>x.Enable=true).ToList(); + } + public ICommand AddNewScriptButton_Click { get; } } } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs similarity index 52% rename from src/ST.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs index b48b69173..9f966814e 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs @@ -14,23 +14,21 @@ using System.Windows.Input; using Xamarin.Essentials; using static System.Application.FilePicker2; +// ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - partial class SettingsPageViewModel + public partial class SettingsPageViewModel { - KeyValuePair _SelectFont; - public KeyValuePair SelectFont - { - get => _SelectFont; - set => this.RaiseAndSetIfChanged(ref _SelectFont, value); - } - - public ICommand SelectImage_Click { get; } - - public ICommand ResetImage_Click { get; } - public SettingsPageViewModel() { + IconKey = nameof(SettingsPageViewModel); + + SelectLanguage = R.Languages.FirstOrDefault(x => x.Key == UISettings.Language.Value); + this.WhenValueChanged(x => x.SelectLanguage, false) + .Subscribe(x => UISettings.Language.Value = x.Key); + + UpdateChannels = Enum2.GetAll(); + SelectFont = R.Fonts.FirstOrDefault(x => x.Value == UISettings.FontName.Value); this.WhenValueChanged(x => x.SelectFont, false) .Subscribe(x => UISettings.FontName.Value = x.Value); @@ -54,6 +52,33 @@ namespace System.Application.UI.ViewModels ResetImage_Click = ReactiveCommand.Create(() => SetBackgroundImagePath(null)); } + public static SettingsPageViewModel Instance { get; } = new(); + + KeyValuePair _SelectLanguage; + public KeyValuePair SelectLanguage + { + get => _SelectLanguage; + set => this.RaiseAndSetIfChanged(ref _SelectLanguage, value); + } + + KeyValuePair _SelectFont; + public KeyValuePair SelectFont + { + get => _SelectFont; + set => this.RaiseAndSetIfChanged(ref _SelectFont, value); + } + + public ICommand SelectImage_Click { get; } + + public ICommand ResetImage_Click { get; } + + IReadOnlyCollection? _UpdateChannels; + public IReadOnlyCollection? UpdateChannels + { + get => _UpdateChannels; + set => this.RaiseAndSetIfChanged(ref _UpdateChannels, value); + } + const double clickInterval = 3d; readonly Dictionary clickTimeRecord = new(); public void OpenFolder(string tag) @@ -70,7 +95,7 @@ namespace System.Application.UI.ViewModels var hasKey = clickTimeRecord.TryGetValue(path, out var dt); var now = DateTime.Now; if (hasKey && (now - dt).TotalSeconds <= clickInterval) return; - IDesktopPlatformService.Instance.OpenFolder(path); + IPlatformService.Instance.OpenFolder(path); if (!clickTimeRecord.TryAdd(path, now)) clickTimeRecord[path] = now; } } @@ -86,8 +111,8 @@ namespace System.Application.UI.ViewModels { if (IOPath.TryOpenRead(imagePath, out var stream, out var _)) { - var image = FileFormat.IsImage(stream); - if (image.isImage) + var (isImage, _) = FileFormat.IsImage(stream); + if (isImage) { UISettings.BackgroundImagePath.Value = imagePath; return; @@ -96,5 +121,57 @@ namespace System.Application.UI.ViewModels } Toast.Show("选择的图片格式不正确"); } + + public static string[] GetThemes() => new[] + { + AppResources.Settings_UI_SystemDefault, + AppResources.Settings_UI_Light, + AppResources.Settings_UI_Dark, + }; + + /// + /// 开始计算指定文件夹大小 + /// + /// + /// + /// + public static void StartCacheSizeCalc(ref bool isStartCacheSizeCalc, string sizeFormat, Action action, CancellationToken cancellationToken = default) + { + if (isStartCacheSizeCalc) return; + isStartCacheSizeCalc = true; + action(AppResources.Settings_General_Calcing); + string? dirPath; + if (sizeFormat == AppResources.Settings_General_CacheSize) + { + dirPath = IOPath.CacheDirectory; + } + else if (sizeFormat == AppResources.Settings_General_LogSize) + { + dirPath = IApplication.LogDirPath; + } + else + { + dirPath = null; + } + if (dirPath != null) + { + try + { + Task.Run(async () => + { + var length = IOPath.GetDirectorySize(dirPath); + var lenString = IOPath.GetSizeString(length); + await MainThread2.InvokeOnMainThreadAsync(() => + { + action(sizeFormat.Format(lenString)); + }); + }, cancellationToken); + } + catch (OperationCanceledException) + { + + } + } + } } -} \ No newline at end of file +} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/StartPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/StartPageViewModel.cs similarity index 84% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/StartPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/StartPageViewModel.cs index 118043b0d..cc4399b8a 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/StartPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/StartPageViewModel.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Text; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class StartPageViewModel { diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/SteamAccountPageViewModel.cs similarity index 94% rename from src/ST.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/SteamAccountPageViewModel.cs index 7e385fd54..36fb26736 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Pages/SteamAccountPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/SteamAccountPageViewModel.cs @@ -16,16 +16,18 @@ using System.Reactive.Linq; // ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - partial class SteamAccountPageViewModel + public partial class SteamAccountPageViewModel { public override bool IsTaskBarSubMenu => MenuItems.Any_Nullable(); - readonly ISteamService steamService = DI.Get(); - readonly IHttpService httpService = DI.Get(); - readonly ISteamworksWebApiService webApiService = DI.Get(); + readonly ISteamService steamService = ISteamService.Instance; + readonly IHttpService httpService = IHttpService.Instance; + readonly ISteamworksWebApiService webApiService = ISteamworksWebApiService.Instance; public SteamAccountPageViewModel() { + IconKey = nameof(SteamAccountPageViewModel); + this.WhenAnyValue(x => x.SteamUsers) .Subscribe(s => this.RaisePropertyChanged(nameof(IsUserEmpty))); LoginAccountCommand = ReactiveCommand.Create(LoginNewSteamAccount); @@ -115,7 +117,7 @@ namespace System.Application.UI.ViewModels }), }); - DI.Get().AddJumpTask(title, AppHelper.ProgramPath, AppHelper.ProgramPath, "-clt steam -account " + user.AccountName, AppResources.UserChange_BtnTootlip, this.Name); + IJumpListService.Instance.AddJumpTask(title, IApplication.ProgramPath, IApplication.ProgramPath, "-clt steam -account " + user.AccountName, AppResources.UserChange_BtnTootlip, Name); } } this.RaisePropertyChanged(nameof(IsTaskBarSubMenu)); @@ -158,7 +160,6 @@ namespace System.Application.UI.ViewModels } _SteamUsersSourceList.Refresh(); #endregion - } public void SteamId_Click(SteamUser user) @@ -244,4 +245,4 @@ namespace System.Application.UI.ViewModels SteamAccountSettings.AccountRemarks.RaiseValueChanged(); } } -} \ No newline at end of file +} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Pages/SteamIdlePageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/SteamIdlePageViewModel.cs similarity index 83% rename from src/ST.Client/UI/ViewModels/Abstractions/Pages/SteamIdlePageViewModel.cs rename to src/ST.Client/UI/ViewModels/Pages/SteamIdlePageViewModel.cs index 5ffae69de..ec15e4385 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Pages/SteamIdlePageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/SteamIdlePageViewModel.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Text; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class SteamIdlePageViewModel { diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs similarity index 87% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs index 2e67d6f55..65073d71e 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/ArchiSteamFarmPlus/ASF_AddBotWindowViewModel.cs @@ -6,9 +6,9 @@ using System.Application.UI.Resx; using System.Properties; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { - public abstract class ASF_AddBotWindowViewModel : WindowViewModel + public class ASF_AddBotWindowViewModel : WindowViewModel { public static string DisplayName_AddBot => "新增Bot"; public static string DisplayName_EditBott => "编辑Bot"; diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/BindPhoneNumberWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.cs similarity index 95% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/BindPhoneNumberWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.cs index 5e89db85c..dc291f817 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/BindPhoneNumberWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/BindPhoneNumberWindowViewModel.cs @@ -9,9 +9,9 @@ using System.Threading.Tasks; using static System.Application.Services.CloudService.Constants; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { - public abstract class BindPhoneNumberWindowViewModel : WindowViewModel, SendSmsUIHelper.IViewModel + public class BindPhoneNumberWindowViewModel : WindowViewModel, SendSmsUIHelper.IViewModel { public static string DisplayName => AppResources.User_BindPhoneNum; diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/ChangeBindPhoneNumberWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.cs similarity index 98% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/ChangeBindPhoneNumberWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.cs index c7f8427d5..05bdfa67f 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/ChangeBindPhoneNumberWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/ChangeBindPhoneNumberWindowViewModel.cs @@ -9,9 +9,9 @@ using System.Threading.Tasks; using static System.Application.Services.CloudService.Constants; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { - public abstract class ChangeBindPhoneNumberWindowViewModel : WindowViewModel + public class ChangeBindPhoneNumberWindowViewModel : WindowViewModel { public static string DisplayName => AppResources.User_ChangePhoneNum; diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/CommunityProxyPage/ProxySettingsWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/CommunityProxyPage/ProxySettingsWindowViewModel.cs similarity index 58% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/CommunityProxyPage/ProxySettingsWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/CommunityProxyPage/ProxySettingsWindowViewModel.cs index 977f08f53..8ded28c34 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/CommunityProxyPage/ProxySettingsWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/CommunityProxyPage/ProxySettingsWindowViewModel.cs @@ -1,5 +1,3 @@ -using ArchiSteamFarm.Steam; -using Newtonsoft.Json.Linq; using ReactiveUI; using System.Application.Models; using System.Application.UI.Resx; @@ -7,15 +5,18 @@ using System.Collections.Generic; using System.Properties; using Titanium.Web.Proxy.Models; +// ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { public class ProxySettingsWindowViewModel : WindowViewModel { - public ProxySettingsWindowViewModel() : base() + public static string DisplayName => AppResources.CommunityFix_ProxySettings; + + public ProxySettingsWindowViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.CommunityFix_ProxySettings; + Title = GetTitleByDisplayName(DisplayName); } - public IEnumerable ProxyTypes { get; set; } = Enum.GetValues(); + public IEnumerable ProxyTypes { get; set; } = Enum2.GetAll(); } -} \ No newline at end of file +} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/AchievementWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/GameListPage/AchievementWindowViewModel.cs similarity index 83% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/AchievementWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/GameListPage/AchievementWindowViewModel.cs index 97e71d8a8..4ead6b52d 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/AchievementWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/GameListPage/AchievementWindowViewModel.cs @@ -1,6 +1,5 @@ using DynamicData; using DynamicData.Binding; -using Newtonsoft.Json.Linq; using ReactiveUI; using System.Application.Models; using System.Application.Services; @@ -13,13 +12,15 @@ using System.IO; using System.Linq; using System.Properties; using System.Reactive.Linq; +using System.Threading; using System.Threading.Tasks; -using System.Windows; namespace System.Application.UI.ViewModels { public class AchievementWindowViewModel : WindowViewModel { + public static string DisplayName => AppResources.Achievement_Manage; + private int AppId { get; } #region 成就列表 @@ -86,18 +87,18 @@ namespace System.Application.UI.ViewModels }; } - public AchievementWindowViewModel(int appid) : base() + public AchievementWindowViewModel(int appid) { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.Achievement_Manage; + Title = GetTitleByDisplayName(DisplayName); SteamConnectService.Current.Initialize(appid); if (SteamConnectService.Current.IsConnectToSteam == false) { - MessageBoxCompat.ShowAsync(AppResources.Achievement_Warning_1, Title, MessageBoxButtonCompat.OKCancel).ContinueWith(s => - { - EnforceClose(); - }).Wait(); + MessageBox.ShowAsync(AppResources.Achievement_Warning_1, Title, MessageBox.Button.OK).ContinueWith(s => + { + EnforceClose(); + }).Wait(); } _AchievementsSourceList = new SourceList(); @@ -120,7 +121,7 @@ namespace System.Application.UI.ViewModels .Connect() .Filter(nameStatisticsFilter) .ObserveOn(RxApp.MainThreadScheduler) - .Sort(SortExpressionComparer.Descending(x => x.Id)) + .Sort(SortExpressionComparer.Descending(x => x.Id!)) .Bind(out _Statistics) .Subscribe(); @@ -142,14 +143,14 @@ namespace System.Application.UI.ViewModels { if (param.Result != 1) { - MessageBoxCompat.ShowAsync(AppResources.Achievement_Warning_2.Format(param.Result), Title, MessageBoxButtonCompat.OKCancel).ContinueWith(s => + MessageBox.ShowAsync(AppResources.Achievement_Warning_2.Format(param.Result), Title, MessageBox.Button.OK).ContinueWith(s => { EnforceClose(); }).Wait(); } - if (this.LoadUserGameStatsSchema() == false) + if (LoadUserGameStatsSchema() == false) { - MessageBoxCompat.ShowAsync($"Failed to load schema", Title, MessageBoxButtonCompat.OKCancel).ContinueWith(s => + MessageBox.ShowAsync("Failed to load schema", Title, MessageBox.Button.OK).ContinueWith(s => { EnforceClose(); }).Wait(); @@ -157,8 +158,7 @@ namespace System.Application.UI.ViewModels GetAchievements(); GetStatistics(); - //ToastService.Current.Notify($"获取到 {this._AchievementsSourceList.Count} 个成就和 {this._StatisticsSourceList.Count} 条统计信息"); - ToastService.Current.Notify(AppResources.Achievement_LoadSucces.Format(_AchievementsSourceList.Count, _StatisticsSourceList.Count)); + Toast.Show(AppResources.Achievement_LoadSucces.Format(_AchievementsSourceList.Count, _StatisticsSourceList.Count)); }); Task.Run(() => @@ -166,29 +166,28 @@ namespace System.Application.UI.ViewModels while (true) { ISteamworksLocalApiService.Instance.RunCallbacks(false); - Threading.Thread.Sleep(2000); + Thread.Sleep(2000); } }).Forget(); - this.RefreshStats_Click(); + RefreshStats_Click(); } - - - private void EnforceClose() + void EnforceClose() { Process.GetCurrentProcess().Kill(); } - private bool LoadUserGameStatsSchema() + bool LoadUserGameStatsSchema() { var path = ISteamService.Instance.SteamDirPath; + if (string.IsNullOrWhiteSpace(path)) return false; path = Path.Combine(path, "appcache"); path = Path.Combine(path, "stats"); path = Path.Combine(path, string.Format( CultureInfo.InvariantCulture, "UserGameStatsSchema_{0}.bin", - this.AppId)); + AppId)); if (File.Exists(path) == false) { @@ -203,7 +202,7 @@ namespace System.Application.UI.ViewModels } var currentLanguage = R.GetCurrentCultureSteamLanguageName(); ; - var stats = kv[this.AppId.ToString(CultureInfo.InvariantCulture)]["stats"]; + var stats = kv[AppId.ToString(CultureInfo.InvariantCulture)]["stats"]; if (stats.Valid == false || stats.Children == null) { @@ -233,7 +232,7 @@ namespace System.Application.UI.ViewModels var id = stat["name"].AsString(""); string name = GetLocalizedString(stat["display"]["name"], currentLanguage, id); - this._StatisticsSourceList.Add(new IntStatInfo() + _StatisticsSourceList.Add(new IntStatInfo() { Id = stat["name"].AsString(""), DisplayName = name, @@ -253,7 +252,7 @@ namespace System.Application.UI.ViewModels var id = stat["name"].AsString(""); string name = GetLocalizedString(stat["display"]["name"], currentLanguage, id); - this._StatisticsSourceList.Add(new FloatStatInfo() + _StatisticsSourceList.Add(new FloatStatInfo() { Id = stat["name"].AsString(""), DisplayName = name, @@ -287,7 +286,7 @@ namespace System.Application.UI.ViewModels string name = GetLocalizedString(bit["display"]["name"], currentLanguage, id); string desc = GetLocalizedString(bit["display"]["desc"], currentLanguage, ""); - this._AchievementsSourceList.Add(new AchievementInfo() + _AchievementsSourceList.Add(new AchievementInfo() { AppId = AppId, Id = id, @@ -315,7 +314,7 @@ namespace System.Application.UI.ViewModels return true; } - private static string GetLocalizedString(KeyValue kv, string language, string defaultValue) + static string GetLocalizedString(KeyValue kv, string language, string defaultValue) { var name = kv[language].AsString(""); if (string.IsNullOrEmpty(name) == false) @@ -349,10 +348,10 @@ namespace System.Application.UI.ViewModels return defaultValue; } - private void GetAchievements() + void GetAchievements() { var list = new List(); - foreach (var def in this._AchievementsSourceList.Items) + foreach (var def in _AchievementsSourceList.Items) { if (string.IsNullOrEmpty(def.Id) == true) { @@ -390,19 +389,19 @@ namespace System.Application.UI.ViewModels // achievement.IconStream = await IHttpService.Instance.GetImageAsync(achievement.IconUrl, ImageChannelType.SteamAchievementIcon); //}); _AchievementsSourceList.Clear(); - this._AchievementsSourceList.AddRange(list); + _AchievementsSourceList.AddRange(list); //_BackAchievements = Achievements; } - private int StoreAchievements() + int StoreAchievements() { - if (this.Achievements.Count == 0) + if (Achievements == null || Achievements.Count == 0) { return 0; } var achievements = new List(); - foreach (var achievementInfo in this.Achievements) + foreach (var achievementInfo in Achievements) { if (achievementInfo != null && achievementInfo.IsAchieved != achievementInfo.IsChecked) @@ -419,9 +418,9 @@ namespace System.Application.UI.ViewModels foreach (AchievementInfo info in achievements) { - if (ISteamworksLocalApiService.Instance.SetAchievement(info.Id, info.IsAchieved) == false) + if (ISteamworksLocalApiService.Instance.SetAchievement(info.Id!, info.IsAchieved) == false) { - MessageBoxCompat.ShowAsync(AppResources.Achievement_Warning_3.Format(info.Name), Title, MessageBoxButtonCompat.OK).ContinueWith(s => + MessageBox.ShowAsync(AppResources.Achievement_Warning_3.Format(info.Name), Title, MessageBox.Button.OK).ContinueWith(s => { EnforceClose(); }); @@ -432,10 +431,10 @@ namespace System.Application.UI.ViewModels return achievements.Count; } - private void GetStatistics() + void GetStatistics() { var list = new List(); - foreach (var rdef in this._StatisticsSourceList.Items) + foreach (var rdef in _StatisticsSourceList.Items) { if (string.IsNullOrEmpty(rdef.Id) == true) { @@ -478,14 +477,14 @@ namespace System.Application.UI.ViewModels _StatisticsSourceList.AddRange(list); } - private int StoreStatistics() + int StoreStatistics() { - if (this.Statistics.Count == 0) + if (Statistics == null || Statistics.Count == 0) { return 0; } - var statistics = this.Statistics.Where(stat => stat.IsModified).ToList(); + var statistics = Statistics.Where(stat => stat.IsModified).ToList(); if (statistics.Count == 0) { return 0; @@ -524,8 +523,8 @@ namespace System.Application.UI.ViewModels public void RefreshStats_Click() { - this._AchievementsSourceList.Clear(); - this._StatisticsSourceList.Clear(); + _AchievementsSourceList.Clear(); + _StatisticsSourceList.Clear(); //Achievements = new ObservableCollection(); //Statistics = new ObservableCollection(); ISteamworksLocalApiService.Instance.RequestCurrentStats(); @@ -535,47 +534,45 @@ namespace System.Application.UI.ViewModels public async void ResetAllStats_Click() { - var result = await MessageBoxCompat.ShowAsync(AppResources.Achievement_ResetWaring_1, Title, MessageBoxButtonCompat.OKCancel); - if (result == MessageBoxResultCompat.OK) + var result = await MessageBox.ShowAsync(AppResources.Achievement_ResetWaring_1, Title, MessageBox.Button.OKCancel); + if (result.IsOK()) { - var achievementsToo = await MessageBoxCompat.ShowAsync(AppResources.Achievement_ResetWaring_2, Title, MessageBoxButtonCompat.OKCancel); - - - var real = await MessageBoxCompat.ShowAsync(AppResources.Achievement_ResetWaring_3, Title, MessageBoxButtonCompat.OKCancel); - if (real == MessageBoxResultCompat.OK) + var achievementsToo = await MessageBox.ShowAsync(AppResources.Achievement_ResetWaring_2, Title, MessageBox.Button.OKCancel); + var real = await MessageBox.ShowAsync(AppResources.Achievement_ResetWaring_3, Title, MessageBox.Button.OKCancel); + if (real.IsOK()) { - if (ISteamworksLocalApiService.Instance.ResetAllStats(achievementsToo == MessageBoxResultCompat.OK)) + if (ISteamworksLocalApiService.Instance.ResetAllStats(achievementsToo.IsOK())) { return; } - this.RefreshStats_Click(); + RefreshStats_Click(); } } } public void SaveChange_Click() { - int achievements = this.StoreAchievements(); + int achievements = StoreAchievements(); if (achievements < 0) { - this.RefreshStats_Click(); + RefreshStats_Click(); return; } - int stats = this.StoreStatistics(); + int stats = StoreStatistics(); if (stats < 0) { - this.RefreshStats_Click(); + RefreshStats_Click(); return; } if (ISteamworksLocalApiService.Instance.StoreStats() == false) { - this.ResetAllStats_Click(); + ResetAllStats_Click(); return; } - ToastService.Current.Notify(AppResources.Achievement_EditSucces.Format(achievements, stats)); - this.RefreshStats_Click(); + Toast.Show(AppResources.Achievement_EditSucces.Format(achievements, stats)); + RefreshStats_Click(); } } } \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/EditAppInfoWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/GameListPage/EditAppInfoWindowViewModel.cs similarity index 63% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/EditAppInfoWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/GameListPage/EditAppInfoWindowViewModel.cs index f1a82b4a6..98d0ffb4f 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/EditAppInfoWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/GameListPage/EditAppInfoWindowViewModel.cs @@ -7,20 +7,18 @@ namespace System.Application.UI.ViewModels { public class EditAppInfoWindowViewModel : WindowViewModel { - private readonly SteamApp? _App; + public static string DisplayName => AppResources.GameList_EditAppInfo; - public EditAppInfoWindowViewModel() : base() + readonly SteamApp? _App; + + public EditAppInfoWindowViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.GameList_EditAppInfo; + Title = GetTitleByDisplayName(DisplayName); } public EditAppInfoWindowViewModel(SteamApp app) : this() { _App = app; } - - - - } } \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/HideAppWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/GameListPage/HideAppWindowViewModel.cs similarity index 91% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/HideAppWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/GameListPage/HideAppWindowViewModel.cs index 0323d377e..19f68a685 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/HideAppWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/GameListPage/HideAppWindowViewModel.cs @@ -3,7 +3,7 @@ using DynamicData.Binding; using Newtonsoft.Json.Linq; using ReactiveUI; using System.Application.Models; -using System.Application.Models.Settings; +using System.Application.Settings; using System.Application.Services; using System.Application.UI.Resx; using System.Collections.Generic; @@ -16,14 +16,17 @@ namespace System.Application.UI.ViewModels { public class HideAppWindowViewModel : WindowViewModel { - public HideAppWindowViewModel() : base() + public static string DisplayName => AppResources.GameList_HideGameManger; + + public HideAppWindowViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.GameList_HideGameManger; + Title = GetTitleByDisplayName(DisplayName); GameLibrarySettings.HideGameList.Subscribe(_ => Refresh_Click()); Refresh_Click(); } + public bool _IsHideGameListEmpty; public bool IsHideGameListEmpty { @@ -52,7 +55,6 @@ namespace System.Application.UI.ViewModels IsHideGameListEmpty = true; else IsHideGameListEmpty = false; - } public void ChangeCheck(KeyValuePair keyValue) diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/IdleAppWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/GameListPage/IdleAppWindowViewModel.cs similarity index 88% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/IdleAppWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/GameListPage/IdleAppWindowViewModel.cs index 0b1fb73f6..ea3515f85 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/IdleAppWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/GameListPage/IdleAppWindowViewModel.cs @@ -1,6 +1,6 @@ using ReactiveUI; using System.Application.Models; -using System.Application.Models.Settings; +using System.Application.Settings; using System.Application.Services; using System.Application.UI.Resx; using System.Collections.ObjectModel; @@ -12,11 +12,13 @@ namespace System.Application.UI.ViewModels { public class IdleAppWindowViewModel : WindowViewModel { - private bool init = false; - private readonly ISteamService SteamTool = ISteamService.Instance; - public IdleAppWindowViewModel() : base() + public static string DisplayName => AppResources.GameList_IdleGamesManger; + + bool init = false; + readonly ISteamService SteamTool = ISteamService.Instance; + public IdleAppWindowViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.GameList_IdleGamesManger; + Title = GetTitleByDisplayName(DisplayName); GameLibrarySettings.AFKAppList.Subscribe(_ => Refresh_Click()); @@ -54,6 +56,7 @@ namespace System.Application.UI.ViewModels get => _IsIdleAppEmpty; set => this.RaiseAndSetIfChanged(ref _IsIdleAppEmpty, value); } + private string _RuningCountTxt = string.Empty; public string RuningCountTxt { @@ -76,9 +79,9 @@ namespace System.Application.UI.ViewModels public void DeleteAllButton_Click() { - var result = MessageBoxCompat.ShowAsync(@AppResources.GameList_DeleteAll, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel).ContinueWith((s) => + var result = MessageBox.ShowAsync(AppResources.GameList_DeleteAll, ThisAssembly.AssemblyTrademark, MessageBox.Button.OKCancel).ContinueWith((s) => { - if (s.Result == MessageBoxResultCompat.OK) + if (s.Result.IsOK()) { if (GameLibrarySettings.AFKAppList.Value != null) { @@ -113,9 +116,9 @@ namespace System.Application.UI.ViewModels public void DeleteButton_Click(SteamApp app) { - var result = MessageBoxCompat.ShowAsync(@AppResources.GameList_DeleteItem, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel).ContinueWith((s) => + var result = MessageBox.ShowAsync(AppResources.GameList_DeleteItem, ThisAssembly.AssemblyTrademark, MessageBox.Button.OKCancel).ContinueWith((s) => { - if (s.Result == MessageBoxResultCompat.OK) + if (s.Result.IsOK()) { if (GameLibrarySettings.AFKAppList.Value != null) { @@ -148,10 +151,13 @@ namespace System.Application.UI.ViewModels RuningCountTxt = AppResources.GameList_RuningCount.Format(count, IdleGameList.Count); RunState = count > 0; if (title) - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.GameList_IdleGamesManger + AppResources.GameList_ListCount.Format(IdleGameList.Count, SteamConnectService.SteamAFKMaxCount); + { + var titleStr = AppResources.GameList_IdleGamesManger + AppResources.GameList_ListCount.Format(IdleGameList.Count, SteamConnectService.SteamAFKMaxCount); + Title = GetTitleByDisplayName(titleStr); + } } - public void RunOrStopAllButton_Click() + public async void RunOrStopAllButton_Click() { if (SteamTool.IsRunningSteamProcess) { @@ -211,11 +217,11 @@ namespace System.Application.UI.ViewModels } else { - var result = MessageBoxCompat.ShowAsync(@AppResources.GameList_SteamNotRuning, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OK); + await MessageBox.ShowAsync(AppResources.GameList_SteamNotRuning, ThisAssembly.AssemblyTrademark, MessageBox.Button.OK); } } - public void RunStopBtn_Click(SteamApp app) + public async void RunStopBtn_Click(SteamApp app) { if (SteamTool.IsRunningSteamProcess) { @@ -236,7 +242,7 @@ namespace System.Application.UI.ViewModels } else { - var result = MessageBoxCompat.ShowAsync(@AppResources.GameList_SteamNotRuning, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OK); + await MessageBox.ShowAsync(AppResources.GameList_SteamNotRuning, ThisAssembly.AssemblyTrademark, MessageBox.Button.OK); } } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/SteamShutdownWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/GameListPage/SteamShutdownWindowViewModel.cs similarity index 84% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/SteamShutdownWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/GameListPage/SteamShutdownWindowViewModel.cs index dc5a2442d..2887df7dc 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/GameListPage/SteamShutdownWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/GameListPage/SteamShutdownWindowViewModel.cs @@ -13,9 +13,11 @@ namespace System.Application.UI.ViewModels { public class SteamShutdownWindowViewModel : WindowViewModel { - public SteamShutdownWindowViewModel() : base() + public static string DisplayName => AppResources.GameList_SteamShutdown; + + public SteamShutdownWindowViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.GameList_SteamShutdown; + Title = GetTitleByDisplayName(DisplayName); SteamConnectService.Current.DownloadApps .Connect() @@ -28,6 +30,5 @@ namespace System.Application.UI.ViewModels private readonly ReadOnlyObservableCollection? _DownloadingApps; public ReadOnlyObservableCollection? DownloadingApps => _DownloadingApps; - } } \ No newline at end of file diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.shared.cs b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.cs similarity index 81% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.shared.cs rename to src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.cs index e19d1473b..40e6ca0f8 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.shared.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/AddAuthWindowViewModel.cs @@ -7,98 +7,73 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; -using System.Properties; using System.Threading.Tasks; -using System.Windows; using System.Windows.Input; using Xamarin.Essentials; using static System.Application.FilePicker2; using static System.Application.Models.GAPAuthenticatorDTO; using static System.Application.Repositories.IGameAccountPlatformAuthenticatorRepository; +// ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - public partial class AddAuthWindowViewModel + public partial class AddAuthWindowViewModel : WindowViewModel { - readonly IHttpService httpService = DI.Get(); + readonly IHttpService httpService = IHttpService.Instance; readonly IGameAccountPlatformAuthenticatorRepository repository = DI.Get(); - public static string TitleName => AppResources.LocalAuth_AddAuth; + public static string DisplayName => AppResources.LocalAuth_AddAuth; - public AddAuthWindowViewModel() : base() + public AddAuthWindowViewModel() { - Title = -#if !__MOBILE__ - ThisAssembly.AssemblyTrademark + " | " + -#endif - TitleName; + Title = GetTitleByDisplayName(DisplayName); SppV2Btn_Click = ReactiveCommand.CreateFromTask(async () => { - var fileTypes = -#if __MOBILE__ - (FilePickerFileType?)null; -#else - new FilePickerFilter(new (string, IEnumerable)[] { - ("MsgPack Files", new[] { "mpo" }), - ("Data Files", new[] { "dat" }), - ("All Files", new[] { "*" }), - }); -#endif + var fileTypes = !IsSupportedFileExtensionFilter ? (FilePickerFileType?)null : new FilePickerFilter(new (string, IEnumerable)[] { + ("MsgPack Files", new[] { "mpo" }), + ("Data Files", new[] { "dat" }), + ("All Files", new[] { "*" }), + }); await PickAsync(ImportSteamPlusPlusV2, fileTypes); }); SppBtn_Click = ReactiveCommand.CreateFromTask(async () => { - var fileTypes = -#if __MOBILE__ - (FilePickerFileType?)null; -#else - new FilePickerFilter(new (string, IEnumerable)[] { - ("Data Files", new[] { "dat" }), - ("All Files", new[] { "*" }), - }); -#endif + var fileTypes = !IsSupportedFileExtensionFilter ? (FilePickerFileType?)null : new FilePickerFilter(new (string, IEnumerable)[] { + ("Data Files", new[] { "dat" }), + ("All Files", new[] { "*" }), + }); await PickAsync(ImportSteamPlusPlusV1, fileTypes); }); SdaBtn_Click = ReactiveCommand.CreateFromTask(async () => { - var fileTypes = -#if __MOBILE__ - (FilePickerFileType?)null; -#else - new FilePickerFilter(new (string, IEnumerable)[] { - ("MaFile Files", new[] { "maFile" }), - ("JSON Files", new[] { "json" }), - ("All Files", new[] { "*" }), - }); -#endif + var fileTypes = !IsSupportedFileExtensionFilter ? (FilePickerFileType?)null : new FilePickerFilter(new (string, IEnumerable)[] { + ("MaFile Files", new[] { "maFile" }), + ("JSON Files", new[] { "json" }), + ("All Files", new[] { "*" }), + }); await PickAsync(ImportSDA, fileTypes); }); WinAuthBtn_Click = ReactiveCommand.CreateFromTask(async () => { - var fileTypes = -#if __MOBILE__ - OperatingSystem2.IsAndroid ? + var fileTypes = OperatingSystem2.IsAndroid ? new GeneralFilePickerFileType(new[] { MediaTypeNames.TXT }) : - (FilePickerFileType?)null; -#else - new FilePickerFilter(new (string, IEnumerable)[] { - ("Text Files", new[] { "txt" }), - ("All Files", new[] { "*" }), - }); -#endif + (!IsSupportedFileExtensionFilter ? (FilePickerFileType?)null : new FilePickerFilter(new (string, IEnumerable)[] { + ("Text Files", new[] { "txt" }), + ("All Files", new[] { "*" }), + })); await PickAsync(ImportWinAuth, fileTypes); }); Initialize(); } - private GAPAuthenticatorValueDTO.SteamAuthenticator? _SteamAuthenticator; - private readonly GAPAuthenticatorValueDTO.SteamAuthenticator.EnrollState _Enroll = new() { RequiresLogin = true }; - private string? AuthPassword; - private bool AuthIsLocal; + GAPAuthenticatorValueDTO.SteamAuthenticator? _SteamAuthenticator; + readonly GAPAuthenticatorValueDTO.SteamAuthenticator.EnrollState _Enroll = new() { RequiresLogin = true }; + string? AuthPassword; + bool AuthIsLocal; - private async void Initialize() + new async void Initialize() { var auths = await repository.GetAllSourceAsync(); var hasPassword = repository.HasSecondaryPassword(auths); @@ -111,7 +86,7 @@ namespace System.Application.UI.ViewModels } else { - this.Close(); + Close(); } } AuthIsLocal = repository.HasLocal(auths); @@ -309,29 +284,30 @@ namespace System.Application.UI.ViewModels bool result = false; Task.Run(() => { -#if !__MOBILE__ - ToastService.Current.Set(AppResources.Logining); -#else + var isSupportedToastService = ToastService.IsSupported; + if (isSupportedToastService) + { + ToastService.Current.Set(AppResources.Logining); + } LoginSteamLoadingText = AppResources.Logining; -#endif result = _SteamAuthenticator.Enroll(_Enroll); -#if !__MOBILE__ - ToastService.Current.Set(); -#else + if (isSupportedToastService) + { + ToastService.Current.Set(); + } LoginSteamLoadingText = null; -#endif if (!result) { if (string.IsNullOrEmpty(_Enroll.Error) == false) { - MessageBoxCompat.Show(_Enroll.Error); + MessageBox.Show(_Enroll.Error); //ToastService.Current.Notify(_Enroll.Error); } if (_Enroll.Requires2FA == true) { - MessageBoxCompat.Show(AppResources.LocalAuth_SteamUser_Requires2FA); + MessageBox.Show(AppResources.LocalAuth_SteamUser_Requires2FA); //ToastService.Current.Notify(AppResources.LocalAuth_SteamUser_Requires2FA); return; } @@ -362,7 +338,7 @@ namespace System.Application.UI.ViewModels _Enroll.Error = null; RequiresLogin = false; - AuthService.AddOrUpdateSaveAuthenticators(new GAPAuthenticatorDTO + AuthService.Current.AddOrUpdateSaveAuthenticators(new GAPAuthenticatorDTO { Name = nameof(GamePlatform.Steam) + "(" + UserName + ")", Value = _SteamAuthenticator @@ -383,7 +359,7 @@ namespace System.Application.UI.ViewModels { error = AppResources.LocalAuth_SteamUser_Error; } - MessageBoxCompat.Show(_Enroll.Error!); + MessageBox.Show(_Enroll.Error!); return; } RequiresActivation = false; @@ -391,15 +367,15 @@ namespace System.Application.UI.ViewModels }).ContinueWith(s => { Log.Error(nameof(AddAuthWindowViewModel), s.Exception, nameof(LoginSteamImport)); - MessageBoxCompat.Show(s.Exception, "Error " + nameof(LoginSteamImport)); + MessageBox.Show(s.Exception, "Error " + nameof(LoginSteamImport)); }, TaskContinuationOptions.OnlyOnFaulted).ContinueWith(s => { _IsLogining = false; -#if !__MOBILE__ - ToastService.Current.Set(); -#else + if (ToastService.IsSupported) + { + ToastService.Current.Set(); + } LoginSteamLoadingText = null; -#endif s.Dispose(); }); } @@ -514,8 +490,18 @@ namespace System.Application.UI.ViewModels } public ICommand SppV2Btn_Click { get; } + public ICommand SppBtn_Click { get; } + public ICommand SdaBtn_Click { get; } + public ICommand WinAuthBtn_Click { get; } + + string? _LoginSteamLoadingText; + public string? LoginSteamLoadingText + { + get => _LoginSteamLoadingText; + set => this.RaiseAndSetIfChanged(ref _LoginSteamLoadingText, value); + } } -} \ No newline at end of file +} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs similarity index 97% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs index 98db97952..585196907 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/AuthTradeWindowViewModel.cs @@ -1,10 +1,9 @@ using ReactiveUI; using System; -using System.Application.Models.Abstractions; +using System.Application.Models; using System.Application.UI.Resx; using System.Collections.Generic; using System.Text; -using System.Application.Models; using System.Application.Repositories; using System.Application.Services; using System.Collections.ObjectModel; @@ -15,13 +14,11 @@ using System.Threading; using System.Threading.Tasks; using WinAuth; using DynamicData; -using AuthService = System.Application.Services.Abstractions.AuthService; -using R = System.Application.UI.Resx.Abstractions.R; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { - public abstract partial class AuthTradeWindowViewModel : MyAuthenticatorWindowViewModel + public partial class AuthTradeWindowViewModel : MyAuthenticatorWindowViewModel { public AuthTradeWindowViewModel() : base() { @@ -69,12 +66,19 @@ namespace System.Application.UI.ViewModels.Abstractions /// /// 是否加载确认物品图片 /// - protected abstract bool IsLoadImage { get; } + static bool IsLoadImage => IApplication.Type switch + { + IApplication.AppType.PlatformUI_Android => false, + _ => true, + }; /// /// 注册全选监听 /// - protected abstract void RegisterSelectAllObservable(); + void RegisterSelectAllObservable() + { + if (!IApplication.IsMobileLayout) return; + } private string? AuthPassword; private bool AuthIsLocal; @@ -307,7 +311,7 @@ namespace System.Application.UI.ViewModels.Abstractions if (!IsLoggedIn) { IsLoading = false; - if (!IsMobile) + if (ToastService.IsSupported) { ToastService.Current.Set(AppResources.Logining); } @@ -569,7 +573,7 @@ namespace System.Application.UI.ViewModels.Abstractions if (result == MessageBox.Result.OK) { var text = AppResources.LocalAuth_AuthTrade_ConfirmTip.Format(str); - if (!IsMobile) + if (ToastService.IsSupported) { ToastService.Current.Set(text); } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.shared.cs b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.cs similarity index 81% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.shared.cs rename to src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.cs index f4de6bd31..2dae5103f 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.shared.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/EncryptionAuthWindowViewModel.cs @@ -2,39 +2,34 @@ using ReactiveUI; using System.Application.Repositories; using System.Application.Services; using System.Application.UI.Resx; -using System.Properties; +// ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - public partial class EncryptionAuthWindowViewModel + public class EncryptionAuthWindowViewModel : WindowViewModel { - private readonly IGameAccountPlatformAuthenticatorRepository repository = DI.Get(); + public static string DisplayName => AppResources.LocalAuth_ProtectionAuth; - public static string TitleName => AppResources.LocalAuth_ProtectionAuth; + readonly IGameAccountPlatformAuthenticatorRepository repository = DI.Get(); - public EncryptionAuthWindowViewModel() : base() + public EncryptionAuthWindowViewModel() { - Title = -#if !__MOBILE__ - ThisAssembly.AssemblyTrademark + " | " + -#endif - TitleName; + Title = GetTitleByDisplayName(DisplayName); + Initialize(); } - private async void Initialize() + new async void Initialize() { var (success, password) = await AuthService.Current.HasPasswordEncryptionShowPassWordWindow(); if (!success) { - this.Close(); + Close(); } var auths = await repository.GetAllSourceAsync(); IsPasswordEncrypt = repository.HasSecondaryPassword(auths); -#if !__MOBILE__ IsOnlyCurrentComputerEncrypt = repository.HasLocal(auths); -#endif if (IsPasswordEncrypt) { Password = password; @@ -63,14 +58,12 @@ namespace System.Application.UI.ViewModels set => this.RaiseAndSetIfChanged(ref _IsPasswordEncrypt, value); } -#if !__MOBILE__ private bool _IsOnlyCurrentComputerEncrypt; public bool IsOnlyCurrentComputerEncrypt { get => _IsOnlyCurrentComputerEncrypt; set => this.RaiseAndSetIfChanged(ref _IsOnlyCurrentComputerEncrypt, value); } -#endif public async void EncryptionAuth() { @@ -107,7 +100,6 @@ namespace System.Application.UI.ViewModels return; } } -#if !__MOBILE__ else if (IsOnlyCurrentComputerEncrypt) { if (hasLocal) @@ -118,7 +110,6 @@ namespace System.Application.UI.ViewModels } VerifyPassword = null; } -#endif else { if (!hasPassword && !hasLocal) @@ -129,15 +120,9 @@ namespace System.Application.UI.ViewModels VerifyPassword = null; } - this.Close(); + Close(); - AuthService.Current.SwitchEncryptionAuthenticators( -#if !__MOBILE__ - IsOnlyCurrentComputerEncrypt -#else - false -#endif - , VerifyPassword); + AuthService.Current.SwitchEncryptionAuthenticators(IsOnlyCurrentComputerEncrypt, VerifyPassword); } } -} \ No newline at end of file +} diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.shared.cs b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.cs similarity index 87% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.shared.cs rename to src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.cs index 1de461faa..862d4de23 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.shared.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/ExportAuthWindowViewModel.cs @@ -7,22 +7,21 @@ using System.IO; using System.Linq; using System.Properties; using System.Threading.Tasks; +using System.Windows.Input; using static System.Application.FilePicker2; +// ReSharper disable once CheckNamespace namespace System.Application.UI.ViewModels { - public partial class ExportAuthWindowViewModel + public class ExportAuthWindowViewModel : WindowViewModel { - public new string Title + public static string DisplayName => AppResources.LocalAuth_ExportAuth; + + public override string Title { get { - var title = - -#if !__MOBILE__ - ThisAssembly.AssemblyTrademark + " | " + -#endif - AppResources.LocalAuth_ExportAuth; + var title = GetTitleByDisplayName(DisplayName); var mark = SelectAuthenticatorMark; if (mark != default) { @@ -30,6 +29,7 @@ namespace System.Application.UI.ViewModels } return title; } + set => throw new NotSupportedException(); } /// @@ -69,28 +69,29 @@ namespace System.Application.UI.ViewModels } } - public ExportAuthWindowViewModel() : base() + public ExportAuthWindowViewModel() { - base.Title = Title; - -#if !__MOBILE__ - SelectPathButton_Click = ReactiveCommand.CreateFromTask(async () => + if (IsSupportedSaveFileDialog) { - var result = await SaveAsync(new SaveOptions + SelectPathButton_Click = ReactiveCommand.CreateFromTask(async () => { - FileTypes = new FilePickerFilter(new (string, IEnumerable)[] { + var result = await SaveAsync(new SaveOptions + { + FileTypes = new FilePickerFilter(new (string, IEnumerable)[] { ("MsgPack Files", new[] { "mpo" }), ("Data Files", new[] { "dat" }), ("All Files", new[] { "*" }), }), - InitialFileName = DefaultExportAuthFileName, - PickerTitle = ThisAssembly.AssemblyTrademark, + InitialFileName = DefaultExportAuthFileName, + PickerTitle = ThisAssembly.AssemblyTrademark, + }); + Path = result?.FullPath; }); - Path = result?.FullPath; - }); -#endif + } } + public ICommand? SelectPathButton_Click { get; } + private bool _IsPasswordEncrypt; public bool IsPasswordEncrypt { @@ -166,7 +167,7 @@ namespace System.Application.UI.ViewModels var (success, _) = await AuthService.Current.HasPasswordEncryptionShowPassWordWindow(); if (!success) { - this.Close(); + Close(); } if (!ignorePath && string.IsNullOrEmpty(Path)) @@ -235,7 +236,7 @@ namespace System.Application.UI.ViewModels { AuthService.Current.ExportAuthenticators(Path, IsOnlyCurrentComputerEncrypt, VerifyPassword, Filter); - this.Close(); + Close(); Toast.Show(string.Format(AppResources.LocalAuth_ExportAuth_ExportSuccess, Path)); @@ -266,4 +267,4 @@ namespace System.Application.UI.ViewModels base.Dispose(disposing); } } -} \ No newline at end of file +} diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/MyAuthenticatorWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/MyAuthenticatorWindowViewModel.cs similarity index 90% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/MyAuthenticatorWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/MyAuthenticatorWindowViewModel.cs index 650d3093f..b9cab6aaa 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/MyAuthenticatorWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/MyAuthenticatorWindowViewModel.cs @@ -1,11 +1,10 @@ using System; using System.Application.Models; -using System.Application.Models.Abstractions; using System.Collections.Generic; using System.Text; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class MyAuthenticatorWindowViewModel : WindowViewModel, IExplicitHasValue { diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs similarity index 89% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs index fade1d128..2c9805293 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LocalAuthPage/ShowAuthWindowViewModel.cs @@ -1,11 +1,11 @@ using System; -using System.Application.Models.Abstractions; +using System.Application.Models; using System.Application.UI.Resx; using System.Collections.Generic; using System.Text; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { public partial class ShowAuthWindowViewModel : MyAuthenticatorWindowViewModel { diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LoginOrRegisterWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs similarity index 97% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/LoginOrRegisterWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs index 14e52369c..9529d38dc 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/LoginOrRegisterWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/LoginOrRegisterWindowViewModel.cs @@ -14,9 +14,9 @@ using Xamarin.Essentials; using static System.Application.Services.CloudService.Constants; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { - public abstract partial class LoginOrRegisterWindowViewModel : WindowViewModel, SendSmsUIHelper.IViewModel + public partial class LoginOrRegisterWindowViewModel : WindowViewModel, SendSmsUIHelper.IViewModel { public static string DisplayName => AppResources.LoginAndRegister; @@ -32,7 +32,6 @@ namespace System.Application.UI.ViewModels.Abstractions ChangeLoginState(3); await this.StartLRBAsync(channel); } -#if !__MOBILE__ else { switch (channel_) @@ -42,7 +41,6 @@ namespace System.Application.UI.ViewModels.Abstractions break; } } -#endif }); ManualLogin = ReactiveCommand.CreateFromTask(this.ManualLoginAsync); SendSms = ReactiveCommand.CreateFromTask(SendSmsAsync); @@ -63,7 +61,7 @@ namespace System.Application.UI.ViewModels.Abstractions #if DEBUG yield return FastLoginChannelViewModel.Create(nameof(FastLoginChannel.Apple), this); #endif - if (IsMobile) + if (IApplication.IsMobileLayout) { yield return FastLoginChannelViewModel.Create(FastLoginChannelViewModel.PhoneNumber, this); } @@ -139,7 +137,7 @@ namespace System.Application.UI.ViewModels.Abstractions if (_LoginState == value) return; _LoginState = value; this.RaisePropertyChanged(); - if (IsMobile) + if (IApplication.IsMobileLayout) { Title = _LoginState == 1 ? AppResources.User_PhoneLogin : AppResources.LoginAndRegister; } diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/ProxyScriptManagePage/ScriptStoreWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/ProxyScriptManagePage/ScriptStoreWindowViewModel.cs similarity index 87% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/ProxyScriptManagePage/ScriptStoreWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/ProxyScriptManagePage/ScriptStoreWindowViewModel.cs index 8839d526d..c7b04bdb1 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/ProxyScriptManagePage/ScriptStoreWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/ProxyScriptManagePage/ScriptStoreWindowViewModel.cs @@ -5,16 +5,17 @@ using System.Application.Models; using System.Application.Services; using System.Application.UI.Resx; using System.Collections.ObjectModel; -using System.Properties; using System.Reactive.Linq; using System.Linq; namespace System.Application.UI.ViewModels { public class ScriptStoreWindowViewModel : WindowViewModel { - public ScriptStoreWindowViewModel() : base() + public static string DisplayName => AppResources.ScriptStore; + + public ScriptStoreWindowViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.ScriptStore; + Title = GetTitleByDisplayName(DisplayName); _ScriptsSourceList = new SourceList(); _ScriptsSourceList @@ -33,14 +34,14 @@ namespace System.Application.UI.ViewModels }); } - private readonly ReadOnlyObservableCollection _Scripts; + readonly ReadOnlyObservableCollection _Scripts; public ReadOnlyObservableCollection Scripts => _Scripts; - private readonly SourceList _ScriptsSourceList; + readonly SourceList _ScriptsSourceList; public bool IsScriptsEmpty => !Scripts.Any_Nullable(); - private string? _SearchText; + string? _SearchText; public string? SearchText { get => _SearchText; @@ -62,7 +63,7 @@ namespace System.Application.UI.ViewModels await Browser2.OpenAsync(script.SourceLink); } - private async void InitializeScriptList() + async void InitializeScriptList() { var client = ICloudServiceClient.Instance.Script; var response = await client.ScriptTable(name: SearchText, pageSize: 100, errormsg: AppResources.ScriptShop_GetTableError); diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/SteamAccountPage/ShareManageViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/SteamAccountPage/ShareManageViewModel.cs similarity index 87% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/SteamAccountPage/ShareManageViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/SteamAccountPage/ShareManageViewModel.cs index 232cb86eb..41c53f86a 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/SteamAccountPage/ShareManageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/SteamAccountPage/ShareManageViewModel.cs @@ -3,30 +3,29 @@ using DynamicData.Binding; using Newtonsoft.Json.Linq; using ReactiveUI; using System.Application.Models; -using System.Application.Models.Settings; +using System.Application.Settings; using System.Application.Services; using System.Application.UI.Resx; using System.Collections.Generic; using System.Collections.ObjectModel; -using System.Globalization; using System.Linq; using System.Properties; using System.Reactive.Linq; using System.Threading.Tasks; -using System.Windows; -using static System.Application.Services.CloudService.Constants; namespace System.Application.UI.ViewModels { public class ShareManageViewModel : WindowViewModel { + public static string DisplayName => AppResources.AccountChange_Title; + readonly ISteamService steamService = DI.Get(); readonly IHttpService httpService = DI.Get(); readonly ISteamworksWebApiService webApiService = DI.Get(); - public ShareManageViewModel() : base() + public ShareManageViewModel() { - Title = ThisAssembly.AssemblyTrademark + " | " + AppResources.AccountChange_Title; + Title = GetTitleByDisplayName(DisplayName); this.WhenAnyValue(x => x.AuthorizedList) .Subscribe(s => this.RaisePropertyChanged(nameof(IsAuthorizedListEmpty))); @@ -44,10 +43,10 @@ namespace System.Application.UI.ViewModels public bool IsAuthorizedListEmpty => !AuthorizedList.Any_Nullable(); - private ReadOnlyObservableCollection? _AuthorizedList; + readonly ReadOnlyObservableCollection? _AuthorizedList; public ReadOnlyObservableCollection? AuthorizedList => _AuthorizedList; - private SourceCache _AuthorizedSourceList; + readonly SourceCache _AuthorizedSourceList; public void Refresh_Click() { @@ -72,6 +71,7 @@ namespace System.Application.UI.ViewModels Refresh_Cash().ConfigureAwait(false); } + public async Task Refresh_Cash() { @@ -112,9 +112,9 @@ namespace System.Application.UI.ViewModels await Browser2.OpenAsync(user.ProfileUrl); } - public void About_Click() + public async void About_Click() { - var result = MessageBoxCompat.ShowAsync(@AppResources.AccountChange_ShareManageAboutTips, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OK); + await MessageBox.ShowAsync(AppResources.AccountChange_ShareManageAboutTips, ThisAssembly.AssemblyTrademark, MessageBox.Button.OK); } public void SetFirstButton_Click(AuthorizedDevice item) @@ -157,8 +157,8 @@ namespace System.Application.UI.ViewModels { if (_AuthorizedList != null) steamService.UpdateAuthorizedDeviceList(_AuthorizedList); - var result = await MessageBoxCompat.ShowAsync(@AppResources.AccountChange_RestartSteam, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel); - if (result == MessageBoxResultCompat.OK) + var result = await MessageBox.ShowAsync(AppResources.AccountChange_RestartSteam, ThisAssembly.AssemblyTrademark, MessageBox.Button.OKCancel); + if (result.IsOK()) { steamService.TryKillSteamProcess(); steamService.StartSteam(); diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/TaskBarWindowViewModel.TrayIcon.cs b/src/ST.Client/UI/ViewModels/Windows/TaskBarWindowViewModel.TrayIcon.cs similarity index 100% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/TaskBarWindowViewModel.TrayIcon.cs rename to src/ST.Client/UI/ViewModels/Windows/TaskBarWindowViewModel.TrayIcon.cs diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/TaskBarWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/TaskBarWindowViewModel.cs similarity index 90% rename from src/ST.Client.Desktop/UI/ViewModels/Windows/TaskBarWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/TaskBarWindowViewModel.cs index d58337ae7..a893a3bb3 100644 --- a/src/ST.Client.Desktop/UI/ViewModels/Windows/TaskBarWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/TaskBarWindowViewModel.cs @@ -32,7 +32,7 @@ namespace System.Application.UI.ViewModels public TaskBarWindowViewModel() { MenuClickCommand = ReactiveCommand.Create(MenuClick); - if (IDesktopWindowViewModelManager.Instance.MainWindow is MainWindowViewModel mainwindow) + if (IViewModelManager.Instance.MainWindow is MainWindowViewModel mainwindow) { Tabs = mainwindow.TabItems.Where(x => x.Id != default); } @@ -54,13 +54,13 @@ namespace System.Application.UI.ViewModels static void OnMenuClick(Func predicate, Action? hideTaskBarWindow = null) { - if (IDesktopWindowViewModelManager.Instance.MainWindow is MainWindowViewModel main) + if (IViewModelManager.Instance.MainWindow is MainWindowViewModel main) { var tab = main.TabItems.FirstOrDefault(predicate); tab ??= main.FooterTabItems.FirstOrDefault(predicate); if (tab != null) { - DI.Get().RestoreMainWindow(); + IApplication.Instance.RestoreMainWindow(); main.SelectedItem = tab; hideTaskBarWindow?.Invoke(); } @@ -72,7 +72,7 @@ namespace System.Application.UI.ViewModels switch (tag) { case CommandExit: - DI.Get().Shutdown(); + IApplication.Instance.Shutdown(); return true; default: MainThread2.BeginInvokeOnMainThread(() => diff --git a/src/ST.Client/UI/ViewModels/Abstractions/Windows/UserProfileWindowViewModel.cs b/src/ST.Client/UI/ViewModels/Windows/UserProfileWindowViewModel.cs similarity index 98% rename from src/ST.Client/UI/ViewModels/Abstractions/Windows/UserProfileWindowViewModel.cs rename to src/ST.Client/UI/ViewModels/Windows/UserProfileWindowViewModel.cs index bee8a331d..9e5d8f898 100644 --- a/src/ST.Client/UI/ViewModels/Abstractions/Windows/UserProfileWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Windows/UserProfileWindowViewModel.cs @@ -11,9 +11,9 @@ using System.Threading.Tasks; using System.Windows.Input; // ReSharper disable once CheckNamespace -namespace System.Application.UI.ViewModels.Abstractions +namespace System.Application.UI.ViewModels { - public abstract partial class UserProfileWindowViewModel : WindowViewModel + public partial class UserProfileWindowViewModel : WindowViewModel { public static string DisplayName => AppResources.UserProfile; diff --git a/src/ST.Client.Desktop/VdfHelper.cs b/src/ST.Client/VdfHelper.cs similarity index 100% rename from src/ST.Client.Desktop/VdfHelper.cs rename to src/ST.Client/VdfHelper.cs diff --git a/src/ST.Services.CloudService.Models/Models/ScriptDTO.cs b/src/ST.Services.CloudService.Models/Models/ScriptDTO.cs index 16da3abac..4a239f9bd 100644 --- a/src/ST.Services.CloudService.Models/Models/ScriptDTO.cs +++ b/src/ST.Services.CloudService.Models/Models/ScriptDTO.cs @@ -74,7 +74,7 @@ namespace System.Application.Models var matchs = string.Join(GeneralSeparator, Regex.Matches(userScript, string.Format(DescRegex, $"@{nameof(Match)}"), RegexOptions.IgnoreCase).GetValues(s => s.Success == true)); var Includes = string.Join(GeneralSeparator, Regex.Matches(userScript, string.Format(DescRegex, $"@{Include}"), RegexOptions.IgnoreCase).GetValues(s => s.Success == true)); script.MatchDomainNames = string.IsNullOrEmpty(matchs) ? Includes : matchs; - //忽略脚本Enable启动标签默认启动 + // 忽略脚本 Enable 启动标签默认启动 //var enable = Regex.Match(userScript, string.Format(DescRegex, $"@{nameof(Enable)}"), RegexOptions.IgnoreCase).GetValue(s => s.Success == true); script.Enable = true; //script.Enable = bool.TryParse(enable, out var e) && e; diff --git a/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs b/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs index 6c9f6cd36..2eb029b2f 100644 --- a/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs +++ b/src/ST.Services.CloudService/Services/CloudService/ApiConnection.cs @@ -24,7 +24,7 @@ namespace System.Application.Services.CloudService internal sealed class ApiConnection : IApiConnection { readonly ILogger logger; - readonly IHttpPlatformHelper http_helper; + readonly IHttpPlatformHelperService http_helper; readonly IApiConnectionPlatformHelper conn_helper; readonly Lazy jsonSerializer = new(() => new JsonSerializer()); readonly IModelValidator validator; @@ -32,7 +32,7 @@ namespace System.Application.Services.CloudService public ApiConnection( ILogger logger, IApiConnectionPlatformHelper conn_helper, - IHttpPlatformHelper http_helper, + IHttpPlatformHelperService http_helper, IModelValidator validator) { this.logger = logger; diff --git a/src/ST.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs b/src/ST.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs index 6734d2f64..3db3c5ee9 100644 --- a/src/ST.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs +++ b/src/ST.Services.CloudService/Services/CloudService/CloudServiceClientBase.cs @@ -58,7 +58,7 @@ namespace System.Application.Services.CloudService public CloudServiceClientBase( ILogger logger, IHttpClientFactory clientFactory, - IHttpPlatformHelper http_helper, + IHttpPlatformHelperService http_helper, IToast toast, IAuthHelper authHelper, IOptions options, @@ -84,7 +84,7 @@ namespace System.Application.Services.CloudService #endregion } - /// + /// internal string UserAgent => http_helper.UserAgent; IAuthHelper IApiConnectionPlatformHelper.Auth => authHelper; diff --git a/src/ST/Services/IHttpService.cs b/src/ST/Services/IHttpService.cs index 80c5c3aa4..9e3074e98 100644 --- a/src/ST/Services/IHttpService.cs +++ b/src/ST/Services/IHttpService.cs @@ -16,7 +16,7 @@ namespace System.Application.Services IHttpClientFactory Factory { get; } - IHttpPlatformHelper PlatformHelper { get; } + IHttpPlatformHelperService PlatformHelper { get; } Task SendAsync( string? requestUri, diff --git a/src/Startup2.HandleGlobalException.cs b/src/Startup2.HandleGlobalException.cs index 6b12c3f99..4ce0abbaf 100644 --- a/src/Startup2.HandleGlobalException.cs +++ b/src/Startup2.HandleGlobalException.cs @@ -50,7 +50,7 @@ namespace System.Application if (!exceptions.Add(ex)) return; } - AppHelper.TrySetLoggerMinLevel(LogLevel.Trace); + IApplication.TrySetLoggerMinLevel(LogLevel.Trace); // NLog: catch any exception and log it. Logger?.Error(ex, "Stopped program because of exception, name: {1}, isTerminating: {0}", isTerminating, name); diff --git a/src/Startup2.cs b/src/Startup2.cs index b8077f7c4..bfbd67d49 100644 --- a/src/Startup2.cs +++ b/src/Startup2.cs @@ -28,7 +28,7 @@ using System.Net; using System.Diagnostics; using System.Net.Http; using Microsoft.Extensions.DependencyInjection.Extensions; -using System.Application.Models.Settings; +using System.Application.Settings; #if __ANDROID__ using Xamarin.Android.Net; using Program = System.Application.UI.MainApplication; @@ -143,7 +143,7 @@ namespace System.Application var hasSteam = level.HasFlag(DILevel.Steam); #if !UI_DEMO && !__MOBILE__ // 桌面平台服务 此项放在其他通用业务实现服务之前 - services.AddDesktopPlatformService(hasSteam, hasGUI, HasNotifyIcon); + services.AddPlatformService(hasSteam, hasGUI, HasNotifyIcon); #endif #if __MOBILE__ services.AddMobilePlatformService(hasGUI); @@ -173,12 +173,12 @@ namespace System.Application services.AddMSALPublicClientApp(AppSettings.MASLClientId); #else - services.AddSingleton(_ => PlatformApplication.Instance); - services.AddSingleton(_ => PlatformApplication.Instance); - services.TryAddSingleton(s => s.GetRequiredService()); + services.AddSingleton(_ => PlatformApplication.Instance); + services.AddSingleton(_ => PlatformApplication.Instance); + services.TryAddSingleton(_ => PlatformApplication.Instance); // 添加管理主窗口服务 - services.AddWindowService(); + services.AddViewModelManager(); // 添加主线程助手(MainThreadDesktop) services.AddMainThreadPlatformService(); @@ -204,7 +204,7 @@ namespace System.Application * - 按钮文本(ButtonText)缺少本地化翻译(Translate) * - 某些图标图片与枚举值不太匹配,例如 Information */ - services.AddShowWindowService(); + services.AddWindowManager(); #if WINDOWS // 可选项,在 Win 平台使用 WPF 实现的 MessageBox @@ -230,7 +230,7 @@ namespace System.Application services.AddPlatformHttpPlatformHelper(); #else // 添加 Http 平台助手桌面端实现 - services.TryAddDesktopHttpPlatformHelper(); + services.TryAddClientHttpPlatformHelperService(); #endif #if StartupTrace StartupTrace.Restart("DI.ConfigureDemandServices.HttpPlatformHelper"); @@ -325,7 +325,7 @@ namespace System.Application #if !__MOBILE__ if (!Program.IsMainProcess) return; #endif - services.AddNotificationService(); + services.TryAddNotificationService(); } #endif #if !__MOBILE__ @@ -364,7 +364,7 @@ namespace System.Application if (hasMainProcessRequired) { // 应用程序更新服务 - services.AddAppUpdateService(); + services.AddApplicationUpdateService(); #if StartupTrace StartupTrace.Restart("DI.ConfigureDemandServices.AppUpdateService"); #endif diff --git a/tests/Common.UnitTest.Droid.App/Common.UnitTest.Droid.App.csproj b/tests/Common.UnitTest.Droid.App/Common.UnitTest.Droid.App.csproj index 8d609b205..da6f5d23a 100644 --- a/tests/Common.UnitTest.Droid.App/Common.UnitTest.Droid.App.csproj +++ b/tests/Common.UnitTest.Droid.App/Common.UnitTest.Droid.App.csproj @@ -137,10 +137,6 @@ {d30203ac-97ab-4a51-bfa5-826251c9a28e} Common.PinyinLib.TinyPinyin - - {0073A08E-6336-4C09-99F9-2E808889D715} - Common.UnitTest.Droid - diff --git a/tests/Common.UnitTest.Droid/Common.UnitTest.Droid.csproj b/tests/Common.UnitTest.Droid/Common.UnitTest.Droid.csproj index 4191340dc..f4c990fb0 100644 --- a/tests/Common.UnitTest.Droid/Common.UnitTest.Droid.csproj +++ b/tests/Common.UnitTest.Droid/Common.UnitTest.Droid.csproj @@ -47,7 +47,6 @@ - \ No newline at end of file diff --git a/tests/ST.Client.Desktop.UnitTest/ST.Client.Desktop.UnitTest.csproj b/tests/ST.Client.Desktop.UnitTest/ST.Client.Desktop.UnitTest.csproj index 92b781a25..9e428915d 100644 --- a/tests/ST.Client.Desktop.UnitTest/ST.Client.Desktop.UnitTest.csproj +++ b/tests/ST.Client.Desktop.UnitTest/ST.Client.Desktop.UnitTest.csproj @@ -20,7 +20,6 @@ - diff --git a/tests/ST.Client.Desktop.UnitTest/SetupFixture.cs b/tests/ST.Client.Desktop.UnitTest/SetupFixture.cs index 9488d88ed..0639f51da 100644 --- a/tests/ST.Client.Desktop.UnitTest/SetupFixture.cs +++ b/tests/ST.Client.Desktop.UnitTest/SetupFixture.cs @@ -6,7 +6,7 @@ namespace System.Application [SetUpFixture] public class SetupFixture { - bool isFirstOneTimeSetUp; + //bool isFirstOneTimeSetUp; //[OneTimeSetUp] //public void OneTimeSetUp() diff --git a/tests/ST.Client.UnitTest/ST.Client.UnitTest.csproj b/tests/ST.Client.UnitTest/ST.Client.UnitTest.csproj index fa5d886f3..dc06f758a 100644 --- a/tests/ST.Client.UnitTest/ST.Client.UnitTest.csproj +++ b/tests/ST.Client.UnitTest/ST.Client.UnitTest.csproj @@ -27,7 +27,6 @@ - diff --git a/tests/ST.Client.UnitTest/SetupFixture.cs b/tests/ST.Client.UnitTest/SetupFixture.cs index e710cc58b..f0a663448 100644 --- a/tests/ST.Client.UnitTest/SetupFixture.cs +++ b/tests/ST.Client.UnitTest/SetupFixture.cs @@ -111,7 +111,7 @@ namespace System.Application } } - internal sealed class PlatformToastImpl : ToastImpl + internal sealed class PlatformToastImpl : ToastBaseImpl { public PlatformToastImpl(IToastIntercept intercept) : base(intercept) {