Compare commits

..
27 Commits
Author SHA1 Message Date
rmbgame 0509d2b843 ready 1.1.4 2021-02-23 02:34:20 +08:00
rmbgame 8aa450f25f ready 1.1.4 2021-02-23 02:33:41 +08:00
rmbgame 81aaa50508 修改更新日志从网络请求数据而不是写在程序内 2021-02-23 02:14:16 +08:00
rmbgame 927b652c42 添加steam更新的代理服务,解决部分用户steam更新无法连接网络的问题 2021-02-22 19:37:56 +08:00
rmbgame 4de1ac13f0 添加windows系统代理方式 2021-02-22 17:25:49 +08:00
Aigio Liu 46de667c17 添加Win7疑难解答程序
优化发布配置
优化电话服务
2021-02-22 17:00:10 +08:00
rmbgame 9d14dce321 Merge branch 'develop' of https://github.com/rmbadmin/SteamTools into develop 2021-02-22 03:02:15 +08:00
rmbgame ea33fa3444 优化反代速度
修复steam图片反代启动时创意工坊图片显示不了的问题
修复uplay更新反代启动时更新失败的问题
2021-02-22 03:00:13 +08:00
Aigio Liu 9b980427f6 fix 2021-02-22 01:02:42 +08:00
Aigio Liu 451d707626 Merge branch 'develop' of https://github.com/rmbadmin/SteamTools into develop 2021-02-22 01:02:24 +08:00
Aigio Liu f483a5dcba 优化 MSBuild 在 Release 时 不生成PDB
新增平台架构(win/mac/linux)
优化 发布配置
2021-02-22 01:02:19 +08:00
rmbgame 31c4111495 修复成就图标加载失败 2021-02-22 00:39:53 +08:00
rmbgame f0a14e332d ready 1.1.3 2021-02-21 21:39:02 +08:00
rmbgame 948016c84f ready 1.1.2 2021-01-29 19:10:07 +08:00
rmbgame 98da730c18 push 1.1.1 2021-01-23 00:02:52 +08:00
rmbgame ab6bfd45b7 ready 1.0.6 2021-01-12 16:25:19 +08:00
rmbgame 8abfc81ba2 ready 1.0.5 2021-01-08 09:57:34 +08:00
rmbgame d4d6c2fb51 update readme 2020-12-29 03:26:07 +08:00
rmbgame 8da01ac3dd ready 1.0.4 2020-12-28 20:35:45 +08:00
rmbgame 2ab26f7848 ready 1.0.3 2020-12-26 22:20:50 +08:00
rmbgame d646eacda1 ready 1.0.2 2020-12-21 21:54:23 +08:00
rmbgame fb029f729b ready 1.0.0 2020-12-21 21:47:08 +08:00
rmbgame 5ef6663269 delete ref lib 2020-12-21 21:36:17 +08:00
rmbgame 5c86b53000 ready 1.0.0 2020-12-17 12:10:47 +08:00
rmbgame efb6adbd9b delete ref lib 2020-12-16 10:38:03 +08:00
rmbgame 209202b5cf sync develop 2020-12-16 10:36:52 +08:00
rmbgame c0a081e226 delete ref lib 2020-12-16 10:34:52 +08:00
68 changed files with 5651 additions and 378 deletions
+4
View File
@@ -1,4 +1,8 @@
<Project>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<PropertyGroup>
<LangVersion>9.0</LangVersion>
<Nullable>enable</Nullable>
+2 -4
View File
@@ -26,14 +26,12 @@ English | [简体中文](./README.md)
5. Some game tools
- Currently there is a forced game borderless windowing, CSGO fix VAC shield.
<!--Prerequisites Microsoft Visual C++ 2015-2019 Redistributable [64 bit](https://aka.ms/vs/16/release/vc_redist.x64.exe) / [32 bit](https://aka.ms/vs/16/release/vc_redist.x86.exe)-->
## 🖥 Operating Environment
- Windows 10 1607+
- Windows 8.1 / Windows Server 2012 R2
- Prerequisites
- Microsoft Visual C++ 2015-2019 Redistributable [64 bit](https://aka.ms/vs/16/release/vc_redist.x64.exe) / [32 bit](https://aka.ms/vs/16/release/vc_redist.x86.exe)
- Windows 7 SP1 [ESU](https://docs.microsoft.com/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq)
- Prerequisites
- Microsoft Visual C++ 2015-2019 Redistributable [64 bit](https://aka.ms/vs/16/release/vc_redist.x64.exe) / [32 bit](https://aka.ms/vs/16/release/vc_redist.x86.exe)
- KB3063858 [64 bit](https://www.microsoft.com/download/details.aspx?id=47442) / [32 bit](https://www.microsoft.com/download/details.aspx?id=47409)
- ~~macOS 10.13 High Sierra Or Higher~~
<!--
@@ -47,7 +45,7 @@ English | [简体中文](./README.md)
- ~~SUSE Enterprise Linux (SLES) 12 SP2+~~
- ~~Ubuntu 20.10, 20.04, 18.04, 16.04~~
- ~~Android 5.0+~~
- ~~iOS 8.0+~~
- ~~iOS 10.0+~~
-->
## 🌎 Roadmap
+5 -4
View File
@@ -13,6 +13,8 @@
</div>
<div align="center"><img src="./resources/screenshots.jpg" /></div>
[English](./README.en.md) | 简体中文
## ✨ 功能
@@ -33,14 +35,13 @@
5. 其他游戏工具
- 目前已有强制游戏无边框窗口化,CSGO 修复 VAC 屏蔽
<!--发布配置SelfContained=true时会自动打包VC++相关程序集-->
<!--先决条件 Microsoft Visual C++ 2015-2019 Redistributable [64 位](https://aka.ms/vs/16/release/vc_redist.x64.exe) / [32 位](https://aka.ms/vs/16/release/vc_redist.x86.exe)-->
## 🖥 系统要求
- Windows 10 1607+
- Windows 8.1 / Windows Server 2012 R2
- 先决条件
- Microsoft Visual C++ 2015-2019 Redistributable [64 位](https://aka.ms/vs/16/release/vc_redist.x64.exe) / [32 位](https://aka.ms/vs/16/release/vc_redist.x86.exe)
- Windows 7 SP1 [ESU](https://docs.microsoft.com/zh-cn/troubleshoot/windows-client/windows-7-eos-faq/windows-7-extended-security-updates-faq)
- 先决条件
- Microsoft Visual C++ 2015-2019 Redistributable [64 位](https://aka.ms/vs/16/release/vc_redist.x64.exe) / [32 位](https://aka.ms/vs/16/release/vc_redist.x86.exe)
- KB3063858 [64 位](https://www.microsoft.com/zh-cn/download/details.aspx?id=47442) / [32 位](https://www.microsoft.com/zh-cn/download/details.aspx?id=47409)
- ~~macOS 10.13 High Sierra 或更高版本~~
<!--
@@ -54,7 +55,7 @@
- ~~SUSE Enterprise Linux (SLES) 12 SP2+~~
- ~~Ubuntu 20.10, 20.04, 18.04, 16.04~~
- ~~Android 5.0+~~
- ~~iOS 8.0+~~
- ~~iOS 10.0+~~
-->
## 🌎 路线图
+35 -7
View File
@@ -9,8 +9,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Common.ClientLib", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Common.CoreLib", "System.Common.CoreLib\System.Common.CoreLib.csproj", "{E7468FDD-75F7-4B08-BA47-B715BBCFCC11}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Common.DesktopLib", "System.Common.DesktopLib\System.Common.DesktopLib.csproj", "{F37D23AA-4EA9-4E07-9B3D-F966ABED046F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Common.ClientLib.Droid", "System.Common.ClientLib.Droid\System.Common.ClientLib.Droid.csproj", "{7C8D906E-426B-49AB-9072-178555370F62}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Common.ClientLib.iOS", "System.Common.ClientLib.iOS\System.Common.ClientLib.iOS.csproj", "{F8F6973C-5831-43D1-89C2-1AD543CE7408}"
@@ -59,6 +57,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Application.SteamTools.Client.Desktop.Avalonia", "System.Application.SteamTools.Client.Desktop.Avalonia\System.Application.SteamTools.Client.Desktop.Avalonia.csproj", "{4F09B6D1-3F83-45A0-AEC8-0F243E7CD263}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Application.SteamTools.Client.Desktop.Platform", "System.Application.SteamTools.Client.Desktop.Platform\System.Application.SteamTools.Client.Desktop.Platform.csproj", "{DD2973AE-D1FC-4307-AFE2-EE2945183D3D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Application.SteamTools.Client.Desktop.Platform.Linux", "System.Application.SteamTools.Client.Desktop.Platform.Linux\System.Application.SteamTools.Client.Desktop.Platform.Linux.csproj", "{D4CF08F5-8EAB-48FB-AAA3-1A221F7B2A82}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Application.SteamTools.Client.Desktop.Platform.Mac", "System.Application.SteamTools.Client.Desktop.Platform.Mac\System.Application.SteamTools.Client.Desktop.Platform.Mac.csproj", "{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Application.SteamTools.Client.Desktop.Platform.Windows", "System.Application.SteamTools.Client.Desktop.Platform.Windows\System.Application.SteamTools.Client.Desktop.Platform.Windows.csproj", "{141532E1-540E-4E50-8723-96936C191281}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Win7Troubleshoot", "Win7Troubleshoot\Win7Troubleshoot.csproj", "{60530AF8-4790-4A85-BCE2-C5673E9C601B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -77,10 +85,6 @@ Global
{E7468FDD-75F7-4B08-BA47-B715BBCFCC11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E7468FDD-75F7-4B08-BA47-B715BBCFCC11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E7468FDD-75F7-4B08-BA47-B715BBCFCC11}.Release|Any CPU.Build.0 = Release|Any CPU
{F37D23AA-4EA9-4E07-9B3D-F966ABED046F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F37D23AA-4EA9-4E07-9B3D-F966ABED046F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F37D23AA-4EA9-4E07-9B3D-F966ABED046F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F37D23AA-4EA9-4E07-9B3D-F966ABED046F}.Release|Any CPU.Build.0 = Release|Any CPU
{7C8D906E-426B-49AB-9072-178555370F62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C8D906E-426B-49AB-9072-178555370F62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C8D906E-426B-49AB-9072-178555370F62}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -131,6 +135,26 @@ Global
{4F09B6D1-3F83-45A0-AEC8-0F243E7CD263}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F09B6D1-3F83-45A0-AEC8-0F243E7CD263}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F09B6D1-3F83-45A0-AEC8-0F243E7CD263}.Release|Any CPU.Build.0 = Release|Any CPU
{DD2973AE-D1FC-4307-AFE2-EE2945183D3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD2973AE-D1FC-4307-AFE2-EE2945183D3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD2973AE-D1FC-4307-AFE2-EE2945183D3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD2973AE-D1FC-4307-AFE2-EE2945183D3D}.Release|Any CPU.Build.0 = Release|Any CPU
{D4CF08F5-8EAB-48FB-AAA3-1A221F7B2A82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4CF08F5-8EAB-48FB-AAA3-1A221F7B2A82}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4CF08F5-8EAB-48FB-AAA3-1A221F7B2A82}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4CF08F5-8EAB-48FB-AAA3-1A221F7B2A82}.Release|Any CPU.Build.0 = Release|Any CPU
{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4}.Release|Any CPU.Build.0 = Release|Any CPU
{141532E1-540E-4E50-8723-96936C191281}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{141532E1-540E-4E50-8723-96936C191281}.Debug|Any CPU.Build.0 = Debug|Any CPU
{141532E1-540E-4E50-8723-96936C191281}.Release|Any CPU.ActiveCfg = Release|Any CPU
{141532E1-540E-4E50-8723-96936C191281}.Release|Any CPU.Build.0 = Release|Any CPU
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60530AF8-4790-4A85-BCE2-C5673E9C601B}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -139,7 +163,6 @@ Global
{512B0511-41AB-444D-BAD8-E19B7D3B52CB} = {DA8EFCA8-5396-48C7-8DC0-CB28A09488D9}
{8B9F2E93-B31B-4BA7-920D-732695A473E6} = {9AF522B5-8923-41E6-8A0A-FAE8E8F83439}
{E7468FDD-75F7-4B08-BA47-B715BBCFCC11} = {D40853F1-B3C5-418A-B1D3-E0FB70B2F394}
{F37D23AA-4EA9-4E07-9B3D-F966ABED046F} = {9AF522B5-8923-41E6-8A0A-FAE8E8F83439}
{7C8D906E-426B-49AB-9072-178555370F62} = {9AF522B5-8923-41E6-8A0A-FAE8E8F83439}
{F8F6973C-5831-43D1-89C2-1AD543CE7408} = {9AF522B5-8923-41E6-8A0A-FAE8E8F83439}
{D40853F1-B3C5-418A-B1D3-E0FB70B2F394} = {2D44BDCF-B70C-4C02-BDC8-4F1DD5066A75}
@@ -158,6 +181,11 @@ Global
{D1F15D97-802E-4AA3-A4A5-B890ABE32897} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{2FFA5BCE-B3C3-46EA-8830-838C938BF814} = {1460800B-D9ED-4147-B1E7-ABF502BEF59A}
{4F09B6D1-3F83-45A0-AEC8-0F243E7CD263} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{DD2973AE-D1FC-4307-AFE2-EE2945183D3D} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{D4CF08F5-8EAB-48FB-AAA3-1A221F7B2A82} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{948C1EA8-12DB-4F8A-A190-8615DFBD9FE4} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{141532E1-540E-4E50-8723-96936C191281} = {B43459A1-709B-4623-9677-AAC2FEE4FBA3}
{60530AF8-4790-4A85-BCE2-C5673E9C601B} = {1460800B-D9ED-4147-B1E7-ABF502BEF59A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {3833E7C5-69BC-4CB3-92CE-A8854AA35D8A}
@@ -4,13 +4,14 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DefineConstants>PUBLISH;$(DefineConstants)</DefineConstants>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\Publish</PublishDir>
<PublishDir>bin\Release\Publish\linux-x64</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>True</PublishSingleFile>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>True</PublishTrimmed>
<TrimMode>link</TrimMode>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
@@ -4,13 +4,14 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DefineConstants>PUBLISH;$(DefineConstants)</DefineConstants>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\Publish</PublishDir>
<PublishDir>bin\Release\Publish\osx-x64</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<RuntimeIdentifier>osx-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>True</PublishSingleFile>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>True</PublishTrimmed>
<TrimMode>link</TrimMode>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
@@ -4,16 +4,27 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<DefineConstants>PUBLISH;$(DefineConstants)</DefineConstants>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>bin\Release\Publish</PublishDir>
<PublishDir>bin\Release\Publish\win-x64</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>True</PublishSingleFile>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>true</PublishReadyToRun>
<!--可以通过将应用程序集编译为 ReadyToRun (R2R) 格式来改进 .NET Core 应用程序的启动时间和延迟。 R2R 是一种预先 (AOT) 编译形式 https://docs.microsoft.com/zh-cn/dotnet/core/deploying/ready-to-run-->
<PublishTrimmed>True</PublishTrimmed>
<TrimMode>link</TrimMode>
<TrimmerRemoveSymbols>true</TrimmerRemoveSymbols>
<!--剪裁框架库功能 https://docs.microsoft.com/zh-cn/dotnet/core/deploying/trimming-options#trimming-framework-library-features-->
<DebuggerSupport>false</DebuggerSupport>
<EnableUnsafeBinaryFormatterSerialization>false</EnableUnsafeBinaryFormatterSerialization>
<EnableUnsafeUTF7Encoding>false</EnableUnsafeUTF7Encoding>
<SuppressTrimAnalysisWarnings>false</SuppressTrimAnalysisWarnings>
<EventSourceSupport>false</EventSourceSupport>
<HttpActivityPropagationSupport>false</HttpActivityPropagationSupport>
<UseSystemResourceKeys>true</UseSystemResourceKeys>
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
@@ -19,13 +19,24 @@
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Avalonia\System.Application.SteamTools.Client.Desktop.Avalonia.csproj" />
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform\System.Application.SteamTools.Client.Desktop.Platform.csproj" />
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop\System.Application.SteamTools.Client.Desktop.csproj" />
<ProjectReference Include="..\System.Common.CoreLib\System.Common.CoreLib.csproj" />
<ProjectReference Include="..\System.Common.DesktopLib\System.Common.DesktopLib.csproj" />
</ItemGroup>
<ItemGroup Condition=" $(RuntimeIdentifier.Contains(`win`)) Or ('$(OS)' == 'Windows_NT' And !$(DefineConstants.Contains(`PUBLISH`))) ">
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform.Windows\System.Application.SteamTools.Client.Desktop.Platform.Windows.csproj" />
</ItemGroup>
<ItemGroup Condition=" $(RuntimeIdentifier.Contains(`osx`)) Or ('$(OS)' == 'OSX' And !$(DefineConstants.Contains(`PUBLISH`))) ">
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform.Mac\System.Application.SteamTools.Client.Desktop.Platform.Mac.csproj" />
</ItemGroup>
<ItemGroup Condition=" $(RuntimeIdentifier.Contains(`linux`)) Or ('$(OS)' == 'Unix' And !$(DefineConstants.Contains(`PUBLISH`))) ">
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform.Linux\System.Application.SteamTools.Client.Desktop.Platform.Linux.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.0" />
<PackageReference Include="MessageBox.Avalonia" Version="1.0.5">
<Aliases>MessageBox_Avalonia</Aliases>
</PackageReference>
@@ -0,0 +1,97 @@
using Avalonia.Input;
using System.Collections.Generic;
namespace System.Application.UI
{
/// <summary>
/// 拖拽功能工具类
/// https://github.com/AvaloniaUI/Avalonia/blob/0.10.0-preview6/samples/ControlCatalog/Pages/DragAndDropPage.xaml.cs
/// </summary>
public static class DragDropUtil
{
public static void InitDragDrop(this IOnDragDropListener listener,
InputElement element)
{
element.PointerPressed += async (_, e)
=> await DragDrop.DoDragDrop(e, new DataObject(), DragDropEffects.Copy);
element.AddHandler(DragDrop.DropEvent, Drop);
element.AddHandler(DragDrop.DragOverEvent, DragOver);
void DragOver(object? s, DragEventArgs? e)
{
if (e?.Data == null) return;
listener.DragOver(s is InputElement el ? el : element, e);
}
void Drop(object? s, DragEventArgs? e)
{
if (e?.Data == null) return;
listener.Drop(s is InputElement el ? el : element, e);
}
}
public static void InitDragDrop(this IOnDragDropListener listener,
IEnumerable<InputElement> elements)
{
foreach (var element in elements)
{
listener.InitDragDrop(element);
}
}
public static void InitDragDrop(this IOnDragDropListener listener,
params InputElement[] elements)
{
IEnumerable<InputElement> elements_ = elements;
listener.InitDragDrop(elements_);
}
public interface IOnDragDropListener
{
void DragOver(InputElement sender, DragEventArgs e)
{
// Only allow Copy or Link as Drop Operations.
e.DragEffects &= (DragDropEffects.Copy | DragDropEffects.Link);
// Only allow if the dragged data contains text or filenames.
if (!e.Data.Contains(DataFormats.Text)
&& !e.Data.Contains(DataFormats.FileNames))
e.DragEffects = DragDropEffects.None;
}
void Drop(InputElement sender, DragEventArgs e)
{
if (e.Data.Contains(DataFormats.Text))
{
var text = e.Data.GetText();
if (text != null)
{
DropText(sender, text);
}
}
else if (e.Data.Contains(DataFormats.FileNames))
{
var fileNames = e.Data.GetFileNames();
if (fileNames != null)
{
DropFileNames(sender, fileNames);
}
}
}
/// <summary>
/// 拖拽文本
/// </summary>
/// <param name="sender"></param>
/// <param name="text"></param>
void DropText(InputElement sender, string text);
/// <summary>
/// 拖拽路径,路径可能是文件也可能是文件夹
/// </summary>
/// <param name="sender"></param>
/// <param name="fileNames"></param>
void DropFileNames(InputElement sender, IEnumerable<string> fileNames);
}
}
}
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>System.Application</RootNamespace>
<RootNamespace>System</RootNamespace>
</PropertyGroup>
<ItemGroup>
@@ -12,14 +12,20 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop\System.Application.SteamTools.Client.Desktop.csproj"/>
<ProjectReference Include="..\System.Common.CoreLib\System.Common.CoreLib.csproj"/>
<ProjectReference Include="..\System.Common.DesktopLib\System.Common.DesktopLib.csproj"/>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop\System.Application.SteamTools.Client.Desktop.csproj" />
<ProjectReference Include="..\System.Common.CoreLib\System.Common.CoreLib.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.0" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.0" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.0" />
<PackageReference Include="MessageBox.Avalonia" Version="1.0.5">
<Aliases>MessageBox_Avalonia</Aliases>
</PackageReference>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)'=='Debug'">
<PackageReference Include="Avalonia.Diagnostics" Version="0.10.0" />
</ItemGroup>
</Project>
@@ -0,0 +1,113 @@
extern alias MessageBox_Avalonia;
using Avalonia.Controls;
using MessageBox_Avalonia::MessageBox.Avalonia;
using MessageBox_Avalonia::MessageBox.Avalonia.BaseWindows.Base;
using MessageBox_Avalonia::MessageBox.Avalonia.DTO;
using MessageBox_Avalonia::MessageBox.Avalonia.Enums;
using System.Reflection;
using System.Threading.Tasks;
// ReSharper disable once CheckNamespace
namespace System.Windows
{
/// <summary>
/// 显示消息框。
/// </summary>
public static class MessageBox
{
static ButtonEnum GetButtonEnum(this MessageBoxButton button) => button switch
{
MessageBoxButton.OK => ButtonEnum.Ok,
MessageBoxButton.OKCancel => ButtonEnum.OkCancel,
MessageBoxButton.YesNo => ButtonEnum.YesNo,
MessageBoxButton.YesNoCancel => ButtonEnum.YesNoCancel,
#pragma warning disable CS0618 // 类型或成员已过时
MessageBoxButton.OkAbort => ButtonEnum.OkAbort,
MessageBoxButton.YesNoAbort => ButtonEnum.YesNoAbort,
#pragma warning restore CS0618 // 类型或成员已过时
_ => throw new ArgumentOutOfRangeException(nameof(button), $"value: {button}"),
};
static Icon GetIcon(this MessageBoxImage icon) => icon switch
{
MessageBoxImage.Asterisk => Icon.Info,
MessageBoxImage.Error => Icon.Error,
MessageBoxImage.Exclamation => Icon.Warning,
MessageBoxImage.None => Icon.None,
#pragma warning disable CS0618 // 类型或成员已过时
MessageBoxImage.Question => Icon.Info,
MessageBoxImage.Battery => Icon.Battery,
MessageBoxImage.Database => Icon.Database,
MessageBoxImage.Folder => Icon.Folder,
MessageBoxImage.Forbidden => Icon.Forbidden,
MessageBoxImage.Plus => Icon.Plus,
MessageBoxImage.Setting => Icon.Setting,
MessageBoxImage.SpeakerLess => Icon.SpeakerLess,
MessageBoxImage.SpeakerMore => Icon.SpeakerMore,
MessageBoxImage.Stop2 => Icon.Stop,
MessageBoxImage.Stopwatch => Icon.Stopwatch,
MessageBoxImage.Wifi => Icon.Wifi,
#pragma warning restore CS0618 // 类型或成员已过时
_ => throw new ArgumentOutOfRangeException(nameof(icon), $"value: {icon}"),
};
static MessageBoxResult GetResult(this ButtonResult result) => result switch
{
ButtonResult.Ok => MessageBoxResult.OK,
ButtonResult.Yes => MessageBoxResult.Yes,
ButtonResult.No => MessageBoxResult.No,
#pragma warning disable CS0618 // 类型或成员已过时
ButtonResult.Abort => MessageBoxResult.Abort,
#pragma warning restore CS0618 // 类型或成员已过时
ButtonResult.Cancel => MessageBoxResult.Cancel,
ButtonResult.None => MessageBoxResult.None,
_ => throw new ArgumentOutOfRangeException(nameof(result), $"value: {result}"),
};
/// <summary>
/// 显示一个消息框,该消息框包含消息、标题栏标题、按钮和图标,并且返回结果。
/// </summary>
/// <param name="messageBoxText">一个 <see cref="string"/>,用于指定要显示的文本。</param>
/// <param name="caption">一个 <see cref="string"/>,用于指定要显示的标题栏标题。</param>
/// <param name="button">一个 <see cref="MessageBoxButton"/> 值,用于指定要显示哪个按钮或哪些按钮。</param>
/// <param name="icon">一个 <see cref="MessageBoxImage"/> 值,用于指定要显示的图标。</param>
/// <returns>一个 <see cref="MessageBoxResult"/> 值,用于指定用户单击了哪个消息框按钮。</returns>
public static async Task<MessageBoxResult> ShowAsync(
string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon)
{
var parms = new MessageBoxStandardParams
{
ButtonDefinitions = button.GetButtonEnum(),
ContentTitle = caption,
ContentMessage = messageBoxText,
Icon = icon.GetIcon(),
Style = Style.None,
WindowStartupLocation = WindowStartupLocation.CenterScreen,
};
var msBoxStandardWindow = MessageBoxManager.GetMessageBoxStandardWindow(parms);
var window = GetWindow(msBoxStandardWindow);
if (window != null)
{
window.Topmost = true;
window.SetResizeMode(ResizeMode.NoResize);
window.SetDefaultFontFamily();
}
var result = await msBoxStandardWindow.Show();
return GetResult(result);
}
static Window? GetWindow(IMsBoxWindow<ButtonResult> window)
{
var _window = window.GetType().GetField("_window", BindingFlags.NonPublic | BindingFlags.Instance);
if (_window != null && _window.FieldType.IsSubclassOf(typeof(Window)))
{
if (_window.GetValue(window) is Window w)
{
return w;
}
}
return null;
}
}
}
@@ -0,0 +1,19 @@
// ReSharper disable once CheckNamespace
namespace System.Windows
{
/// <summary>
/// 指定显示在消息框上的按钮。 用作 <see cref="MessageBox"/>.Show... 方法的参数。
/// </summary>
public enum MessageBoxButton
{
OK = 0,
OKCancel = 1,
YesNo = 4,
YesNoCancel = 3,
[Obsolete("non-standard api")]
OkAbort = 1000,
[Obsolete("non-standard api")]
YesNoAbort = 1001,
}
}
@@ -0,0 +1,45 @@
// ReSharper disable once CheckNamespace
namespace System.Windows
{
/// <summary>
/// 指定消息框所显示的图标。
/// </summary>
public enum MessageBoxImage
{
#pragma warning disable CA1069 // 不应复制枚举值
Asterisk = 64,
Error = 16,
Exclamation = 48,
Hand = 16,
Information = 64,
None = 0,
[Obsolete("The question mark message icon is no longer recommended because it does not clearly represent a specific type of message and because the phrasing of a message as a question could apply to any message type. In addition, users can confuse the question mark symbol with a help information symbol. Therefore, do not use this question mark symbol in your message boxes. The system continues to support its inclusion only for backward compatibility.")]
Question = 32,
Stop = 16,
Warning = 48,
[Obsolete("non-standard api")]
Battery = 1000,
[Obsolete("non-standard api")]
Database,
[Obsolete("non-standard api")]
Folder,
[Obsolete("non-standard api")]
Forbidden,
[Obsolete("non-standard api")]
Plus,
[Obsolete("non-standard api")]
Setting,
[Obsolete("non-standard api")]
SpeakerLess,
[Obsolete("non-standard api")]
SpeakerMore,
[Obsolete("non-standard api")]
Stop2,
[Obsolete("non-standard api")]
Stopwatch,
[Obsolete("non-standard api")]
Wifi,
#pragma warning restore CA1069 // 不应复制枚举值
}
}
@@ -0,0 +1,18 @@
// ReSharper disable once CheckNamespace
namespace System.Windows
{
/// <summary>
/// 指定用户单击的消息框按钮。 由 <see cref="MessageBox"/>.Show... 方法返回。
/// </summary>
public enum MessageBoxResult
{
Cancel = 2,
No = 7,
None = 0,
OK = 1,
Yes = 6,
[Obsolete("non-standard api")]
Abort = 1000,
}
}
@@ -0,0 +1,32 @@
using System.Application.Services;
// ReSharper disable once CheckNamespace
namespace System.Windows
{
/// <summary>
/// 指定是否可以调整窗口大小,并在可调整大小的情况下指定如何调整窗口大小。由 SetResizeMode 使用。
/// </summary>
public enum ResizeMode
{
/// <summary>
/// 用户无法调整窗口的大小。 不显示 "最大化" 和 "最小化" 框。
/// </summary>
NoResize = IDesktopPlatformService.ResizeMode_NoResize,
/// <summary>
/// 用户只能最小化窗口并从任务栏还原。 同时显示 "最小化" 和 "最大化" 框,但只启用 "最小化" 框。
/// </summary>
CanMinimize = IDesktopPlatformService.ResizeMode_CanMinimize,
/// <summary>
/// 用户可以通过使用 "最小化" 和 "最大化" 框以及围绕窗口的可拖动轮廓来完全调整窗口的大小。 显示和启用 "最小化" 和 "最大化" 框。 (默认) 。
/// </summary>
CanResize = IDesktopPlatformService.ResizeMode_CanResize,
/// <summary>
/// 此选项具有与相同的功能 <see cref="CanResize"/> ,但会将 "调整手柄" 添加到窗口的右下角。
/// </summary>
[Obsolete("not implemented")]
CanResizeWithGrip = IDesktopPlatformService.ResizeMode_CanResizeWithGrip,
}
}
@@ -0,0 +1,75 @@
using System.Application.Services;
using System.IO;
using FontFamily = Avalonia.Media.FontFamily;
using Window = Avalonia.Controls.Window;
// ReSharper disable once CheckNamespace
namespace System.Windows
{
/// <summary>
/// 通过扩展兼容WPF部分API的内容
/// </summary>
public static partial class WpfCompatExtensions
{
static readonly Lazy<bool> lazy_has_msyh = new Lazy<bool>(() =>
{
if (DI.Platform == Platform.Windows)
{
var fontsPath = Environment.GetFolderPath(Environment.SpecialFolder.Fonts);
var msyhFilePath = Path.Combine(fontsPath, "msyh.ttc");
return File.Exists(msyhFilePath);
}
else
{
return false;
}
});
public static bool HAS_FONT_MSYH => lazy_has_msyh.Value;
public static void SetDefaultFontFamily(this Window window)
{
if (DI.Platform == Platform.Windows)
{
if (HAS_FONT_MSYH) // (版权、许可)不能在非WinOS上使用 微软雅黑字体,不可将字体嵌入程序
{
string name;
var major = Environment.OSVersion.Version.Major;
if (major > 6 || (major == 6 && Environment.OSVersion.Version.Minor >= 2))
{
name = "Microsoft YaHei UI";
}
else
{
name = "Microsoft YaHei";
}
window.FontFamily = new FontFamily(name);
}
}
}
/// <summary>
/// 设置调整大小模式。
/// </summary>
/// <param name="window"></param>
/// <param name="value"></param>
public static void SetResizeMode(this Window window, ResizeMode value)
{
var p = DI.Get<IDesktopPlatformService>();
switch (value)
{
case ResizeMode.NoResize:
case ResizeMode.CanMinimize:
window.CanResize = false;
break;
case ResizeMode.CanResize:
#pragma warning disable CS0618 // 类型或成员已过时
case ResizeMode.CanResizeWithGrip:
#pragma warning restore CS0618 // 类型或成员已过时
window.CanResize = true;
break;
}
p.SetResizeMode(window.PlatformImpl.Handle.Handle, (int)value);
}
}
}
@@ -0,0 +1,10 @@
namespace System.Application.Services.Implementation
{
internal sealed class LinuxDesktopPlatformServiceImpl : IDesktopPlatformService
{
public void SetResizeMode(IntPtr hWnd, int value)
{
}
}
}
@@ -0,0 +1,23 @@
using System;
using System.Application.Services;
using System.Application.Services.Implementation;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDesktopPlatformService(this IServiceCollection services)
{
if (DI.Platform == Platform.Linux)
{
services.AddSingleton<IDesktopPlatformService, LinuxDesktopPlatformServiceImpl>();
}
else
{
throw new PlatformNotSupportedException();
}
return services;
}
}
}
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>System.Application.Services</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\System.Common.CoreLib\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform\System.Application.SteamTools.Client.Desktop.Platform.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,9 @@
namespace System.Application.Services.Implementation
{
internal sealed class MacDesktopPlatformServiceImpl : IDesktopPlatformService
{
public void SetResizeMode(IntPtr hWnd, int value)
{
}
}
}
@@ -0,0 +1,23 @@
using System;
using System.Application.Services;
using System.Application.Services.Implementation;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDesktopPlatformService(this IServiceCollection services)
{
if (DI.Platform == Platform.Apple)
{
services.AddSingleton<IDesktopPlatformService, MacDesktopPlatformServiceImpl>();
}
else
{
throw new PlatformNotSupportedException();
}
return services;
}
}
}
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>System.Application.Services</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\System.Common.CoreLib\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform\System.Application.SteamTools.Client.Desktop.Platform.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,90 @@
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
namespace System.Application.Services.Implementation
{
[SupportedOSPlatform("Windows")]
internal sealed class WindowsDesktopPlatformServiceImpl : IDesktopPlatformService
{
#region 窗口右上角的三个按钮(最小化,最大化,关闭)
// https://stackoverflow.com/questions/339620/how-do-i-remove-minimize-and-maximize-from-a-resizable-window-in-wpf
// https://blog.magnusmontin.net/2014/11/30/disabling-or-hiding-the-minimize-maximize-or-close-button-of-a-wpf-window/
public const int MF_BYCOMMAND = 0x00000000;
public const int SC_CLOSE = 0xF060;
public const int SC_MINIMIZE = 0xF020;
public const int SC_MAXIMIZE = 0xF030;
[DllImport("user32.dll")]
public static extern int DeleteMenu(IntPtr hMenu, int nPosition, int wFlags);
[DllImport("user32.dll")]
public static extern IntPtr GetSystemMenu(IntPtr hWnd, bool bRevert);
public const int GWL_STYLE = -16,
WS_MAXIMIZEBOX = 0x10000,
WS_MINIMIZEBOX = 0x20000;
[DllImport("user32.dll")]
public extern static int GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
public extern static int SetWindowLong(IntPtr hwnd, int index, int value);
public const int WS_SYSMENU = 0x80000;
public static void EnableMinimizeButton(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_MINIMIZEBOX);
}
public static void EnableMaximizeButton(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_MAXIMIZEBOX);
}
public static void ShowMinimizeAndMaximizeButtons(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_MAXIMIZEBOX | WS_MINIMIZEBOX);
}
public static void ShowAllButtons(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) | WS_SYSMENU);
}
public static void HideMinimizeAndMaximizeButtons(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX & ~WS_MINIMIZEBOX);
}
public static void DisableMinimizeButton(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_MINIMIZEBOX);
}
public static void DisableMaximizeButton(IntPtr hWnd)
{
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX);
}
public void SetResizeMode(IntPtr hWnd, int value)
{
switch (value)
{
case IDesktopPlatformService.ResizeMode_NoResize:
_ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MAXIMIZE, MF_BYCOMMAND);
_ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MINIMIZE, MF_BYCOMMAND);
HideMinimizeAndMaximizeButtons(hWnd);
break;
case IDesktopPlatformService.ResizeMode_CanMinimize:
_ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MAXIMIZE, MF_BYCOMMAND);
DisableMaximizeButton(hWnd);
break;
}
}
#endregion
}
}
@@ -0,0 +1,23 @@
using System;
using System.Application.Services;
using System.Application.Services.Implementation;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection AddDesktopPlatformService(this IServiceCollection services)
{
if (DI.Platform == Platform.Windows)
{
services.AddSingleton<IDesktopPlatformService, WindowsDesktopPlatformServiceImpl>();
}
else
{
throw new PlatformNotSupportedException();
}
return services;
}
}
}
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>System.Application.Services</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\System.Common.CoreLib\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform\System.Application.SteamTools.Client.Desktop.Platform.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,14 @@
using ResizeMode = System.Int32;
namespace System.Application.Services
{
public interface IDesktopPlatformService
{
void SetResizeMode(IntPtr hWnd, ResizeMode value);
public const ResizeMode ResizeMode_NoResize = 0;
public const ResizeMode ResizeMode_CanMinimize = 1;
public const ResizeMode ResizeMode_CanResize = 2;
public const ResizeMode ResizeMode_CanResizeWithGrip = 3;
}
}
@@ -0,0 +1,9 @@
namespace System.Application.Services.Implementation
{
public class DesktopPlatformServiceImpl : IDesktopPlatformService
{
public void SetResizeMode(IntPtr hWnd, int value)
{
}
}
}
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>System.Application.Services</RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\System.Common.CoreLib\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client\System.Application.SteamTools.Client.csproj" />
</ItemGroup>
</Project>
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<RootNamespace>System.Application</RootNamespace>
</PropertyGroup>
@@ -16,6 +16,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\System.Application.SteamTools.Client.Desktop.Platform\System.Application.SteamTools.Client.Desktop.Platform.csproj" />
<ProjectReference Include="..\System.Application.SteamTools.Client\System.Application.SteamTools.Client.csproj" />
</ItemGroup>
@@ -15,7 +15,7 @@ namespace System.Application.Services.Implementation
{
var telephony = XEPlatform.AppContext.GetSystemService<TelephonyManager>(Context.TelephonyService);
var value = telephony.Line1Number;
return PhoneNumberHelper.GetCNMainlandPhoneNumber11(value);
return PhoneNumberHelper.GetChineseMainlandPhoneNumber11(value);
}
}
}
@@ -45,7 +45,7 @@ namespace System.Application
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string? GetCNMainlandPhoneNumber11(string? value)
public static string? GetChineseMainlandPhoneNumber11(string? value)
{
if (!string.IsNullOrWhiteSpace(value))
{
@@ -23,13 +23,17 @@
</Compile>
<Compile Include="..\System.Common.UnitTest\Logging\*.cs">
<Link />
<LinkBase>Logging</LinkBase>
</Compile>
<Compile Include="..\System.Common.UnitTest\Utils\*.cs">
<Link />
<LinkBase>Utils</LinkBase>
</Compile>
<Compile Include="..\System.Common.UnitTest\Droid\*.cs">
<Link />
<LinkBase>Droid</LinkBase>
</Compile>
<!--https://docs.microsoft.com/zh-cn/visualstudio/msbuild/common-msbuild-item-metadata?view=vs-2019-->
</ItemGroup>
<ItemGroup>
+7
View File
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
<supportedRuntime version="v2.0.50727" />
</startup>
</configuration>
+8
View File
@@ -0,0 +1,8 @@
namespace Win7Troubleshoot
{
public static class DownloadLinks
{
public const string KB3063858_x64 = "https://www.microsoft.com/{0}/download/details.aspx?id=47442";
public const string KB3063858_x86 = "https://www.microsoft.com/{0}/download/details.aspx?id=47409";
}
}
+69
View File
@@ -0,0 +1,69 @@
// https://www.codeproject.com/questions/641314/check-64-or-32-bit-in-net-3-5
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Win7Troubleshoot
{
public static class EnvironmentEx
{
[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
internal extern static IntPtr LoadLibrary(string libraryName);
[DllImport("kernel32", SetLastError = true, CallingConvention = CallingConvention.Winapi)]
internal extern static IntPtr GetProcAddress(IntPtr hwnd, string procedureName);
delegate bool IsWow64ProcessDelegate([In] IntPtr handle, [Out] out bool isWow64Process);
public static bool Is64BitOperatingSystem
{
get
{
if (IntPtr.Size == 8 || (IntPtr.Size == 4 && Is32BitProcessOn64BitProcessor()))
{
return true;
}
else
{
return false;
}
}
}
static IsWow64ProcessDelegate GetIsWow64ProcessDelegate()
{
IntPtr handle = LoadLibrary("kernel32");
if (handle != IntPtr.Zero)
{
IntPtr fnPtr = GetProcAddress(handle, "IsWow64Process");
if (fnPtr != IntPtr.Zero)
{
return (IsWow64ProcessDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)fnPtr, typeof(IsWow64ProcessDelegate));
}
}
return null;
}
static bool Is32BitProcessOn64BitProcessor()
{
IsWow64ProcessDelegate fnDelegate = GetIsWow64ProcessDelegate();
if (fnDelegate == null)
{
return false;
}
bool retVal = fnDelegate.Invoke(Process.GetCurrentProcess().Handle, out var isWow64);
if (retVal == false)
{
return false;
}
return isWow64;
}
}
}
+143
View File
@@ -0,0 +1,143 @@
/* 适用于 Windwos 7 OS 的 疑难解答助手
* 主要逻辑:if 安装了补丁 KB3063858
* 直接运行主程序
* else 本地化文本提示未安装补丁,引导用户进行下载
* 例如:输入 y 跳转微软官方下载中心下载补丁安装后再使用本应用程序,输入 n 退出
* Win7 自带 net35 可能魔改版删除了此功能,那就没办法了
* 可在 控制面板\程序\程序和功能 - 打开或关闭 Windows 功能 - Microsoft .NET Framework 3.5.1 根据左边的勾选框,非空心即代表已安装
* 对于本程序
* 在配置文件 exe.config supportedRuntime 项中可添加net4x的支持
*/
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Win7Troubleshoot.Properties;
namespace Win7Troubleshoot
{
static class Program
{
internal static Mutex? mutex;
[STAThread]
#pragma warning disable IDE0060 // 删除未使用的参数
static void Main(string[] args)
#pragma warning restore IDE0060 // 删除未使用的参数
{
mutex = new Mutex(true, Process.GetCurrentProcess().ProcessName, out var isNotRunning);
if (isNotRunning)
{
try
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
throw new PlatformNotSupportedException();
var r = IsWin7SP1OrNotSupportedPlatform();
if (r.HasValue)
{
if (r.Value) // Win7SP1
{
if (!CheckInstalled_KB3063858())
{
if (MessageBox.Show(
SR.Not_Installed_KB3063858,
SR.Error,
MessageBoxButtons.YesNo,
MessageBoxIcon.Error) == DialogResult.Yes)
{
Open_KB3063858_DownloadLink();
}
return;
}
}
else // NotSupportedPlatform - For example, WinXP/Win2000
{
MessageBox.Show(
SR.NotSupportedPlatformError,
SR.Error,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return;
}
}
AppRun();
}
catch (Exception e)
{
MessageBox.Show(
e.ToString(),
SR.Error,
MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
/// <summary>
/// 在浏览器中打开补丁KB3063858的下载地址
/// </summary>
static void Open_KB3063858_DownloadLink()
{
var downloadLink = EnvironmentEx.Is64BitOperatingSystem ?
DownloadLinks.KB3063858_x64 : DownloadLinks.KB3063858_x86;
downloadLink = string.Format(downloadLink, CultureInfo.CurrentCulture.Name);
Process.Start(downloadLink);
}
/// <summary>
/// 检查是否安装了补丁KB3063858
/// </summary>
/// <returns></returns>
static bool CheckInstalled_KB3063858()
{
const string KB3063858 = "KB3063858";
using var p = new Process();
p.StartInfo.FileName = "cmd";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardInput = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.CreateNoWindow = true;
p.Start();
p.StandardInput.WriteLine("wmic qfe&exit");
p.StandardInput.AutoFlush = true;
var str = p.StandardOutput.ReadToEnd();
p.WaitForExit();
return str.Contains(KB3063858);
}
/// <summary>
/// 启动主APP
/// </summary>
static void AppRun()
{
var fileName = Process.GetCurrentProcess().MainModule.FileName;
fileName = fileName.Replace(".win7", string.Empty, StringComparison.OrdinalIgnoreCase);
if (string.IsNullOrEmpty(fileName) || !File.Exists(fileName)) return;
Process.Start(fileName);
}
/// <summary>
/// 返回结果:
/// <para><see langword="true"/> 当前运行的操作系统为 Win7SP1</para>
/// <para><see langword="false"/> 当前运行的操作系统不支持 </para>
/// <para><see langword="null"/> 当前运行的操作系统为Win8或更高</para>
/// </summary>
/// <returns></returns>
static bool? IsWin7SP1OrNotSupportedPlatform()
{
if (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor == 1)
{
return Environment.OSVersion.ServicePack == "Service Pack 1";
}
if (Environment.OSVersion.Version.Major < 6)
{
return false;
}
return null;
}
}
}
+90
View File
@@ -0,0 +1,90 @@
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Win7Troubleshoot.Properties {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[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 {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal SR() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Win7Troubleshoot.Properties.SR", typeof(SR).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找类似 错误 的本地化字符串。
/// </summary>
internal static string Error {
get {
return ResourceManager.GetString("Error", resourceCulture);
}
}
/// <summary>
/// 查找类似 操作系统中缺少必要的补丁 KB3063858 导致程序无法运行,是否使用浏览器打开下载地址并手动安装? 的本地化字符串。
/// </summary>
internal static string Not_Installed_KB3063858 {
get {
return ResourceManager.GetString("Not_Installed_KB3063858", resourceCulture);
}
}
/// <summary>
/// 查找类似 操作系统最低需要 Windows 7 SP1 的本地化字符串。
/// </summary>
internal static string NotSupportedPlatformError {
get {
return ResourceManager.GetString("NotSupportedPlatformError", resourceCulture);
}
}
}
}
+129
View File
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Error" xml:space="preserve">
<value>Error</value>
</data>
<data name="NotSupportedPlatformError" xml:space="preserve">
<value>The minimum requirement of operating system is Windows 7 SP1</value>
</data>
<data name="Not_Installed_KB3063858" xml:space="preserve">
<value>Due to the lack of necessary patch KB3063858 in the operating system, the program cannot run. Do you want to open the download address with a browser and install it manually?</value>
</data>
</root>
+129
View File
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Error" xml:space="preserve">
<value>错误</value>
</data>
<data name="NotSupportedPlatformError" xml:space="preserve">
<value>操作系统最低需要 Windows 7 SP1</value>
</data>
<data name="Not_Installed_KB3063858" xml:space="preserve">
<value>操作系统中缺少必要的补丁 KB3063858 导致程序无法运行,是否使用浏览器打开下载地址并手动安装?</value>
</data>
</root>
+129
View File
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Error" xml:space="preserve">
<value>錯誤</value>
</data>
<data name="NotSupportedPlatformError" xml:space="preserve">
<value>作業系統最低需要Windows 7 SP1</value>
</data>
<data name="Not_Installed_KB3063858" xml:space="preserve">
<value>作業系統中缺少必要的補丁 KB3063858 導致程式無法運行,是否使用瀏覽器打開下載地址並手動安裝?</value>
</data>
</root>
+105
View File
@@ -0,0 +1,105 @@
using System.Diagnostics;
using System.Text;
// ReSharper disable once CheckNamespace
namespace System
{
public static partial class StringExtensions
{
/// <summary>
/// Returns a new string in which all occurrences of a specified string in the current instance are replaced with another
/// specified string according the type of search to use for the specified string.
/// </summary>
/// <param name="str">The string performing the replace method.</param>
/// <param name="oldValue">The string to be replaced.</param>
/// <param name="newValue">The string replace all occurrences of <paramref name="oldValue"/>.
/// If value is equal to <c>null</c>, than all occurrences of <paramref name="oldValue"/> will be removed from the <paramref name="str"/>.</param>
/// <param name="comparisonType">One of the enumeration values that specifies the rules for the search.</param>
/// <returns>A string that is equivalent to the current string except that all instances of <paramref name="oldValue"/> are replaced with <paramref name="newValue"/>.
/// If <paramref name="oldValue"/> is not found in the current instance, the method returns the current instance unchanged.</returns>
[DebuggerStepThrough]
public static string Replace(this string str,
string oldValue, string @newValue,
StringComparison comparisonType)
{
// https://stackoverflow.com/questions/6275980/string-replace-ignoring-case
// Check inputs.
if (str == null)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentNullException(nameof(str));
}
if (str.Length == 0)
{
// Same as original .NET C# string.Replace behavior.
return str;
}
if (oldValue == null)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentNullException(nameof(oldValue));
}
if (oldValue.Length == 0)
{
// Same as original .NET C# string.Replace behavior.
throw new ArgumentException("String cannot be of zero length.");
}
//if (oldValue.Equals(newValue, comparisonType))
//{
//This condition has no sense
//It will prevent method from replacesing: "Example", "ExAmPlE", "EXAMPLE" to "example"
//return str;
//}
// Prepare string builder for storing the processed string.
// Note: StringBuilder has a better performance than String by 30-40%.
StringBuilder resultStringBuilder = new StringBuilder(str.Length);
// Analyze the replacement: replace or remove.
bool isReplacementNullOrEmpty = string.IsNullOrEmpty(@newValue);
// Replace all values.
const int valueNotFound = -1;
int foundAt;
int startSearchFromIndex = 0;
while ((foundAt = str.IndexOf(oldValue, startSearchFromIndex, comparisonType)) != valueNotFound)
{
// Append all characters until the found replacement.
int @charsUntilReplacment = foundAt - startSearchFromIndex;
bool isNothingToAppend = @charsUntilReplacment == 0;
if (!isNothingToAppend)
{
resultStringBuilder.Append(str, startSearchFromIndex, @charsUntilReplacment);
}
// Process the replacement.
if (!isReplacementNullOrEmpty)
{
resultStringBuilder.Append(@newValue);
}
// Prepare start index for the next search.
// This needed to prevent infinite loop, otherwise method always start search
// from the start of the string. For example: if an oldValue == "EXAMPLE", newValue == "example"
// and comparisonType == "any ignore case" will conquer to replacing:
// "EXAMPLE" to "example" to "example" to "example" … infinite loop.
startSearchFromIndex = foundAt + oldValue.Length;
if (startSearchFromIndex == str.Length)
{
// It is end of the input string: no more space for the next search.
// The input string ends with a value that has already been replaced.
// Therefore, the string builder with the result is complete and no further action is required.
return resultStringBuilder.ToString();
}
}
// Append the last part to the result.
int @charsUntilStringEnd = str.Length - startSearchFromIndex;
resultStringBuilder.Append(str, startSearchFromIndex, @charsUntilStringEnd);
return resultStringBuilder.ToString();
}
}
}
+39
View File
@@ -0,0 +1,39 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<PlatformTarget>AnyCPU</PlatformTarget>
<TargetFramework>net35</TargetFramework>
<ApplicationIcon>..\System.Application.SteamTools.Client.Desktop.Avalonia.App\Assets\Icon.ico</ApplicationIcon>
<AssemblyName>Steam++.Win7</AssemblyName>
<ApplicationManifest>..\System.Application.SteamTools.Client.Desktop.Avalonia.App\Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\System.Common.CoreLib\Properties\AssemblyInfo.cs">
<Link>Properties\AssemblyInfo.cs</Link>
</Compile>
<Compile Include="..\System.Common.CoreLib\Properties\ThisAssembly.cs">
<Link>Properties\ThisAssembly.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\SR.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>SR.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\SR.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>SR.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
</Project>
+14 -16
View File
@@ -13,16 +13,14 @@ Steam++只在keylol论坛与github发布,为了账号安全,请不要到其
## 更新内容
### 1.1.2
### 1.1.3
```
新增在账号切换的状态栏右下角位置登录新账号功能
账号切换功能可以实时刷新获取Steam新登录的账号数据
关于里加入FAQ常见问题疑难解答
修改谷歌验证码代理方式为全局跳转www.recaptcha.net
记录更详细错误日志
修复某些情况下开机自启失效问题
修复配置文件加载时提示根元素错误
配置文件备份机制完善,如果配置文件出错会提示还原上次读取成功的配置
修改部分提示文本,修复证书生成安装失败
修改证书生成方式避免324错误和100错误
修复faq文本错误
修复在某些情况下出现算法不同证书验证错误问题
库存游戏列表添加clienticon图标显示
准备制作跨平台版本支持Linux和Mac OS...
```
@@ -109,12 +107,12 @@ Steam++只在keylol论坛与github发布,为了账号安全,请不要到其
> [Github](https://github.com/rmbadmin/SteamTools/releases)
> 分流下载:
> [hide]
> [蓝奏云](https://wws.lanzous.com/ioCJnl1hdli)
> [百度云](https://pan.baidu.com/s/1j8Y2a-8X7tpa5BnEFLOxbg)
> 提取码:stpp
> [蓝奏云](https://wws.lanzous.com/iFkh4lyooeh)
> [百度云](https://pan.baidu.com/s/1HWbCnTLNnLiOObVLn9aTiQ)
> 提取码:ytrq
> [/hide]
> EXE 大小:4.88MB
> EXE MD5:023FB09444B774354827C0A7D6547DEE
> ZIP MD5:51D8921256DF485FBE9F4AF3F05E2564
> [查毒链接](https://www.virustotal.com/gui/file/9931d6034c3b8f6c362ecb991a21d205623734fbee201e62f813d05f50347e64/detection)
> EXE 大小:4.97MB
> EXE MD5:4F61CA2F44C684FCF4628801474655C7
> ZIP MD5:CDF061F677BAAA2BF1F465BFD4026C23
> [查毒链接](https://www.virustotal.com/gui/file/8d6da4a3fe7b1738aa5725e9797a86f8b5c668920d1449594279ea7bb262e4ef/detection)
虽然没有什么杀毒软件报毒,但是使用过程中可能遇到windows defender误报,您可以选择添加信任。
Binary file not shown.

After

Width:  |  Height:  |  Size: 736 KiB

+2 -1
View File
@@ -12,6 +12,7 @@ namespace SteamTool.Model
public const string HOST_TAG = "#Steam++";
public const string REWARDMELIST_URL = "https://gitee.com/rmbgame/steam-tools_-data/raw/master/RewardRecord.json";
public const string UPDATEHISTORY_URL = "https://gitee.com/rmbgame/steam-tools_-data/raw/master/UpdateHistory";
//public const string REWARDMELIST_URL = "https://raw.githubusercontent.com/rmbadmin/SteamTools/develop/Data/RewardRecord.json";
public const string GITHUB_LATEST_RELEASEAPI_URL = "https://api.github.com/repos/rmbadmin/SteamTools/releases/latest";
@@ -28,7 +29,7 @@ namespace SteamTool.Model
public const string STEAMAPP_LIST_URL = "https://api.steampowered.com/ISteamApps/GetAppList/v2";
public const string STORE_APP_URL = "https://store.steampowered.com/app/{0}";
public const string STEAMAPP_LOGO_URL = "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/{0}/{1}.jpg";
public const string STEAMAPP_ICON_URL = "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/{0}/{1}.jpg";
public const string STEAMAPP_ICON_URL = "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/{0}/{1}";
public const string STEAMAPP_CAPSULE_URL = "https://steamcdn-a.akamaihd.net/steam/apps/{0}/capsule_184x69.jpg";
public const string STEAMAPP_HEADIMAGE_URL = "https://steamcdn-a.akamaihd.net/steam/apps/{0}/header.jpg";
public const string STEAM_MEDIA_URL = "https://steamcdn-a.akamaihd.net/steam/apps/{0}/movie_max.webm";
@@ -32,7 +32,7 @@ namespace SteamTool.Model
public string HeaderLogoUrl => string.Format(Const.STEAMAPP_CAPSULE_URL, AppId);
public string IconUrl => string.IsNullOrEmpty(Icon) ? null : string.Format(Const.STEAMAPP_ICON_URL, AppId, Icon);
public string IconUrl => string.IsNullOrEmpty(Icon) ? null : string.Format(Const.STEAMAPP_LOGO_URL, AppId, Icon);
public Process Process { get; set; }
+63 -49
View File
@@ -42,7 +42,7 @@ namespace SteamTool.Proxy
proxyServer.CertificateManager.PfxFilePath = Path.Combine(AppContext.BaseDirectory, $@"{CertificateName}.Certificate.pfx");
proxyServer.CertificateManager.RootCertificateIssuerName = $"{CertificateName} Certificate Authority";
proxyServer.CertificateManager.RootCertificateName = $"{CertificateName} Certificate";
proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastle;
proxyServer.CertificateManager.CertificateEngine = Titanium.Web.Proxy.Network.CertificateEngine.BouncyCastleFast;
}
public bool ProxyRunning => proxyServer.ProxyRunning;
@@ -77,17 +77,6 @@ namespace SteamTool.Proxy
Debug.WriteLine("OnRequest HTTP " + e.HttpClient.Request.HttpVersion);
//Logger.Info("OnRequest" + e.HttpClient.Request.RequestUri.AbsoluteUri);
#endif
// Dns.GetHostAddressesAsync(e.HttpClient.Request.Host).ContinueWith(s =>
//{
// //部分运营商将奇怪的域名解析到127.0.0.1 再此排除这些不支持的代理域名
// if (IPAddress.IsLoopback(s.Result.FirstOrDefault())
// && ProxyDomains.Count(w => w.IsEnable && w.Hosts.Contains(e.HttpClient.Request.Host)) == 0)
// {
// e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} \r\n not support proxy");
// return;
// }
//});
//Logger.Info("Steam++ OnRequest: " + e.HttpClient.Request.RequestUri.AbsoluteUri);
foreach (var item in ProxyDomains)
{
if (!item.IsEnable)
@@ -142,8 +131,20 @@ namespace SteamTool.Proxy
}
}
//没有匹配到的结果直接返回不支持,避免出现Loopback死循环内存溢出
e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} {Environment.NewLine}not support proxy");
await Dns.GetHostAddressesAsync(e.HttpClient.Request.Host).ContinueWith(s =>
{
//部分运营商将奇怪的域名解析到127.0.0.1 再此排除这些不支持的代理域名
if (IPAddress.IsLoopback(s.Result.FirstOrDefault())
&& ProxyDomains.Count(w => w.IsEnable && w.Hosts.Contains(e.HttpClient.Request.Host)) == 0)
{
e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} \r\n not support proxy");
return;
}
Logger.Info("Steam++ IsLoopback OnRequest: " + e.HttpClient.Request.RequestUri.AbsoluteUri);
});
////没有匹配到的结果直接返回不支持,避免出现Loopback死循环内存溢出
//e.Ok($"URL : {e.HttpClient.Request.RequestUri.AbsoluteUri} {Environment.NewLine}not support proxy");
return;
}
public async Task OnResponse(object sender, SessionEventArgs e)
@@ -218,8 +219,6 @@ namespace SteamTool.Proxy
foreach (var req in script.Require)
{
var headIndex = doc.LastIndexOf("</head>", StringComparison.OrdinalIgnoreCase);
//<script type="text/javascript" src=""></script>
//var result = await httpServices.Get(req);
var temp1 = $"<script type=\"text/javascript\" src=\"{req}\"></script>\n";
doc = doc.Insert(headIndex, temp1);
}
@@ -272,7 +271,7 @@ namespace SteamTool.Proxy
if (!result)
{
Logger.Error("创建证书失败");
return false;
}
proxyServer.CertificateManager.RootCertificate.SaveCerCertificateFile(Path.Combine(AppContext.BaseDirectory, $@"{CertificateName}.Certificate.cer"));
proxyServer.CertificateManager.EnsureRootCertificate();
@@ -332,7 +331,7 @@ namespace SteamTool.Proxy
return inUse;
}
public bool StartProxy(bool IsProxyGOG = false)
public bool StartProxy(bool IsProxyGOG = false, bool IsWindowsProxy = false)
{
if (!IsCertificateInstalled(proxyServer.CertificateManager.RootCertificate))
{
@@ -348,27 +347,6 @@ namespace SteamTool.Proxy
}
if (IsProxyGOG) { WirtePemCertificateToGoGSteamPlugins(); }
#region 写入Hosts
var hosts = new List<(string, string)>();
foreach (var proxyDomain in ProxyDomains)
{
if (proxyDomain.IsEnable)
{
foreach (var host in proxyDomain.Hosts)
{
if (host.Contains(" "))
{
var h = host.Split(' ');
hosts.Add((h[0], h[1]));
}
else
hosts.Add((IPAddress.Loopback.ToString(), host));
}
}
}
hostsService.UpdateHosts(hosts);
#endregion
#region 启动代理
proxyServer.BeforeRequest += OnRequest;
proxyServer.BeforeResponse += OnResponse;
@@ -381,16 +359,46 @@ namespace SteamTool.Proxy
// // 当代理客户端不需要证书信任时非常有用
// //GenericCertificate = new X509Certificate2(Path.Combine(AppContext.BaseDirectory, "genericcert.pfx"), "password")
//};
//当接收到连接请求时触发
//explicitEndPoint.BeforeTunnelConnectRequest += OnBeforeTunnelRequest;
//explicit endpoint 是客户端知道代理存在的地方
//proxyServer.AddEndPoint(explicitEndPoint);
proxyServer.AddEndPoint(new TransparentProxyEndPoint(IPAddress.Any, 443, true)
var explicitProxyEndPoint = new ExplicitProxyEndPoint(IPAddress.Any, 26501, true)
{
// 通过不启用为每个http的域创建证书来优化性能
//GenericCertificate = proxyServer.CertificateManager.RootCertificate
});
proxyServer.AddEndPoint(new TransparentProxyEndPoint(IPAddress.Any, 80, true));
};
if (IsWindowsProxy)
{
//explicit endpoint 是客户端知道代理存在的地方
proxyServer.AddEndPoint(explicitProxyEndPoint);
}
else
{
#region 写入Hosts
var hosts = new List<(string, string)>();
foreach (var proxyDomain in ProxyDomains)
{
if (proxyDomain.IsEnable)
{
foreach (var host in proxyDomain.Hosts)
{
if (host.Contains(" "))
{
var h = host.Split(' ');
hosts.Add((h[0], h[1]));
}
else
hosts.Add((IPAddress.Loopback.ToString(), host));
}
}
}
hostsService.UpdateHosts(hosts);
#endregion
proxyServer.AddEndPoint(new TransparentProxyEndPoint(IPAddress.Any, 443, true)
{
// 通过不启用为每个http的域创建证书来优化性能
//GenericCertificate = proxyServer.CertificateManager.RootCertificate
});
proxyServer.AddEndPoint(new TransparentProxyEndPoint(IPAddress.Any, 80, false));
}
proxyServer.ExceptionFunc = ((Exception exception) =>
{
Logger.Error(exception);
@@ -405,9 +413,13 @@ namespace SteamTool.Proxy
Logger.Error(ex);
return false;
}
//proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 8888 };
if (IsWindowsProxy)
{
proxyServer.SetAsSystemHttpProxy(explicitProxyEndPoint);
proxyServer.SetAsSystemHttpsProxy(explicitProxyEndPoint);
//proxyServer.UpStreamHttpProxy = new ExternalProxy() { HostName = "localhost", Port = 26501 };
//proxyServer.UpStreamHttpsProxy = new ExternalProxy() { HostName = "localhost", Port = 26501 };
}
#endregion
#if DEBUG
foreach (var endPoint in proxyServer.ProxyEndPoints)
@@ -426,6 +438,8 @@ namespace SteamTool.Proxy
proxyServer.BeforeResponse -= OnResponse;
//proxyServer.ServerCertificateValidationCallback -= OnCertificateValidation;
//proxyServer.ClientCertificateSelectionCallback -= OnCertificateSelection;
proxyServer.DisableSystemHttpProxy();
proxyServer.DisableSystemHttpsProxy();
proxyServer.Stop();
hostsService.RemoveHostsByTag();
}
@@ -91,5 +91,7 @@ namespace SteamTool.Proxy
PixivImage = 15,
[Description("steam图片上传(聊天\\截图)")]
SteamImageUpload = 16,
[Description("steam更新")]
SteamMeidia = 17,
}
}
+9
View File
@@ -186,6 +186,15 @@ namespace SteamTool.Proxy.Properties {
}
}
/// <summary>
/// 查找类似 Steam更新 的本地化字符串。
/// </summary>
public static string SteamMeidia {
get {
return ResourceManager.GetString("SteamMeidia", resourceCulture);
}
}
/// <summary>
/// 查找类似 Steam商店 的本地化字符串。
/// </summary>
@@ -159,6 +159,9 @@
<data name="SteamImageUpload" xml:space="preserve">
<value>Steam图片上传(聊天\截图)</value>
</data>
<data name="SteamMeidia" xml:space="preserve">
<value>Steam更新</value>
</data>
<data name="SteamStore" xml:space="preserve">
<value>Steam商店</value>
</data>
+2 -5
View File
@@ -23,9 +23,6 @@ using SteamTools.Models.Settings;
using SteamTools.ViewModels;
using SteamTool.Core;
using Microsoft.Win32;
using Microsoft.AppCenter;
using Microsoft.AppCenter.Analytics;
using Microsoft.AppCenter.Crashes;
namespace SteamTools
{
@@ -78,8 +75,8 @@ namespace SteamTools
/// <param name="e"></param>
protected override void OnStartup(StartupEventArgs e)
{
AppCenter.Start("ccca922e-40fe-48ab-9982-45ba496b1201",
typeof(Analytics), typeof(Crashes));
//AppCenter.Start("ccca922e-40fe-48ab-9982-45ba496b1201",
//typeof(Analytics), typeof(Crashes));
#if !DEBUG
var appInstance = new MetroTrilithon.Desktop.ApplicationInstance().AddTo(this);
if (appInstance.IsFirst)
@@ -15,6 +15,12 @@ namespace SteamTools.Models.Settings
public static SerializableProperty<bool> IsProxyGOG { get; }
= new SerializableProperty<bool>(GetKey(), Providers.Local, false) { AutoSave = true };
/// <summary>
/// 启用GOG代理
/// </summary>
public static SerializableProperty<bool> EnableWindowsProxy { get; }
= new SerializableProperty<bool>(GetKey(), Providers.Local, false) { AutoSave = true };
/// <summary>
/// 启用代理脚本
/// </summary>
Binary file not shown.
+11 -2
View File
@@ -438,6 +438,15 @@ namespace SteamTools.Properties {
}
}
/// <summary>
/// 查找类似 Windows系统代理方式 的本地化字符串。
/// </summary>
public static string EnableWindowsProxy {
get {
return ResourceManager.GetString("EnableWindowsProxy", resourceCulture);
}
}
/// <summary>
/// 查找类似 EPIC 的本地化字符串。
/// </summary>
@@ -880,7 +889,7 @@ namespace SteamTools.Properties {
}
/// <summary>
/// 查找类似 脚本列表 的本地化字符串。
/// 查找类似 脚本列表(启动加速后脚本才会生效) 的本地化字符串。
/// </summary>
public static string ScriptList {
get {
@@ -889,7 +898,7 @@ namespace SteamTools.Properties {
}
/// <summary>
/// 查找类似 脚本配置(启动加速后脚本才会生效) 的本地化字符串。
/// 查找类似 脚本配置 的本地化字符串。
/// </summary>
public static string ScriptSettings {
get {
+5 -2
View File
@@ -243,6 +243,9 @@
<data name="EnableScriptService" xml:space="preserve">
<value>启用脚本</value>
</data>
<data name="EnableWindowsProxy" xml:space="preserve">
<value>Windows系统代理方式</value>
</data>
<data name="Epic" xml:space="preserve">
<value>EPIC</value>
</data>
@@ -391,10 +394,10 @@
<value>成就解锁</value>
</data>
<data name="ScriptList" xml:space="preserve">
<value>脚本列表</value>
<value>脚本列表(启动加速后脚本才会生效)</value>
</data>
<data name="ScriptSettings" xml:space="preserve">
<value>脚本配置(启动加速后脚本才会生效)</value>
<value>脚本配置</value>
</data>
<data name="Search" xml:space="preserve">
<value>搜索</value>
+12 -4
View File
@@ -58,13 +58,21 @@ IsEnable= true,
},
new ProxyDomainModel{
Name=Resources.SteamStore,
Domains = new List<string>{"steampowered.com" },
Domains = new List<string>{"store.steampowered.com","api.steampowered.com" },
ToDomain = "steamstore.rmbgame.net",
Hosts = new List<string>{ "store.steampowered.com", "api.steampowered.com"},
DomainTag = DomainTag.SteamStore,
IsEnable= false,
},
new ProxyDomainModel{
Name=Resources.SteamMeidia,
Domains = new List<string>{"media.steampowered.com" },
ToDomain = "steammedia.rmbgame.net",
Hosts = new List<string>{ "media.steampowered.com",},
DomainTag = DomainTag.SteamMeidia,
IsEnable= false,
},
new ProxyDomainModel{
Name=Resources.SteamImage,
Domains = new List<string>{"steamcdn-a.akamaihd.net","steamuserimages-a.akamaihd.net" },
//ToDomain = "cdn.akamai.steamstatic.com",
@@ -207,8 +215,8 @@ IsEnable= false,
new ProxyDomainModel{
Name=Resources.UplayUpdate,
Domains = new List<string>{"static3.cdn.ubi.com" },
//ToDomain = "ubisoftstatic3.rmbgame.net",
ProxyIPAddres = "116.211.99.137",
ToDomain = "ubisoftstatic3.rmbgame.net",
//ProxyIPAddres = "116.211.99.137",
Hosts = new List<string>{ "static3.cdn.ubi.com"},
DomainTag = DomainTag.UplayUpdate,
IsEnable= false,
@@ -403,7 +411,7 @@ IsEnable = false,
{
if (value)
{
var isRun = Proxy.StartProxy(ProxySettings.IsProxyGOG.Value);
var isRun = Proxy.StartProxy(ProxySettings.IsProxyGOG.Value, ProxySettings.EnableWindowsProxy.Value);
if (isRun)
{
StatusService.Current.Notify(SteamTools.Properties.Resources.ProxyRun);
+7 -2
View File
@@ -135,8 +135,6 @@
<PackageReference Include="LivetCask.EventListeners" Version="3.2.3.2" />
<PackageReference Include="LivetCask.Messaging" Version="3.2.3.2" />
<PackageReference Include="LivetCask.Mvvm" Version="3.2.3.2" />
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.1.0" />
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.1.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.31" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
@@ -327,6 +325,10 @@
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Pages\SteamShutdown.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Pages\SteamIdleCardPage.xaml">
<XamlRuntime>$(DefaultXamlRuntime)</XamlRuntime>
</Page>
@@ -385,6 +387,9 @@
<None Update="scripts\GM.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="scripts\Steam Economy Enhancer.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="scripts\Steam历史最低价格查询.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows;
using SteamTools.Win32;
using MetroRadiance.Interop.Win32;
using System.Diagnostics;
using SteamTool.Core.Common;
using System.Runtime.InteropServices;
using SteamTools.Services;
using SteamTool.Core;
using System.IO;
using SteamTools.Properties;
using SteamTool.Model;
using Newtonsoft.Json;
using System.Threading;
namespace SteamTools.ViewModels
{
public class AboutUpdateHistoryViewModel : Livet.ViewModel
{
private readonly HttpServices httpServices = SteamToolCore.Instance.Get<HttpServices>();
private string _UpdateHistoryText;
public string UpdateHistoryText
{
get => this._UpdateHistoryText;
set
{
if (this._UpdateHistoryText != value)
{
this._UpdateHistoryText = value;
this.RaisePropertyChanged();
}
}
}
public AboutUpdateHistoryViewModel()
{
_ = Task.Run(() =>
{
httpServices.Get(Const.UPDATEHISTORY_URL).ContinueWith(s =>
{
if (!string.IsNullOrEmpty(s.Result))
{
UpdateHistoryText = s.Result;
}
});
}).ContinueWith(s => { Logger.Error(s.Exception); WindowService.Current.ShowDialogWindow(s.Exception.Message); }, TaskContinuationOptions.OnlyOnFaulted);
}
}
}
@@ -187,12 +187,11 @@ namespace SteamTools.ViewModels
{
case SteamAppTypeEnum.Application:
case SteamAppTypeEnum.Game:
//var nApp = app.Clone();
//nApp.Process = Process.Start($"{ProductInfo.Title}.exe", app.AppId.ToString(CultureInfo.InvariantCulture));
WindowService.Current.MainWindow.Dialog("【风险提示】解锁成就可能会被游戏开发者视为作弊,并且会被成就统计网站封锁。若决定继续使用,请自行承担解锁成就带来的风险和后果。");
app.Process = Process.Start(Path.Combine(AppContext.BaseDirectory, App.Instance.ProgramName), "-app " + app.AppId.ToString(CultureInfo.InvariantCulture));
SteamConnectService.Current.RuningSteamApps.Add(app);
if (WindowService.Current.MainWindow.Dialog("【风险提示】解锁成就可能会被游戏开发者视为作弊,并且会被成就统计网站封锁。若决定继续使用,请自行承担解锁成就带来的风险和后果。"))
{
app.Process = Process.Start(Path.Combine(AppContext.BaseDirectory, App.Instance.ProgramName), "-app " + app.AppId.ToString(CultureInfo.InvariantCulture));
SteamConnectService.Current.RuningSteamApps.Add(app);
}
break;
default:
StatusService.Current.Notify(Resources.Unsupported_Operation);
@@ -34,262 +34,7 @@
TextAlignment="Left"
MaxPageWidth="900">
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.1.3" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2021-02-21" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改部分提示文本,修复证书生成安装失败" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改证书生成方式避免324错误和100错误" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复faq文本错误" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复在某些情况下出现算法不同证书验证错误问题"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="库存游戏列表添加clienticon图标显示 "></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="准备制作跨平台版本支持Linux和Mac OS..." />
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.1.2" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2021-01-29" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增账号切换在账号切换的状态栏右下角位置登录新账号功能" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="账号切换功能可以实时刷新获取Steam新登录的账号数据" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="关于里加入FAQ常见问题疑难解答"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改谷歌验证码代理方式为全局跳转www.recaptcha.net"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="记录更详细错误日志" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复某些情况下开机自启失效问题"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复配置文件加载时提示根元素错误"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="配置文件备份机制完善,如果配置文件出错会提示还原上次读取成功的配置"></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.1.0" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2021-01-22" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="本地令牌市场交易确认功能上线" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增内置steam史低查询脚本" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增Steam启动消息通知设置项"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增github gist代理服务支持"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复设置文件的错误存储" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复discord更新下载和图片失效"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复twitch聊天频道连接失效"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复gihub头像资源加载失败"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增pixiv图片的代理选项来修复pixiv图片失效"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="还修复了一些没有记下来的bug..."></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.6" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2021-01-12" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增启用日志记录设置项(反馈bug时一起提交方便排查问题)" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复twitch反代聊天连接错误和直播视频无法观看" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="放宽令牌同步时网络请求超时时间以降低令牌同步时提示超时概率" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改生成的cer证书编码格式为utf8,解决火狐无法导入cer证书"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="增加80端口反代,以便自动跳转http访问到https请求上"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改了用户信息获取的api为steam官方社区api(没有启动软件的自动代理服务的话依然加载不出头像。)"></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.5" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2021-01-08" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="优化反代过程的逻辑" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="增加启动时自动运行Steam的设置项" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增令牌刷新功能" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="帐户切换增加了离线模式启动的选项"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复因为第三方steamdb api挂掉导致程序崩溃"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复刷新游戏缓存按钮程序闪退BUG"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="还修复了一些没有记下来的小错误..."></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.4" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-28" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="*此版本修改了配置文件的保存读取功能,会无法读取1.0.4版本以前的配置文件包括令牌数据。(可以通过设置-令牌设置-导入旧版本Steam++令牌数据按钮来恢复旧版本令牌数据)" />
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="还原steam社区反代上游地址修复部分请求会提示需要登录的问题" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增令牌导入导出备份功能" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增令牌可以选择保存在程序根目录下的设置选项(方便备份)" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改了自动更新的提示方式"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="自动更新可以自动覆盖升级,不再需要手动替换"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复令牌无法保存的问题"></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.3" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-26" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增pixiv本地反代服务支持" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增在欢迎页steam昵称后显示steam的登陆区域" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="添加steam图片修复的本地反代支持" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复最小化恢复时UI边框错位的BUG"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复令牌编辑和导入时出现的非空报错"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="帐户切换功能的最近登陆时间从北京时间改为当前系统时区时间"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复一个因为DNS解析错误会导致程序内存溢出闪退的BUG"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="SDA令牌导入不再支持导入加密文件,如果要导入加密的maFile请先在SDA移除加密"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修改初始化的方式和steam api的连接逻辑来避免steam游戏掉帧的BUG"></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.2" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-21" FontSize="10" />
<LineBreak />
<Run Text="更新内容"></Run>
<LineBreak />
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="更新了由Benares制作的图标" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增帐户切换删除功能" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="添加github图片资源文件代理服务与discord代理服务支持" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="因为有问题暂时去掉了GOG Galaxy代理选项"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复一个会导致程序启动没有反应的bug"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="修复托盘菜单steam昵称过长ui错位bug"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增steam启动参数设置"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增启动时程序最小化到托盘菜单设置"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增捐助列表的展示"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="新增工具自动更新功能"></Run>
</Paragraph>
<Paragraph Language="zh-cn">
<Run Text="Steam++ v1.0.0" FontSize="16"/>
<Run Text="&#160;"/>
<Run Text="2020-12-14" FontSize="10" />
<LineBreak />
<Run Text="发布第一个版本" />
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="主要功能:社区反代,帐户切换,成就解锁,本地令牌。"></Run>
<LineBreak/>
<Run Text="&#160;&#160;&#160;&#160;"/>
<Run Text="次要功能:强制无边框窗口化以及CSGO VAC屏蔽修复。"></Run>
<Run Text="{Binding UpdateHistoryText}"></Run>
</Paragraph>
</FlowDocument>
</FlowDocumentScrollViewer>
+5 -1
View File
@@ -69,7 +69,11 @@
<TextBlock Text="{Binding Resources.AboutUpdateHistory,Source={x:Static services:ResourceService.Current}, Mode=OneWay}"
Style="{StaticResource TabHeaderTextStyleKey}" />
</TabItem.Header>
<contents:AboutUpdateHistory></contents:AboutUpdateHistory>
<contents:AboutUpdateHistory>
<contents:AboutUpdateHistory.DataContext>
<viewModel:AboutUpdateHistoryViewModel></viewModel:AboutUpdateHistoryViewModel>
</contents:AboutUpdateHistory.DataContext>
</contents:AboutUpdateHistory>
</TabItem>
<TabItem Visibility="Collapsed">
@@ -61,7 +61,8 @@
<StackPanel Margin="10" VerticalAlignment="Bottom">
<CheckBox Content="{Binding Resources.AutoRunProxyService,Source={x:Static services:ResourceService.Current}, Mode=OneWay}" HorizontalAlignment="Center" IsChecked="{Binding Source={x:Static ms:ProxySettings.ProgramStartupRunProxy}, Path=Value, Mode=TwoWay}"></CheckBox>
<CheckBox Content="{Binding Resources.GOG_Plugin_Support,Source={x:Static services:ResourceService.Current}, Mode=OneWay}" HorizontalAlignment="Center" IsChecked="{Binding Source={x:Static ms:ProxySettings.IsProxyGOG}, Path=Value, Mode=TwoWay}"></CheckBox>
<!--<CheckBox Content="{Binding Resources.GOG_Plugin_Support,Source={x:Static services:ResourceService.Current}, Mode=OneWay}" HorizontalAlignment="Center" IsChecked="{Binding Source={x:Static ms:ProxySettings.IsProxyGOG}, Path=Value, Mode=TwoWay}"></CheckBox>-->
<CheckBox Content="{Binding Resources.EnableWindowsProxy,Source={x:Static services:ResourceService.Current}, Mode=OneWay}" HorizontalAlignment="Center" IsChecked="{Binding Source={x:Static ms:ProxySettings.EnableWindowsProxy}, Path=Value, Mode=TwoWay}" IsEnabled="{Binding ElementName=service,Path=IsChecked,Mode=OneWay,Converter={StaticResource ReverseBooleanConverter}}"></CheckBox>
<Separator Opacity="0" Height="10"/>
<Button Content="{Binding Resources.SetupCertificate,Source={x:Static services:ResourceService.Current}, Mode=OneWay}" FontSize="14" Height="30">
<i:Interaction.Triggers>
@@ -88,6 +88,7 @@
<Run Text="{Binding Resources.Type,Source={x:Static services:ResourceService.Current},Mode=OneWay}" />
<Run Text=":" />
</TextBlock>
<WrapPanel Grid.Column="2">
<CheckBox Content="{Binding Resources.Game,Source={x:Static services:ResourceService.Current},Mode=OneWay}"
IsChecked="{Binding Game, Mode=TwoWay}" />
@@ -0,0 +1,227 @@
<UserControl x:Class="SteamTools.Views.Pages.SteamShutdown"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:metro="http://schemes.grabacr.net/winfx/2014/controls"
xmlns:metro2="clr-namespace:MetroTrilithon.UI.Controls;assembly=MetroTrilithon.Desktop"
xmlns:viewModel="clr-namespace:SteamTools.ViewModels"
xmlns:services="clr-namespace:SteamTools.Services"
xmlns:model="clr-namespace:SteamTool.Model;assembly=SteamTool.Model"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:livet="http://schemas.livet-mvvm.net/2011/wpf"
mc:Ignorable="d"
x:Name="u"
d:DesignWidth="800"
d:DesignHeight="400"
Background="{DynamicResource ThemeBrushKey}"
d:DataContext="{d:DesignInstance viewModel:SteamAppPageViewModel}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Content-->
<Border Grid.Row="1" Margin="8"
BorderBrush="{DynamicResource BorderBrushKey}"
BorderThickness=".99">
<ListView ItemsSource="{Binding Games,Mode=OneWay}"
ItemContainerStyle="{DynamicResource GridViewItemContainerStyleKey}"
ScrollViewer.PanningMode="Both">
<ListView.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Margin"
Value="5,4" />
</Style>
<Style TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource ActiveForegroundBrushKey}" />
</Style>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Setter Property="BorderThickness"
Value="0,0,0,.99" />
<Setter Property="BorderBrush"
Value="{DynamicResource BorderBrushKey}" />
<Setter Property="Background"
Value="{DynamicResource BackgroundBrushKey}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
<Grid>
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{TemplateBinding Background}">
<ContentPresenter Margin="{TemplateBinding Padding}" />
</Border>
<Thumb x:Name="PART_HeaderGripper"
HorizontalAlignment="Right"
BorderBrush="{TemplateBinding BorderBrush}"
Margin="0,0,-6,0">
<Thumb.Template>
<ControlTemplate TargetType="{x:Type Thumb}">
<Border Background="Transparent"
Width="13">
<Rectangle Width=".99"
Stroke="{TemplateBinding BorderBrush}" />
</Border>
</ControlTemplate>
</Thumb.Template>
</Thumb>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<!--Index-->
<GridViewColumn Width="40">
<GridViewColumn.Header>
<TextBlock Text="" />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Index}"
Margin="0,3"
Opacity="0.5"
TextTrimming="None"
TextWrapping="NoWrap" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--logo-->
<GridViewColumn Width="184">
<GridViewColumn.Header>
<TextBlock Text="{Binding Resources.Logo,Source={x:Static services:ResourceService.Current},Mode=OneWay}" />
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Source="{Binding HeaderLogoUrl, Mode=OneWay}" Cursor="Hand" Height="69"
ToolTip="{Binding Resources.AppLogo_ImageTootlip,Source={x:Static services:ResourceService.Current},Mode=OneWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<livet:LivetCallMethodAction
MethodName="LogoImage_Click"
MethodParameter="{Binding AppId}"
MethodTarget="{Binding DataContext,ElementName=u}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--APPID-->
<GridViewColumn Width="70">
<GridViewColumn.Header>
<metro2:SortButton MethodName="Sort"
MethodParameter="{x:Static viewModel:SteamAppSortWorker.AppIdColumn}">
<TextBlock Text="AppId" />
</metro2:SortButton>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox BorderThickness="0" IsReadOnly="True" Text="{Binding AppId, Mode=OneWay}"
Margin="0,3" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--Type-->
<GridViewColumn Width="60">
<GridViewColumn.Header>
<metro2:SortButton MethodName="Sort"
MethodParameter="{x:Static viewModel:SteamAppSortWorker.TypeColumn}">
<TextBlock Text="{Binding Resources.Type,Source={x:Static services:ResourceService.Current},Mode=OneWay}"/>
</metro2:SortButton>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type, Mode=OneWay}"
Margin="0,3" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--Name-->
<GridViewColumn Width="266">
<GridViewColumn.Header>
<metro2:SortButton MethodName="Sort"
MethodParameter="{x:Static viewModel:SteamAppSortWorker.NameColumn}">
<TextBlock Text="{Binding Resources.Name,Source={x:Static services:ResourceService.Current},Mode=OneWay}"/>
</metro2:SortButton>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding IconUrl,Mode=OneWay}" Width="20" Height="20"></Image>
<TextBox DockPanel.Dock="Left" Width="300" BorderThickness="0" IsReadOnly="True" Text="{Binding Name, Mode=OneWay}"
Margin="0,3" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<!--Operating-->
<GridViewColumn Width="80">
<GridViewColumn.Header>
<TextBlock Text="{Binding Resources.Operating,Source={x:Static services:ResourceService.Current},Mode=OneWay}"/>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/Resources/Asstes/unlock.png" Margin="6,0" Width="25" Cursor="Hand" ToolTip="{Binding Resources.Sam,Source={x:Static services:ResourceService.Current},Mode=OneWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction
MethodName="UnlockAchievement_Click"
MethodParameter="{Binding}"
MethodTarget="{Binding DataContext,ElementName=u}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
<Image Margin="6,0" Width="24" Cursor="Hand">
<Image.Style>
<Style TargetType="{x:Type Image}">
<Style.Triggers>
<DataTrigger Binding="{Binding Type,Mode=OneWay}" Value="Media">
<Setter Property="Source" Value="/Resources/Asstes/play.png" />
<Setter Property="ToolTip" Value="{Binding Resources.Play,Source={x:Static services:ResourceService.Current},Mode=OneWay}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsInstalled,Mode=OneWay}" Value="True">
<Setter Property="Source" Value="/Resources/Asstes/play.png" />
<Setter Property="ToolTip" Value="{Binding Resources.RunGame,Source={x:Static services:ResourceService.Current},Mode=OneWay}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsInstalled,Mode=OneWay}" Value="False">
<Setter Property="Source" Value="/Resources/Asstes/install-line.png" />
<Setter Property="ToolTip" Value="{Binding Resources.Install,Source={x:Static services:ResourceService.Current},Mode=OneWay}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<livet:LivetCallMethodAction
MethodName="InstallSteamApp_Click"
MethodParameter="{Binding}"
MethodTarget="{Binding DataContext,ElementName=u}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Border>
</Grid>
</UserControl>
@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace SteamTools.Views.Pages
{
/// <summary>
/// SteamAppPage.xaml 的交互逻辑
/// </summary>
public partial class SteamShutdown : UserControl
{
public SteamShutdown()
{
InitializeComponent();
}
}
}
@@ -62,7 +62,7 @@
Style="{DynamicResource SeparatorRectangleStyleKey}" />
<TextBlock Foreground="{DynamicResource ActiveForegroundBrushKey}">
<Run Text="作者:" />
<metro2:HyperlinkEx Uri="https://blog.rmbgame.net">
<metro2:HyperlinkEx Uri="https://github.com/SteamTools-Team">
<Run Text="@软妹币玩家" />
</metro2:HyperlinkEx>
<LineBreak />
File diff suppressed because it is too large Load Diff