├── logo.png
├── .gitattributes
├── WSATools
├── WSATools
│ ├── favicon.ico
│ ├── FodyWeavers.xml
│ ├── Properties
│ │ ├── launchSettings.json
│ │ ├── Settings.settings
│ │ └── Settings.Designer.cs
│ ├── Helpers
│ │ ├── Converter
│ │ │ ├── IsEqualToVisibilityConverter.cs
│ │ │ ├── BoolToVisibilityConverter.cs
│ │ │ ├── ConverterTools.cs
│ │ │ ├── IsEqualToObjectConverter.cs
│ │ │ └── BoolToObjectConverter.cs
│ │ ├── UpdateHelper.cs
│ │ └── UIHelper.cs
│ ├── Themes
│ │ ├── Generic.xaml
│ │ ├── SettingsUI.xaml
│ │ ├── Dark
│ │ │ └── Color.xaml
│ │ ├── Light
│ │ │ └── Color.xaml
│ │ └── HighContrast
│ │ │ └── Color.xaml
│ ├── Pages
│ │ ├── SettingsPages
│ │ │ ├── TestPage.xaml.cs
│ │ │ ├── TestPage.xaml
│ │ │ ├── SettingsPage.xaml.cs
│ │ │ └── SettingsPage.xaml
│ │ ├── AppsPage.xaml.cs
│ │ ├── AppsPage.xaml
│ │ ├── HomePage.xaml.cs
│ │ ├── MainPage.xaml
│ │ ├── HomePage.xaml
│ │ └── MainPage.xaml.cs
│ ├── MainWindow.xaml.cs
│ ├── MainWindow.xaml
│ ├── AssemblyInfo.cs
│ ├── Styles
│ │ ├── TextBlock.xaml
│ │ ├── SettingButton.xaml
│ │ ├── SettingsGroup.xaml
│ │ ├── Button.xaml
│ │ ├── Setting.xaml
│ │ └── SettingExpander.xaml
│ ├── ViewModels
│ │ ├── AppsViewModel.cs
│ │ ├── HomeViewModel.cs
│ │ └── SettingsViewModel.cs
│ ├── Models
│ │ ├── UpdateInfo.cs
│ │ └── SystemVersionInfo.cs
│ ├── App.xaml.cs
│ ├── App.xaml
│ ├── Controls
│ │ ├── SettingsGroup.cs
│ │ ├── PageHeader.xaml
│ │ ├── PageHeader.xaml.cs
│ │ └── Setting.cs
│ ├── WSATools.csproj
│ └── FodyWeavers.xsd
├── WSATools.Package
│ ├── Images
│ │ ├── StoreLogo.backup.png
│ │ ├── LargeTile.scale-100.png
│ │ ├── LargeTile.scale-125.png
│ │ ├── LargeTile.scale-150.png
│ │ ├── LargeTile.scale-200.png
│ │ ├── LargeTile.scale-400.png
│ │ ├── SmallTile.scale-100.png
│ │ ├── SmallTile.scale-125.png
│ │ ├── SmallTile.scale-150.png
│ │ ├── SmallTile.scale-200.png
│ │ ├── SmallTile.scale-400.png
│ │ ├── StoreLogo.scale-100.png
│ │ ├── StoreLogo.scale-125.png
│ │ ├── StoreLogo.scale-150.png
│ │ ├── StoreLogo.scale-200.png
│ │ ├── StoreLogo.scale-400.png
│ │ ├── SplashScreen.scale-100.png
│ │ ├── SplashScreen.scale-125.png
│ │ ├── SplashScreen.scale-150.png
│ │ ├── SplashScreen.scale-200.png
│ │ ├── SplashScreen.scale-400.png
│ │ ├── LockScreenLogo.scale-200.png
│ │ ├── Square44x44Logo.scale-100.png
│ │ ├── Square44x44Logo.scale-125.png
│ │ ├── Square44x44Logo.scale-150.png
│ │ ├── Square44x44Logo.scale-200.png
│ │ ├── Square44x44Logo.scale-400.png
│ │ ├── Wide310x150Logo.scale-100.png
│ │ ├── Wide310x150Logo.scale-125.png
│ │ ├── Wide310x150Logo.scale-150.png
│ │ ├── Wide310x150Logo.scale-200.png
│ │ ├── Wide310x150Logo.scale-400.png
│ │ ├── Square150x150Logo.scale-100.png
│ │ ├── Square150x150Logo.scale-125.png
│ │ ├── Square150x150Logo.scale-150.png
│ │ ├── Square150x150Logo.scale-200.png
│ │ ├── Square150x150Logo.scale-400.png
│ │ ├── Square44x44Logo.targetsize-16.png
│ │ ├── Square44x44Logo.targetsize-24.png
│ │ ├── Square44x44Logo.targetsize-256.png
│ │ ├── Square44x44Logo.targetsize-32.png
│ │ ├── Square44x44Logo.targetsize-48.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-16.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-32.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-48.png
│ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png
│ │ ├── Square44x44Logo.altform-unplated_targetsize-256.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png
│ │ ├── Square44x44Logo.altform-lightunplated_targetsize-48.png
│ │ └── Square44x44Logo.altform-lightunplated_targetsize-256.png
│ ├── Package.appxmanifest
│ └── WSATools.Package.wapproj
└── WSATools.Core
│ ├── Models
│ ├── StorageInfo.cs
│ └── APKInfo.cs
│ ├── WSATools.Core.csproj
│ ├── Helpers
│ ├── WSAHelper.cs
│ └── ADBHelper.cs
│ └── Receivers
│ └── StorageReceiver.cs
├── .gitmodules
├── .github
├── FUNDING.yml
└── workflows
│ └── build-and-publish.yml
├── README.md
├── .gitignore
└── WSATools.sln
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/logo.png
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/WSATools/WSATools/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools/favicon.ico
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "WSATools/APPXManager"]
2 | path = WSATools/APPXManager
3 | url = https://github.com/wherewhere/APPX-Manager.git
4 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/StoreLogo.backup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/StoreLogo.backup.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/LargeTile.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/LargeTile.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/LargeTile.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/LargeTile.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/LargeTile.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/LargeTile.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/LargeTile.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/LargeTile.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/LargeTile.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/LargeTile.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SmallTile.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SmallTile.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SmallTile.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SmallTile.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SmallTile.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SmallTile.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SmallTile.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SmallTile.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SmallTile.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SmallTile.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/StoreLogo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/StoreLogo.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/StoreLogo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/StoreLogo.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/StoreLogo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/StoreLogo.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/StoreLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/StoreLogo.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/StoreLogo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/StoreLogo.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SplashScreen.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SplashScreen.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SplashScreen.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SplashScreen.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SplashScreen.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SplashScreen.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/SplashScreen.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/SplashScreen.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/LockScreenLogo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/LockScreenLogo.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Wide310x150Logo.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square150x150Logo.scale-100.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square150x150Logo.scale-100.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square150x150Logo.scale-125.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square150x150Logo.scale-125.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square150x150Logo.scale-150.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square150x150Logo.scale-150.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square150x150Logo.scale-400.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square150x150Logo.scale-400.png
--------------------------------------------------------------------------------
/WSATools/WSATools/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "WSATools": {
4 | "commandName": "Project",
5 | "nativeDebugging": true
6 | }
7 | }
8 | }
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-16.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-24.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-256.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-32.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-48.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-16.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-32.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-48.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-unplated_targetsize-256.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-16.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-24.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-32.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-48.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Paving-Base/WSA-Tools/HEAD/WSATools/WSATools.Package/Images/Square44x44Logo.altform-lightunplated_targetsize-256.png
--------------------------------------------------------------------------------
/WSATools/WSATools.Core/Models/StorageInfo.cs:
--------------------------------------------------------------------------------
1 | namespace WSATools.Core.Models
2 | {
3 | public class StorageInfo
4 | {
5 | public int Use { get; set; }
6 | public int Size { get; set; }
7 | public int Used { get; set; }
8 | public int Available { get; set; }
9 | public string Mountedon { get; set; }
10 | public string Filesystem { get; set; }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/Converter/IsEqualToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace WSATools.Helpers.Converter
4 | {
5 | public partial class IsEqualToVisibilityConverter : IsEqualToObjectConverter
6 | {
7 | public IsEqualToVisibilityConverter()
8 | {
9 | TrueValue = Visibility.Visible;
10 | FalseValue = Visibility.Collapsed;
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Core/Models/APKInfo.cs:
--------------------------------------------------------------------------------
1 | using AdvancedSharpAdbClient.DeviceCommands;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace WSATools.Core.Models
9 | {
10 | public class APKInfo
11 | {
12 | public string Name { get; set; }
13 | public bool IsActive { get; set; }
14 | public VersionInfo VersionInfo { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/SettingsPages/TestPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Controls;
3 | using Windows.Foundation.Collections;
4 | using Windows.System;
5 |
6 | namespace WSATools.Pages.SettingsPages
7 | {
8 | ///
9 | /// TestPage.xaml 的交互逻辑
10 | ///
11 | public partial class TestPage : Page
12 | {
13 | public TestPage()
14 | {
15 | InitializeComponent();
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 2021-11-12
7 |
8 |
9 |
--------------------------------------------------------------------------------
/WSATools/WSATools/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using WSATools.Helpers;
3 | using WSATools.Pages;
4 |
5 | namespace WSATools
6 | {
7 | ///
8 | /// Interaction logic for MainWindow.xaml
9 | ///
10 | public partial class MainWindow : Window
11 | {
12 | public MainWindow()
13 | {
14 | InitializeComponent();
15 | UIHelper.MainWindow = this;
16 | MainPage MainPage = new();
17 | Content = MainPage;
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/SettingsPages/TestPage.xaml:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/WSATools/WSATools/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/WSATools/WSATools/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | [assembly: ThemeInfo(
4 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5 | //(used if a resource is not found in the page,
6 | // or application resource dictionaries)
7 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8 | //(used if a resource is not found in the page,
9 | // app, or any theme specific resource dictionaries)
10 | )]
11 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Core/WSATools.Core.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | preview
5 | net4.8
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/Converter/BoolToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace WSATools.Helpers.Converter
4 | {
5 | ///
6 | /// This class converts a boolean value into a Visibility enumeration.
7 | ///
8 | public class BoolToVisibilityConverter : BoolToObjectConverter
9 | {
10 | ///
11 | /// Initializes a new instance of the class.
12 | ///
13 | public BoolToVisibilityConverter()
14 | {
15 | TrueValue = Visibility.Visible;
16 | FalseValue = Visibility.Collapsed;
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/AppsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace WSATools.Pages
17 | {
18 | ///
19 | /// AppsPage.xaml 的交互逻辑
20 | ///
21 | public partial class AppsPage : ModernWpf.Controls.Page
22 | {
23 | public AppsPage() => InitializeComponent();
24 |
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: wherewhere
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
13 | custom: ['afdian.net/@wherewhere']
14 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/SettingsPages/SettingsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using ModernWpf.Controls;
2 | using System.Windows.Navigation;
3 | using WSATools.ViewModels;
4 |
5 | namespace WSATools.Pages.SettingsPages
6 | {
7 | ///
8 | /// SettingsPage.xaml 的交互逻辑
9 | ///
10 | public partial class SettingsPage : Page
11 | {
12 | private SettingsViewModel ViewModel;
13 |
14 | public SettingsPage()
15 | {
16 | InitializeComponent();
17 | }
18 |
19 | protected override void OnNavigatedTo(NavigationEventArgs e)
20 | {
21 | base.OnNavigatedTo(e);
22 | if (DataContext is SettingsViewModel viewModel)
23 | {
24 | ViewModel = viewModel;
25 | }
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/AppsPage.xaml:
--------------------------------------------------------------------------------
1 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Themes/SettingsUI.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | 240
12 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Core/Helpers/WSAHelper.cs:
--------------------------------------------------------------------------------
1 | using APPXManager.DeviceCommands;
2 | using APPXManager.Models;
3 | using System.Diagnostics;
4 |
5 | namespace WSATools.Core.Helpers
6 | {
7 | public static class WSAHelper
8 | {
9 | public static bool IsWSARunning
10 | {
11 | get
12 | {
13 | Process[] ps = Process.GetProcessesByName("vmmemWSA");
14 | return ps != null && ps.Length > 0;
15 | }
16 | }
17 |
18 | public static (bool, PackageInfo) GetWSAInfo() => PackageManager.FindPackageByName("MicrosoftCorporationII.WindowsSubsystemForAndroid");
19 |
20 | public static void StartWSA()
21 | {
22 | PackageManager.LaunchPackage("MicrosoftCorporationII.WindowsSubsystemForAndroid_8wekyb3d8bbwe");
23 | while (IsWSARunning)
24 | {
25 | ;
26 | }
27 | }
28 |
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Themes/Dark/Color.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | 1
9 | #FF5fb2f2
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Themes/Light/Color.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | 1
9 | #FF0063b1
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Themes/HighContrast/Color.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | 2
9 | #FF5fb2f2
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/HomePage.xaml.cs:
--------------------------------------------------------------------------------
1 | using ModernWpf.Controls;
2 | using System.Security.Principal;
3 | using System.Windows;
4 | using System.Windows.Navigation;
5 | using WSATools.ViewModels;
6 |
7 | namespace WSATools.Pages
8 | {
9 | ///
10 | /// HomePage.xaml 的交互逻辑
11 | ///
12 | public partial class HomePage : Page
13 | {
14 | private HomeViewModel Provider;
15 |
16 | public HomePage()
17 | {
18 | InitializeComponent();
19 | }
20 |
21 | protected override void OnNavigatedTo(NavigationEventArgs e)
22 | {
23 | base.OnNavigatedTo(e);
24 | if (DataContext is HomeViewModel ViewModel)
25 | {
26 | Provider = ViewModel;
27 | }
28 | //获得当前登录的Windows用户标示
29 | WindowsIdentity identity = WindowsIdentity.GetCurrent();
30 | WindowsPrincipal principal = new WindowsPrincipal(identity);
31 | InfoBar.Visibility = principal.IsInRole(WindowsBuiltInRole.Administrator) ? Visibility.Collapsed : Visibility.Visible;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Styles/TextBlock.xaml:
--------------------------------------------------------------------------------
1 |
6 |
16 | 12
17 |
21 |
--------------------------------------------------------------------------------
/WSATools/WSATools/ViewModels/AppsViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.ComponentModel;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using WSATools.Core.Helpers;
9 | using WSATools.Core.Models;
10 |
11 | namespace WSATools.ViewModels
12 | {
13 | public sealed class AppsViewModel : INotifyPropertyChanged
14 | {
15 | ObservableCollection _appList;
16 | public ObservableCollection AppList
17 | {
18 | get => _appList;
19 | set
20 | {
21 | if (_appList != value)
22 | {
23 | _appList = value;
24 | RaisePropertyChangedEvent();
25 | }
26 | }
27 | }
28 |
29 | public event PropertyChangedEventHandler PropertyChanged;
30 |
31 | private void RaisePropertyChangedEvent([System.Runtime.CompilerServices.CallerMemberName] string name = null)
32 | {
33 | if (name != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }
34 | }
35 |
36 | public void Refresh()
37 | {
38 | AppList = ADBHelper.GetAppsList();
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/Converter/ConverterTools.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace WSATools.Helpers.Converter
4 | {
5 | ///
6 | /// Static class used to provide internal tools
7 | ///
8 | internal static class ConverterTools
9 | {
10 | ///
11 | /// Helper method to safely cast an object to a boolean
12 | ///
13 | /// Parameter to cast to a boolean
14 | /// Bool value or false if cast failed
15 | internal static bool TryParseBool(object parameter)
16 | {
17 | bool parsed = false;
18 | if (parameter != null)
19 | {
20 | bool.TryParse(parameter.ToString(), out parsed);
21 | }
22 |
23 | return parsed;
24 | }
25 |
26 | ///
27 | /// Helper method to convert a value from a source type to a target type.
28 | ///
29 | /// The value to convert
30 | /// The target type
31 | /// The converted value
32 | internal static object Convert(object value, Type targetType)
33 | {
34 | return value;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Models/UpdateInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text.Json.Serialization;
4 |
5 | namespace WSATools.Models
6 | {
7 | public class UpdateInfo
8 | {
9 | [JsonPropertyName("url")]
10 | public string ApiUrl { get; set; }
11 | [JsonPropertyName("html_url")]
12 | public string ReleaseUrl { get; set; }
13 | [JsonPropertyName("tag_name")]
14 | public string TagName { get; set; }
15 | [JsonPropertyName("prerelease")]
16 | public bool IsPreRelease { get; set; }
17 | [JsonPropertyName("created_at")]
18 | public DateTime CreatedAt { get; set; }
19 | [JsonPropertyName("published_at")]
20 | public DateTime PublishedAt { get; set; }
21 | [JsonPropertyName("assets")]
22 | public List Assets { get; set; }
23 | [JsonPropertyName("body")]
24 | public string Changelog { get; set; }
25 | public bool IsExistNewVersion { get; set; }
26 | public UpdateState UpdateState { get; set; }
27 | }
28 |
29 | public class Asset
30 | {
31 | [JsonPropertyName("size")]
32 | public int Size { get; set; }
33 | [JsonPropertyName("browser_download_url")]
34 | public string Url { get; set; }
35 | }
36 |
37 | public enum UpdateState
38 | {
39 | CheckingUpdate,
40 | CheckFailed,
41 | UpToDate,
42 | ReadyToDownload,
43 | ErrorDownloading,
44 | ReadyToInstall
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/WSATools/WSATools/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Security.Principal;
2 | using System.Windows;
3 |
4 | namespace WSATools
5 | {
6 | ///
7 | /// Interaction logic for App.xaml
8 | ///
9 | public partial class App : Application
10 | {
11 | public App()
12 | {
13 | /**
14 | * 当前用户是管理员的时候,直接启动应用程序
15 | * 如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行
16 | */
17 | //获得当前登录的Windows用户标示
18 | WindowsIdentity identity = WindowsIdentity.GetCurrent();
19 | WindowsPrincipal principal = new WindowsPrincipal(identity);
20 | //判断当前登录用户是否为管理员
21 | //if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
22 | //{
23 | // //创建启动对象
24 | // System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
25 | // startInfo.UseShellExecute = true;
26 | // startInfo.WorkingDirectory = Environment.CurrentDirectory;
27 | // startInfo.FileName = Assembly.GetExecutingAssembly().Location;
28 | // //设置启动动作,确保以管理员身份运行
29 | // startInfo.Verb = "runas";
30 | // try
31 | // {
32 | // System.Diagnostics.Process.Start(startInfo);
33 | // }
34 | // catch
35 | // {
36 | // return;
37 | // }
38 | // //退出
39 | // Application.Current.Shutdown();
40 | //}
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // 此代码由工具生成。
4 | // 运行时版本:4.0.30319.42000
5 | //
6 | // 对此文件的更改可能会导致不正确的行为,并且如果
7 | // 重新生成代码,这些更改将会丢失。
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace WSATools.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.1.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 |
26 | [global::System.Configuration.UserScopedSettingAttribute()]
27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
28 | [global::System.Configuration.DefaultSettingValueAttribute("2021-11-12")]
29 | public global::System.DateTime UpdateDate {
30 | get {
31 | return ((global::System.DateTime)(this["UpdateDate"]));
32 | }
33 | set {
34 | this["UpdateDate"] = value;
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Styles/SettingButton.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
21 |
22 |
23 |
33 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Styles/SettingsGroup.xaml:
--------------------------------------------------------------------------------
1 |
6 |
37 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Core/Receivers/StorageReceiver.cs:
--------------------------------------------------------------------------------
1 | using AdvancedSharpAdbClient;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Threading.Tasks;
9 | using WSATools.Core.Models;
10 |
11 | namespace WSATools.Core.Receivers
12 | {
13 | public class StorageReceiver : MultiLineReceiver
14 | {
15 | public StorageReceiver()
16 | {
17 | Storages = new ObservableCollection();
18 | }
19 |
20 | public ObservableCollection Storages { get; private set; }
21 |
22 | ///
23 | /// Processes the new lines.
24 | ///
25 | /// The lines.
26 | protected override void ProcessNewLines(IEnumerable lines)
27 | {
28 | Storages.Clear();
29 |
30 | foreach (string line in lines)
31 | {
32 | if (!string.IsNullOrEmpty(line) && !line.StartsWith("Filesystem"))
33 | {
34 | string[] parts = Regex.Split(line, "\\s+", RegexOptions.IgnoreCase);
35 | StorageInfo Info = new StorageInfo()
36 | {
37 | Mountedon = parts[5].Trim(),
38 | Filesystem = parts[0].Trim(),
39 | Size = Convert.ToInt32(parts[1].Trim()),
40 | Used = Convert.ToInt32(parts[2].Trim()),
41 | Available = Convert.ToInt32(parts[3].Trim()),
42 | Use = Convert.ToInt32(parts[4].Trim().Replace("%", string.Empty))
43 | };
44 | Storages.Add(Info);
45 | }
46 | }
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # WSA Tools
4 | 一个基于 Modern WPF 的 WSA 工具箱
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ## 目录
14 | - [WSA Tools](#wsa-tools)
15 | - [目录](#目录)
16 | - [如何安装应用](#如何安装应用)
17 | - [最低需求](#最低需求)
18 | - [使用到的模块](#使用到的模块)
19 | - [鸣谢](#鸣谢)
20 | - [Star 数量统计](#star-数量统计)
21 |
22 | ## 如何安装应用
23 | ### 最低需求
24 | - Windows 7 Build 7231 及以上
25 | - 设备需支持ARM/ARM64/x86/x64
26 | - 至少20MB的空余储存空间(用于储存安装包与安装应用)
27 |
28 | ## 使用到的模块
29 | - [FluentWPF](https://github.com/sourcechord/FluentWPF "FluentWPF")
30 | - [ModernWpf](https://github.com/Kinnara/ModernWpf "ModernWpf")
31 | - [Windows Community Toolkit](https://github.com/CommunityToolkit/WindowsCommunityToolkit "Windows Community Toolkit")
32 |
33 | ## 鸣谢
34 | - 所有为 WSA Tools 做出贡献的同志们
35 | - **铺路尚未成功,同志仍需努力!**
36 |
37 | ## Star 数量统计
38 | [](https://starchart.cc/Paving-Base/WSA-Tools "Star 数量统计")
--------------------------------------------------------------------------------
/.github/workflows/build-and-publish.yml:
--------------------------------------------------------------------------------
1 | name: build and publish
2 |
3 | on:
4 | push:
5 | pull_request:
6 | branches: [main]
7 | paths:
8 | - 'WSATools/**'
9 |
10 | jobs:
11 | build-and-test:
12 |
13 | name: build-and-publish
14 | runs-on: windows-latest
15 |
16 | env:
17 | Solution_Name: WSATools/WSATools/WSATools.csproj
18 | Project_Directory: WSATools/WSATools
19 |
20 | steps:
21 | - name: Checkout
22 | uses: actions/checkout@v3
23 | with:
24 | fetch-depth: 0
25 |
26 | - name: Clone ModernWpf
27 | run: |
28 | echo 'Cloning into sources folder at: ..\ModernWpf'
29 | git clone https://github.com/wherewhere/ModernWpf.git --progress --branch master --single-branch --depth=1 ..\ModernWpf
30 | exit
31 |
32 | - name: Clone APPXManager
33 | run: |
34 | echo 'Cloning into sources folder at: ..\APPX-Manager'
35 | git clone https://github.com/wherewhere/APPX-Manager.git --progress --branch master --single-branch --depth=1 ..\APPX-Manager
36 | exit
37 |
38 | - name: Clone SharpAdbClient
39 | run: |
40 | echo 'Cloning into sources folder at: ..\AdvancedSharpAdbClient'
41 | git clone https://github.com/yungd1plomat/AdvancedSharpAdbClient.git --progress --branch main --single-branch --depth=1 ..\AdvancedSharpAdbClient
42 | exit
43 |
44 | # Add MSBuild to the PATH: https://github.com/microsoft/setup-msbuild
45 | - name: Setup MSBuild.exe
46 | uses: microsoft/setup-msbuild@v1
47 | with:
48 | msbuild-architecture: x64
49 |
50 | # Restore the application to populate the obj folder with RuntimeIdentifiers
51 | - name: Restore the application
52 | run: msbuild $env:Solution_Name /t:Restore /p:Configuration=$env:Configuration
53 | env:
54 | Configuration: Release
55 |
56 | # Create the app package by building and packaging the Windows Application Packaging project
57 | - name: Publish the app package
58 | run: msbuild $env:Solution_Name /p:Configuration=$env:Configuration /p:Platform=$env:Platforms
59 | env:
60 | Platforms: "Any CPU"
61 | Configuration: Release
62 |
63 | # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact
64 | - name: Upload build artifacts
65 | uses: actions/upload-artifact@v3
66 | with:
67 | name: Publish Package
68 | path: WSATools/WSATools/bin/**
69 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
13 |
14 |
15 | WSA Tools
16 | wherewhere
17 | Images\StoreLogo.png
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Models/SystemVersionInfo.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace WSATools.Models
4 | {
5 | public readonly struct SystemVersionInfo
6 | {
7 | public SystemVersionInfo(int major, int minor, int build, int revision = 0)
8 | {
9 | Major = major;
10 | Minor = minor;
11 | Build = build;
12 | Revision = revision;
13 | }
14 |
15 | public int Major { get; }
16 |
17 | public int Minor { get; }
18 |
19 | public int Build { get; }
20 |
21 | public int Revision { get; }
22 |
23 | public bool Equals(SystemVersionInfo other) => Major == other.Major && Minor == other.Minor && Build == other.Build && Revision == other.Revision;
24 |
25 | public override bool Equals(object obj) => obj is SystemVersionInfo other && Equals(other);
26 |
27 | public override int GetHashCode() => Major.GetHashCode() ^ Minor.GetHashCode() ^ Build.GetHashCode() ^ Revision.GetHashCode();
28 |
29 | public static bool operator ==(SystemVersionInfo left, SystemVersionInfo right) => left.Equals(right);
30 |
31 | public static bool operator !=(SystemVersionInfo left, SystemVersionInfo right) => !(left == right);
32 |
33 | public int CompareTo(SystemVersionInfo other)
34 | {
35 | if (Major != other.Major)
36 | {
37 | return Major.CompareTo(other.Major);
38 | }
39 |
40 | if (Minor != other.Minor)
41 | {
42 | return Minor.CompareTo(other.Minor);
43 | }
44 |
45 | if (Build != other.Build)
46 | {
47 | return Build.CompareTo(other.Build);
48 | }
49 |
50 | if (Revision != other.Revision)
51 | {
52 | return Revision.CompareTo(other.Revision);
53 | }
54 |
55 | return 0;
56 | }
57 |
58 | public int CompareTo(object obj)
59 | {
60 | if (!(obj is SystemVersionInfo other))
61 | {
62 | throw new ArgumentException();
63 | }
64 |
65 | return CompareTo(other);
66 | }
67 |
68 | public static bool operator <(SystemVersionInfo left, SystemVersionInfo right) => left.CompareTo(right) < 0;
69 |
70 | public static bool operator <=(SystemVersionInfo left, SystemVersionInfo right) => left.CompareTo(right) <= 0;
71 |
72 | public static bool operator >(SystemVersionInfo left, SystemVersionInfo right) => left.CompareTo(right) > 0;
73 |
74 | public static bool operator >=(SystemVersionInfo left, SystemVersionInfo right) => left.CompareTo(right) >= 0;
75 |
76 | public override string ToString() => $"{Major}.{Minor}.{Build}.{Revision}";
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
19 |
20 |
21 |
22 |
23 |
29 |
35 |
36 |
46 |
47 |
51 |
55 |
56 |
57 |
58 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/WSATools/WSATools/App.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | 641
41 |
42 | 0
43 | -4,0,12,0
44 |
45 |
46 | 0,48,0,0
47 | 1,1,0,0
48 | 8,0,0,0
49 | 56,34,0,0
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Controls/SettingsGroup.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows;
3 | using System.Windows.Automation.Peers;
4 | using System.Windows.Controls;
5 |
6 | namespace WSATools.Controls
7 | {
8 | ///
9 | /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
10 | ///
11 | /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
12 | /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
13 | /// 元素中:
14 | ///
15 | /// xmlns:MyNamespace="clr-namespace:WSATools.Controls"
16 | ///
17 | ///
18 | /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
19 | /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
20 | /// 元素中:
21 | ///
22 | /// xmlns:MyNamespace="clr-namespace:WSATools.Controls;assembly=WSATools.Controls"
23 | ///
24 | /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
25 | /// 并重新生成以避免编译错误:
26 | ///
27 | /// 在解决方案资源管理器中右击目标项目,然后依次单击
28 | /// “添加引用”->“项目”->[浏览查找并选择此项目]
29 | ///
30 | ///
31 | /// 步骤 2)
32 | /// 继续操作并在 XAML 文件中使用控件。
33 | ///
34 | ///
35 | ///
36 | ///
37 | ///
38 | /// Represents a control that can contain multiple settings (or other) controls
39 | ///
40 | [TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
41 | [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
42 | public partial class SettingsGroup : ItemsControl
43 | {
44 | public SettingsGroup()
45 | {
46 | DefaultStyleKey = typeof(SettingsGroup);
47 | }
48 |
49 | public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
50 | "Header",
51 | typeof(string),
52 | typeof(SettingsGroup),
53 | new PropertyMetadata(default(string)));
54 |
55 | [Localizable(true)]
56 | public string Header
57 | {
58 | get => (string)GetValue(HeaderProperty);
59 | set => SetValue(HeaderProperty, value);
60 | }
61 |
62 | public override void OnApplyTemplate()
63 | {
64 | IsEnabledChanged -= SettingsGroup_IsEnabledChanged;
65 | SetEnabledState();
66 | IsEnabledChanged += SettingsGroup_IsEnabledChanged;
67 | base.OnApplyTemplate();
68 | }
69 |
70 | private void SettingsGroup_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
71 | {
72 | SetEnabledState();
73 | }
74 |
75 | private void SetEnabledState()
76 | {
77 | VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
78 | }
79 |
80 | protected override AutomationPeer OnCreateAutomationPeer()
81 | {
82 | return new SettingsGroupAutomationPeer(this);
83 | }
84 | }
85 |
86 | public class SettingsGroupAutomationPeer : FrameworkElementAutomationPeer
87 | {
88 | public SettingsGroupAutomationPeer(SettingsGroup owner)
89 | : base(owner)
90 | {
91 | }
92 |
93 | protected override string GetNameCore()
94 | {
95 | SettingsGroup selectedSettingsGroup = (SettingsGroup)Owner;
96 | return selectedSettingsGroup.Header;
97 | }
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/WSATools/WSATools/WSATools.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | True
5 | favicon.ico
6 | wherewhere
7 | Copyright © 2017 - 2021 Paving Base. All Rights Reserved
8 | 一个基于 Modern WPF 的 WSA 管理工具
9 | preview
10 | WinExe
11 | https://github.com/Paving-Base/WSA-Tools
12 | https://github.com/Paving-Base/WSA-Tools
13 | net4.8
14 | true
15 | 0.0.1
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | True
25 | \
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | runtime; build; native; contentfiles; analyzers; buildtransitive
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | True
53 | True
54 | Settings.settings
55 |
56 |
57 |
58 |
59 |
60 | SettingsSingleFileGenerator
61 | Settings.Designer.cs
62 |
63 |
64 |
65 |
66 |
67 | $(DefaultXamlRuntime)
68 | Designer
69 |
70 |
71 | $(DefaultXamlRuntime)
72 | Designer
73 |
74 |
75 | $(DefaultXamlRuntime)
76 | Designer
77 |
78 |
79 | $(DefaultXamlRuntime)
80 | Designer
81 |
82 |
83 | $(DefaultXamlRuntime)
84 | Designer
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/Converter/IsEqualToObjectConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace WSATools.Helpers.Converter
7 | {
8 | public partial class IsEqualToObjectConverter : DependencyObject, IValueConverter
9 | {
10 | ///
11 | /// Identifies the property.
12 | ///
13 | public static readonly DependencyProperty TrueValueProperty =
14 | DependencyProperty.Register(nameof(TrueValue), typeof(object), typeof(IsEqualToObjectConverter), new PropertyMetadata(null));
15 |
16 | ///
17 | /// Identifies the property.
18 | ///
19 | public static readonly DependencyProperty FalseValueProperty =
20 | DependencyProperty.Register(nameof(FalseValue), typeof(object), typeof(IsEqualToObjectConverter), new PropertyMetadata(null));
21 |
22 | ///
23 | /// Gets or sets the value to be returned when the boolean is true
24 | ///
25 | public object TrueValue
26 | {
27 | get { return GetValue(TrueValueProperty); }
28 | set { SetValue(TrueValueProperty, value); }
29 | }
30 |
31 | ///
32 | /// Gets or sets the value to be returned when the boolean is false
33 | ///
34 | public object FalseValue
35 | {
36 | get { return GetValue(FalseValueProperty); }
37 | set { SetValue(FalseValueProperty, value); }
38 | }
39 |
40 | ///
41 | /// Convert a boolean value to an other object.
42 | ///
43 | /// The source data being passed to the target.
44 | /// The type of the target property, as a type reference.
45 | /// An optional parameter to be used to invert the converter logic.
46 | /// The language of the conversion.
47 | /// The value to be passed to the target dependency property.
48 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
49 | {
50 | bool boolValue = value.ToString() == (string)parameter;
51 |
52 | return ConverterTools.Convert(boolValue ? TrueValue : FalseValue, targetType);
53 | }
54 |
55 | ///
56 | /// Convert back the value to a boolean
57 | ///
58 | /// If the parameter is a reference type, must match its reference to return true.
59 | /// The target data being passed to the source.
60 | /// The type of the target property, as a type reference (System.Type for Microsoft .NET, a TypeName helper struct for Visual C++ component extensions (C++/CX)).
61 | /// An optional parameter to be used to invert the converter logic.
62 | /// The language of the conversion.
63 | /// The value to be passed to the source object.
64 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
65 | {
66 | return value;
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/WSATools/WSATools/ViewModels/HomeViewModel.cs:
--------------------------------------------------------------------------------
1 | using APPXManager.Models;
2 | using System.Collections.ObjectModel;
3 | using System.ComponentModel;
4 | using System.Threading.Tasks;
5 | using WSATools.Core.Helpers;
6 | using WSATools.Core.Models;
7 | using WSATools.Helpers;
8 |
9 | namespace WSATools.ViewModels
10 | {
11 | public sealed class HomeViewModel : INotifyPropertyChanged
12 | {
13 | private PackageInfo _WSAInfo = new PackageInfo();
14 | public PackageInfo WSAInfo
15 | {
16 | get => _WSAInfo;
17 | set
18 | {
19 | if (_WSAInfo != value)
20 | {
21 | _WSAInfo = value;
22 | RaisePropertyChangedEvent();
23 | }
24 | }
25 | }
26 |
27 | private bool _isWSAStart = WSAHelper.IsWSARunning;
28 | public bool IsWSAStart
29 | {
30 | get => _isWSAStart;
31 | set
32 | {
33 | if (_isWSAStart != value)
34 | {
35 | _isWSAStart = value;
36 | RaisePropertyChangedEvent();
37 | }
38 | }
39 | }
40 |
41 | private bool _isWSAInstalled = false;
42 | public bool IsWSAInstalled
43 | {
44 | get => _isWSAInstalled;
45 | set
46 | {
47 | if (_isWSAInstalled != value)
48 | {
49 | _isWSAInstalled = value;
50 | RaisePropertyChangedEvent();
51 | }
52 | }
53 | }
54 |
55 | private double _storageUsage;
56 | public double StorageUsage
57 | {
58 | get => _storageUsage;
59 | set
60 | {
61 | if (_storageUsage != value)
62 | {
63 | _storageUsage = value;
64 | RaisePropertyChangedEvent();
65 | }
66 | }
67 | }
68 |
69 | private string _storageUsageText;
70 | public string StorageUsageText
71 | {
72 | get => _storageUsageText;
73 | set
74 | {
75 | if (_storageUsageText != value)
76 | {
77 | _storageUsageText = value;
78 | RaisePropertyChangedEvent();
79 | }
80 | }
81 | }
82 |
83 | public event PropertyChangedEventHandler PropertyChanged;
84 |
85 | private void RaisePropertyChangedEvent([System.Runtime.CompilerServices.CallerMemberName] string name = null)
86 | {
87 | if (name != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }
88 | }
89 |
90 | public HomeViewModel()
91 | {
92 | //(IsWSAInstalled, WSAInfo) = WSAHelper.GetWSAInfo();
93 | //ADBHelper.InitilizeADB();
94 | //ADBHelper.ConnectWSA();
95 | }
96 |
97 | public void Refresh()
98 | {
99 | ObservableCollection storages = ADBHelper.GetStorageInfo();
100 | int Size = 0, Used = 0, Available = 0;
101 | foreach (StorageInfo storage in storages)
102 | {
103 | Size += storage.Size;
104 | Used += storage.Used;
105 | Available += storage.Available;
106 | }
107 | StorageUsage = (double)Used / Size;
108 | StorageUsageText = $"一共 {((double)Size * 1024).GetSizeString()} 空余 {((double)Available * 1024).GetSizeString()}";
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Controls/PageHeader.xaml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
36 |
40 |
49 |
50 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
69 |
75 |
76 |
83 |
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/Converter/BoolToObjectConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace WSATools.Helpers.Converter
7 | {
8 | ///
9 | /// This class converts a boolean value into an other object.
10 | /// Can be used to convert true/false to visibility, a couple of colors, couple of images, etc.
11 | ///
12 | public partial class BoolToObjectConverter : DependencyObject, IValueConverter
13 | {
14 | ///
15 | /// Identifies the property.
16 | ///
17 | public static readonly DependencyProperty TrueValueProperty =
18 | DependencyProperty.Register(nameof(TrueValue), typeof(object), typeof(BoolToObjectConverter), new PropertyMetadata(null));
19 |
20 | ///
21 | /// Identifies the property.
22 | ///
23 | public static readonly DependencyProperty FalseValueProperty =
24 | DependencyProperty.Register(nameof(FalseValue), typeof(object), typeof(BoolToObjectConverter), new PropertyMetadata(null));
25 |
26 | ///
27 | /// Gets or sets the value to be returned when the boolean is true
28 | ///
29 | public object TrueValue
30 | {
31 | get { return GetValue(TrueValueProperty); }
32 | set { SetValue(TrueValueProperty, value); }
33 | }
34 |
35 | ///
36 | /// Gets or sets the value to be returned when the boolean is false
37 | ///
38 | public object FalseValue
39 | {
40 | get { return GetValue(FalseValueProperty); }
41 | set { SetValue(FalseValueProperty, value); }
42 | }
43 |
44 | ///
45 | /// Convert a boolean value to an other object.
46 | ///
47 | /// The source data being passed to the target.
48 | /// The type of the target property, as a type reference.
49 | /// An optional parameter to be used to invert the converter logic.
50 | /// The language of the conversion.
51 | /// The value to be passed to the target dependency property.
52 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
53 | {
54 | bool boolValue = value is bool && (bool)value;
55 |
56 | // Negate if needed
57 | if (ConverterTools.TryParseBool(parameter))
58 | {
59 | boolValue = !boolValue;
60 | }
61 |
62 | return ConverterTools.Convert(boolValue ? TrueValue : FalseValue, targetType);
63 | }
64 |
65 | ///
66 | /// Convert back the value to a boolean
67 | ///
68 | /// If the parameter is a reference type, must match its reference to return true.
69 | /// The target data being passed to the source.
70 | /// The type of the target property, as a type reference (System.Type for Microsoft .NET, a TypeName helper struct for Visual C++ component extensions (C++/CX)).
71 | /// An optional parameter to be used to invert the converter logic.
72 | /// The language of the conversion.
73 | /// The value to be passed to the source object.
74 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
75 | {
76 | bool result = Equals(value, ConverterTools.Convert(TrueValue, value.GetType()));
77 |
78 | if (ConverterTools.TryParseBool(parameter))
79 | {
80 | result = !result;
81 | }
82 |
83 | return result;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Controls/PageHeader.xaml.cs:
--------------------------------------------------------------------------------
1 | using ModernWpf.Media.Animation;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using System.Windows.Media.Animation;
5 |
6 | namespace WSATools.Controls
7 | {
8 | ///
9 | /// PageHeader.xaml 的交互逻辑
10 | ///
11 | public partial class PageHeader : UserControl
12 | {
13 | public object Title
14 | {
15 | get { return GetValue(TitleProperty); }
16 | set { SetValue(TitleProperty, value); }
17 | }
18 |
19 | public static readonly DependencyProperty TitleProperty =
20 | DependencyProperty.Register("Title", typeof(object), typeof(PageHeader), new PropertyMetadata(null));
21 |
22 |
23 | public Thickness HeaderPadding
24 | {
25 | get { return (Thickness)GetValue(HeaderPaddingProperty); }
26 | set { SetValue(HeaderPaddingProperty, value); }
27 | }
28 |
29 | // Using a DependencyProperty as the backing store for BackgroundColorOpacity. This enables animation, styling, binding, etc...
30 | public static readonly DependencyProperty HeaderPaddingProperty =
31 | DependencyProperty.Register("HeaderPadding", typeof(Thickness), typeof(PageHeader), new PropertyMetadata((Thickness)App.Current.Resources["PageHeaderDefaultPadding"]));
32 |
33 |
34 | public double BackgroundColorOpacity
35 | {
36 | get { return (double)GetValue(BackgroundColorOpacityProperty); }
37 | set { SetValue(BackgroundColorOpacityProperty, value); }
38 | }
39 |
40 | // Using a DependencyProperty as the backing store for BackgroundColorOpacity. This enables animation, styling, binding, etc...
41 | public static readonly DependencyProperty BackgroundColorOpacityProperty =
42 | DependencyProperty.Register("BackgroundColorOpacity", typeof(double), typeof(PageHeader), new PropertyMetadata(0.0));
43 |
44 |
45 | public double AcrylicOpacity
46 | {
47 | get { return (double)GetValue(AcrylicOpacityProperty); }
48 | set { SetValue(AcrylicOpacityProperty, value); }
49 | }
50 |
51 | // Using a DependencyProperty as the backing store for BackgroundColorOpacity. This enables animation, styling, binding, etc...
52 | public static readonly DependencyProperty AcrylicOpacityProperty =
53 | DependencyProperty.Register("AcrylicOpacity", typeof(double), typeof(PageHeader), new PropertyMetadata(0.3));
54 |
55 | public double ShadowOpacity
56 | {
57 | get { return (double)GetValue(ShadowOpacityProperty); }
58 | set { SetValue(ShadowOpacityProperty, value); }
59 | }
60 |
61 | // Using a DependencyProperty as the backing store for BackgroundColorOpacity. This enables animation, styling, binding, etc...
62 | public static readonly DependencyProperty ShadowOpacityProperty =
63 | DependencyProperty.Register("ShadowOpacity", typeof(double), typeof(PageHeader), new PropertyMetadata(0.0));
64 |
65 | public UIElement TitlePanel
66 | {
67 | get { return PageTitle; }
68 | }
69 |
70 | public PageHeader()
71 | {
72 | this.InitializeComponent();
73 | }
74 |
75 | ///
76 | /// This method will be called when a gets unloaded.
77 | /// Put any code in here that should be done when a gets unloaded.
78 | ///
79 | /// The sender (the ItemPage)
80 | /// The of the ItemPage that was unloaded.
81 | public void Event_ItemPage_Unloaded(object sender, RoutedEventArgs e)
82 | {
83 |
84 | }
85 |
86 | public void RectanglePointerEntered()
87 | {
88 | var storyboard = new Storyboard();
89 | var animation = new FadeInThemeAnimation { TargetName = nameof(MessageBar) };
90 | storyboard.Children.Add(animation);
91 | storyboard.Begin();
92 | }
93 |
94 | public void RectanglePointerExited()
95 | {
96 | var storyboard = new Storyboard();
97 | var animation = new FadeOutThemeAnimation { TargetName = nameof(MessageBar) };
98 | storyboard.Children.Add(animation);
99 | storyboard.Begin();
100 | }
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/WSATools/WSATools/ViewModels/SettingsViewModel.cs:
--------------------------------------------------------------------------------
1 | using APKInstaller.Helpers;
2 | using CommunityToolkit.Mvvm.Input;
3 | using System;
4 | using System.ComponentModel;
5 | using System.Reflection;
6 | using System.Threading.Tasks;
7 | using Windows.System;
8 | using WSATools.Helpers;
9 | using WSATools.Models;
10 | using WSATools.Pages.SettingsPages;
11 | using WSATools.Properties;
12 |
13 | namespace WSATools.ViewModels
14 | {
15 | public sealed class SettingsViewModel : INotifyPropertyChanged
16 | {
17 | public IRelayCommand GotoUpdateCommand { get; }
18 | public IRelayCommand GotoTestPageCommand { get; }
19 | public IAsyncRelayCommand CheackUpdateCommand { get; }
20 |
21 | private DateTime _updateDate = Settings.Default.UpdateDate;
22 | public DateTime UpdateDate
23 | {
24 | get => _updateDate;
25 | set
26 | {
27 | if (_updateDate != value)
28 | {
29 | Settings.Default.UpdateDate = value;
30 | Settings.Default.Save();
31 | _updateDate = Settings.Default.UpdateDate;
32 | RaisePropertyChangedEvent();
33 | }
34 | }
35 | }
36 |
37 | private UpdateInfo _updateInfo = new UpdateInfo();
38 | public UpdateInfo UpdateInfo
39 | {
40 | get => _updateInfo;
41 | set
42 | {
43 | if (_updateInfo != value)
44 | {
45 | _updateInfo = value;
46 | RaisePropertyChangedEvent();
47 | }
48 | }
49 | }
50 |
51 | private string _updateErrorMessage = string.Empty;
52 | public string UpdateErrorMessage
53 | {
54 | get => _updateErrorMessage;
55 | set
56 | {
57 | if (_updateErrorMessage != value)
58 | {
59 | _updateErrorMessage = value;
60 | RaisePropertyChangedEvent();
61 | }
62 | }
63 | }
64 |
65 | private bool _checkingUpdate = false;
66 | public bool CheckingUpdate
67 | {
68 | get => _checkingUpdate;
69 | set
70 | {
71 | if (_checkingUpdate != value)
72 | {
73 | _checkingUpdate = value;
74 | RaisePropertyChangedEvent();
75 | }
76 | }
77 | }
78 |
79 | public string VersionText
80 | {
81 | get
82 | {
83 | string ver = $"{Assembly.GetExecutingAssembly().GetName().Version.Build}.{Assembly.GetExecutingAssembly().GetName().Version.Major}.{Assembly.GetExecutingAssembly().GetName().Version.Minor}";
84 | string name = "WSA Tools";
85 | return $"{name} v{ver}";
86 | }
87 | }
88 |
89 | public event PropertyChangedEventHandler PropertyChanged;
90 |
91 | private void RaisePropertyChangedEvent([System.Runtime.CompilerServices.CallerMemberName] string name = null)
92 | {
93 | if (name != null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); }
94 | }
95 |
96 | public SettingsViewModel()
97 | {
98 | GotoUpdateCommand = new RelayCommand(GotoUpdate);
99 | GotoTestPageCommand = new RelayCommand(GotoTestPage);
100 | CheackUpdateCommand = new AsyncRelayCommand(CheckUpdate);
101 | if (UpdateDate == DateTime.MinValue) { _ = CheckUpdate(); }
102 | }
103 |
104 | private async Task CheckUpdate()
105 | {
106 | CheckingUpdate = true;
107 | try
108 | {
109 | UpdateInfo = await UpdateHelper.CheckUpdateAsync("Paving-Base", "WSA-Tools");
110 | }
111 | catch (Exception ex)
112 | {
113 | UpdateErrorMessage = ex.Message;
114 | UpdateInfo = new UpdateInfo()
115 | {
116 | UpdateState = UpdateState.CheckFailed
117 | };
118 | }
119 | UpdateDate = DateTime.Now;
120 | CheckingUpdate = false;
121 | }
122 |
123 | private void GotoTestPage() => UIHelper.Navigate(typeof(TestPage));
124 |
125 | private void GotoUpdate() => _ = Launcher.LaunchUriAsync(new Uri(UpdateInfo.ReleaseUrl));
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/UpdateHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 | using System.Net;
4 | using System.Net.Http;
5 | using System.Reflection;
6 | using System.Text.Json;
7 | using System.Threading.Tasks;
8 | using WSATools.Models;
9 |
10 | namespace APKInstaller.Helpers
11 | {
12 | public static class UpdateHelper
13 | {
14 | private const string KKPP_API = "https://v2.kkpp.cc/repos/{0}/{1}/releases/latest";
15 | private const string GITHUB_API = "https://api.github.com/repos/{0}/{1}/releases/latest";
16 |
17 | public static async Task CheckUpdateAsync(string username, string repository, Version currentVersion = null)
18 | {
19 | UpdateInfo Info = new UpdateInfo()
20 | {
21 | UpdateState = UpdateState.CheckingUpdate
22 | };
23 |
24 | if (string.IsNullOrEmpty(username))
25 | {
26 | throw new ArgumentNullException(nameof(username));
27 | }
28 |
29 | if (string.IsNullOrEmpty(repository))
30 | {
31 | throw new ArgumentNullException(nameof(repository));
32 | }
33 |
34 | ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;
35 | HttpClient client = new HttpClient();
36 | client.DefaultRequestHeaders.Add("User-Agent", username);
37 | string url = string.Format(GITHUB_API, username, repository);
38 | HttpResponseMessage response = await client.GetAsync(url);
39 | if (!response.IsSuccessStatusCode)
40 | {
41 | url = string.Format(KKPP_API, username, repository);
42 | response = await client.GetAsync(url);
43 | }
44 | string responseBody = await response.Content.ReadAsStringAsync();
45 | UpdateInfo result = JsonSerializer.Deserialize(responseBody);
46 |
47 | if (result != null)
48 | {
49 | if (currentVersion == null)
50 | {
51 | currentVersion = Assembly.GetEntryAssembly().GetName().Version;
52 | }
53 |
54 | SystemVersionInfo newVersionInfo = GetAsVersionInfo(result.TagName);
55 | int major = currentVersion.Major == -1 ? 0 : currentVersion.Major;
56 | int minor = currentVersion.Minor == -1 ? 0 : currentVersion.Minor;
57 | int build = currentVersion.Build == -1 ? 0 : currentVersion.Build;
58 | int revision = currentVersion.Revision == -1 ? 0 : currentVersion.Revision;
59 |
60 | SystemVersionInfo currentVersionInfo = new SystemVersionInfo(major, minor, build, revision);
61 |
62 | Info.Changelog = result?.Changelog;
63 | Info.CreatedAt = Convert.ToDateTime(result?.CreatedAt);
64 | Info.Assets = result.Assets;
65 | Info.IsPreRelease = result.IsPreRelease;
66 | Info.PublishedAt = Convert.ToDateTime(result?.PublishedAt);
67 | Info.TagName = result.TagName;
68 | Info.ApiUrl = result?.ApiUrl;
69 | Info.ReleaseUrl = result?.ReleaseUrl;
70 | Info.IsExistNewVersion = newVersionInfo > currentVersionInfo;
71 | Info.UpdateState = Info.IsExistNewVersion ? UpdateState.ReadyToDownload : UpdateState.UpToDate;
72 | }
73 | else
74 | {
75 | Info.UpdateState = UpdateState.UpToDate;
76 | }
77 | return Info;
78 | }
79 |
80 | private static SystemVersionInfo GetAsVersionInfo(string version)
81 | {
82 | System.Collections.Generic.List nums = GetVersionNumbers(version).Split('.').Select(int.Parse).ToList();
83 |
84 | if (nums.Count <= 1)
85 | {
86 | return new SystemVersionInfo(nums[0], 0, 0, 0);
87 | }
88 | else if (nums.Count <= 2)
89 | {
90 | return new SystemVersionInfo(nums[0], nums[1], 0, 0);
91 | }
92 | else if (nums.Count <= 3)
93 | {
94 | return new SystemVersionInfo(nums[0], nums[1], nums[2], 0);
95 | }
96 | else
97 | {
98 | return new SystemVersionInfo(nums[0], nums[1], nums[2], nums[3]);
99 | }
100 | }
101 |
102 | private static string GetVersionNumbers(string version)
103 | {
104 | string allowedChars = "01234567890.";
105 | return new string(version.Where(c => allowedChars.Contains(c)).ToArray());
106 | }
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Core/Helpers/ADBHelper.cs:
--------------------------------------------------------------------------------
1 | using AdvancedSharpAdbClient;
2 | using AdvancedSharpAdbClient.DeviceCommands;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using System.Diagnostics;
7 | using System.Linq;
8 | using System.Net;
9 | using System.Text;
10 | using System.Threading.Tasks;
11 | using WSATools.Core.Models;
12 | using WSATools.Core.Receivers;
13 |
14 | namespace WSATools.Core.Helpers
15 | {
16 | public static class ADBHelper
17 | {
18 | private static IEnumerable DeviceList;
19 |
20 | public static DeviceData WSA;
21 | public static bool IsConnectWSA = false;
22 | public static StartServerResult? ADBStatus;
23 | public static AdvancedAdbClient ADBClient = new AdvancedAdbClient();
24 | public static DeviceMonitor Monitor = new DeviceMonitor(new AdbSocket(new IPEndPoint(IPAddress.Loopback, AdvancedAdbClient.AdbServerPort)));
25 |
26 | public static void InitilizeADB() => InitilizeADB(null);
27 | public static void InitilizeADB(IProgress progress)
28 | {
29 | Process[] processes = Process.GetProcessesByName("adb");
30 | if (processes != null && processes.Any())
31 | {
32 | ADBStatus = new AdbServer().StartServer(processes.First().MainModule.FileName, restartServerIfNewer: false);
33 | }
34 | if (progress != null)
35 | {
36 | progress.Report(50);
37 | }
38 | if (ADBStatus != null)
39 | {
40 | Monitor.DeviceChanged += OnDeviceChanged;
41 | DeviceList = new AdvancedAdbClient().GetDevices();
42 | }
43 | if (progress != null)
44 | {
45 | progress.Report(100);
46 | }
47 | }
48 |
49 | public static void ConnectWSA() => ConnectWSA(null);
50 | public static void ConnectWSA(IProgress progress)
51 | {
52 | if (DeviceList != null && DeviceList.Any())
53 | {
54 | ConsoleOutputReceiver receiver = new ConsoleOutputReceiver();
55 | foreach (DeviceData device in DeviceList)
56 | {
57 | if (progress != null)
58 | {
59 | progress.Report((double)(DeviceList.ToList().IndexOf(device) + 1) * 100 / DeviceList.Count());
60 | }
61 | if (device == null || device.State == DeviceState.Offline) { continue; }
62 | ADBClient.ExecuteRemoteCommand("getprop ro.boot.hardware", device, receiver);
63 | if (receiver.ToString().Contains("windows"))
64 | {
65 | WSA = device ?? WSA;
66 | IsConnectWSA = true;
67 | break;
68 | }
69 | }
70 | }
71 | else
72 | {
73 | IsConnectWSA = false;
74 | }
75 | }
76 |
77 | public static ObservableCollection GetAppsList()
78 | {
79 | ObservableCollection Applications = new ObservableCollection();
80 | AdvancedAdbClient client = new AdvancedAdbClient();
81 | PackageManager manager = new PackageManager(client, WSA);
82 | foreach (KeyValuePair app in manager.Packages)
83 | {
84 | if (!string.IsNullOrEmpty(app.Key))
85 | {
86 | ConsoleOutputReceiver receiver = new ConsoleOutputReceiver();
87 | client.ExecuteRemoteCommand($"pidof {app.Key}", WSA, receiver);
88 | bool isactive = !string.IsNullOrEmpty(receiver.ToString());
89 | Applications.Add(new APKInfo()
90 | {
91 | Name = app.Key,
92 | IsActive = isactive,
93 | VersionInfo = manager.GetVersionInfo(app.Key)
94 | });
95 | }
96 | }
97 | return Applications;
98 | }
99 |
100 | public static ObservableCollection GetStorageInfo()
101 | {
102 | StorageReceiver receiver = new StorageReceiver();
103 | if (WSA != null)
104 | {
105 | ADBClient.ExecuteRemoteCommand("df", WSA, receiver);
106 | }
107 | return receiver.Storages;
108 | }
109 |
110 | private static void OnDeviceChanged(object sender, DeviceDataEventArgs e)
111 | {
112 | DeviceList = new AdvancedAdbClient().GetDevices();
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Styles/Button.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
87 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Helpers/UIHelper.cs:
--------------------------------------------------------------------------------
1 | using ModernWpf.Media.Animation;
2 | using System;
3 | using System.Collections.ObjectModel;
4 | using System.Drawing;
5 | using System.Threading.Tasks;
6 | using WSATools.Pages;
7 |
8 | namespace WSATools.Helpers
9 | {
10 | internal static class UIHelper
11 | {
12 | public const string Error = "";
13 | public const string Seccess = "";
14 | public const string Message = "";
15 | public const string Warnning = "";
16 | public const string AppTitle = "Universal-like Minecraft Launcher";
17 |
18 | public static float DpiX, DpiY;
19 | public static MainPage MainPage;
20 | public static MainWindow MainWindow;
21 | public static bool IsShowingProgressRing, IsShowingProgressBar, IsShowingMessage;
22 | private static readonly ObservableCollection<(string message, string info, MainPage.MessageColor color)> MessageList = new();
23 |
24 | public enum NavigationThemeTransition
25 | {
26 | Default,
27 | Entrance,
28 | DrillIn,
29 | Suppress
30 | }
31 |
32 | static UIHelper()
33 | {
34 | Graphics graphics = Graphics.FromHwnd(IntPtr.Zero);
35 | DpiX = graphics.DpiX / 96;
36 | DpiY = graphics.DpiY / 96;
37 | }
38 |
39 | public static void Navigate(Type pageType, object e = null, NavigationThemeTransition Type = NavigationThemeTransition.Default)
40 | {
41 | _ = Type switch
42 | {
43 | NavigationThemeTransition.DrillIn => MainPage?.NavigationViewFrame.Navigate(pageType, e, new DrillInNavigationTransitionInfo()),
44 | NavigationThemeTransition.Entrance => MainPage?.NavigationViewFrame.Navigate(pageType, e, new EntranceNavigationTransitionInfo()),
45 | NavigationThemeTransition.Suppress => MainPage?.NavigationViewFrame.Navigate(pageType, e, new SuppressNavigationTransitionInfo()),
46 | NavigationThemeTransition.Default => MainPage?.NavigationViewFrame.Navigate(pageType, e),
47 | _ => MainPage?.NavigationViewFrame.Navigate(pageType, e),
48 | };
49 | }
50 |
51 | ///
52 | /// 显示进度环
53 | ///
54 | public static void ShowProgressRing()
55 | {
56 | IsShowingProgressRing = true;
57 | MainPage.ShowProgressRing();
58 | }
59 |
60 | ///
61 | /// 隐藏进度环
62 | ///
63 | public static void HideProgressRing()
64 | {
65 | IsShowingProgressRing = false;
66 | MainPage.HideProgressRing();
67 | }
68 |
69 | ///
70 | /// 显示进度条-正常
71 | ///
72 | public static void ShowProgressBar()
73 | {
74 | IsShowingProgressBar = true;
75 | MainPage.ShowProgressBar();
76 | }
77 |
78 | ///
79 | /// 显示进度条-暂停
80 | ///
81 | public static void PausedProgressBar()
82 | {
83 | IsShowingProgressBar = true;
84 | MainPage.PausedProgressBar();
85 | }
86 |
87 | ///
88 | /// 显示进度条-错误
89 | ///
90 | public static void ErrorProgressBar()
91 | {
92 | IsShowingProgressBar = true;
93 | MainPage.ErrorProgressBar();
94 | }
95 |
96 | ///
97 | /// 隐藏进度条
98 | ///
99 | public static void HideProgressBar()
100 | {
101 | IsShowingProgressBar = false;
102 | MainPage.HideProgressBar();
103 | }
104 |
105 | ///
106 | /// 展示应用内通知
107 | ///
108 | /// 要展示的消息
109 | /// 消息前的图标
110 | /// 消息前图标的颜色
111 | public static async void ShowMessage(string message, string info = Message, MainPage.MessageColor color = MainPage.MessageColor.Blue)
112 | {
113 | MessageList.Add((message, info, color));
114 | if (!IsShowingMessage)
115 | {
116 | IsShowingMessage = true;
117 | while (MessageList.Count > 0)
118 | {
119 | if (!string.IsNullOrEmpty(MessageList[0].message))
120 | {
121 | string messages = $"{MessageList[0].message.Replace("\n", " ")}";
122 | MainPage.ShowMessage(messages, MessageList[0].info, MessageList[0].color);
123 | await Task.Delay(3000);
124 | }
125 | MessageList.RemoveAt(0);
126 | if (MessageList.Count == 0)
127 | {
128 | MainPage.HideMessage();
129 | }
130 | }
131 | IsShowingMessage = false;
132 | }
133 | }
134 |
135 | ///
136 | /// 获取时间内的问候语
137 | ///
138 | /// 问候语
139 | public static string GetGreetings()
140 | {
141 | string str = "";
142 | DateTime now = DateTime.Now;
143 | int times = now.Hour;
144 | if (times is >= 0 and < 6) { str = "熬夜对身体不好哦"; }
145 | if (times is >= 6 and < 9) { str = "早安"; }
146 | if (times is >= 9 and < 11) { str = "上午好"; }
147 | if (times is >= 11 and < 13) { str = "中午好"; }
148 | if (times is >= 13 and < 17) { str = "下午好"; }
149 | if (times is >= 17 and < 19) { str = "吃过晚饭了吗"; }
150 | if (times is >= 19 and < 24) { str = "晚安"; }
151 | return str;
152 | }
153 |
154 | ///
155 | /// 将字节数转换为可读数据
156 | ///
157 | /// 字节数
158 | /// xx.xx xB
159 | public static string GetSizeString(this double size)
160 | {
161 | int index = 0;
162 | while (true)
163 | {
164 | index++;
165 | size /= 1024;
166 | if (size is > 0.7 and < 716.8) { break; }
167 | else if (size >= 716.8) { continue; }
168 | else if (size <= 0.7)
169 | {
170 | size *= 1024;
171 | index--;
172 | break;
173 | }
174 | }
175 | string str = string.Empty;
176 | switch (index)
177 | {
178 | case 0: str = "B"; break;
179 | case 1: str = "KB"; break;
180 | case 2: str = "MB"; break;
181 | case 3: str = "GB"; break;
182 | case 4: str = "TB"; break;
183 | default:
184 | break;
185 | }
186 | return $"{size:N2}{str}";
187 | }
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Aa][Rr][Mm]/
27 | [Aa][Rr][Mm]64/
28 | bld/
29 | [Bb]in/
30 | [Oo]bj/
31 | [Ll]og/
32 | [Ll]ogs/
33 |
34 | # Visual Studio 2015/2017 cache/options directory
35 | .vs/
36 | # Uncomment if you have tasks that create the project's static files in wwwroot
37 | #wwwroot/
38 |
39 | # Visual Studio 2017 auto generated files
40 | Generated\ Files/
41 |
42 | # MSTest test Results
43 | [Tt]est[Rr]esult*/
44 | [Bb]uild[Ll]og.*
45 |
46 | # NUnit
47 | *.VisualState.xml
48 | TestResult.xml
49 | nunit-*.xml
50 |
51 | # Build Results of an ATL Project
52 | [Dd]ebugPS/
53 | [Rr]eleasePS/
54 | dlldata.c
55 |
56 | # Benchmark Results
57 | BenchmarkDotNet.Artifacts/
58 |
59 | # .NET Core
60 | project.lock.json
61 | project.fragment.lock.json
62 | artifacts/
63 |
64 | # StyleCop
65 | StyleCopReport.xml
66 |
67 | # Files built by Visual Studio
68 | *_i.c
69 | *_p.c
70 | *_h.h
71 | *.ilk
72 | *.meta
73 | *.obj
74 | *.iobj
75 | *.pch
76 | *.pdb
77 | *.ipdb
78 | *.pgc
79 | *.pgd
80 | *.rsp
81 | *.sbr
82 | *.tlb
83 | *.tli
84 | *.tlh
85 | *.tmp
86 | *.tmp_proj
87 | *_wpftmp.csproj
88 | *.log
89 | *.vspscc
90 | *.vssscc
91 | .builds
92 | *.pidb
93 | *.svclog
94 | *.scc
95 |
96 | # Chutzpah Test files
97 | _Chutzpah*
98 |
99 | # Visual C++ cache files
100 | ipch/
101 | *.aps
102 | *.ncb
103 | *.opendb
104 | *.opensdf
105 | *.sdf
106 | *.cachefile
107 | *.VC.db
108 | *.VC.VC.opendb
109 |
110 | # Visual Studio profiler
111 | *.psess
112 | *.vsp
113 | *.vspx
114 | *.sap
115 |
116 | # Visual Studio Trace Files
117 | *.e2e
118 |
119 | # TFS 2012 Local Workspace
120 | $tf/
121 |
122 | # Guidance Automation Toolkit
123 | *.gpState
124 |
125 | # ReSharper is a .NET coding add-in
126 | _ReSharper*/
127 | *.[Rr]e[Ss]harper
128 | *.DotSettings.user
129 |
130 | # TeamCity is a build add-in
131 | _TeamCity*
132 |
133 | # DotCover is a Code Coverage Tool
134 | *.dotCover
135 |
136 | # AxoCover is a Code Coverage Tool
137 | .axoCover/*
138 | !.axoCover/settings.json
139 |
140 | # Visual Studio code coverage results
141 | *.coverage
142 | *.coveragexml
143 |
144 | # NCrunch
145 | _NCrunch_*
146 | .*crunch*.local.xml
147 | nCrunchTemp_*
148 |
149 | # MightyMoose
150 | *.mm.*
151 | AutoTest.Net/
152 |
153 | # Web workbench (sass)
154 | .sass-cache/
155 |
156 | # Installshield output folder
157 | [Ee]xpress/
158 |
159 | # DocProject is a documentation generator add-in
160 | DocProject/buildhelp/
161 | DocProject/Help/*.HxT
162 | DocProject/Help/*.HxC
163 | DocProject/Help/*.hhc
164 | DocProject/Help/*.hhk
165 | DocProject/Help/*.hhp
166 | DocProject/Help/Html2
167 | DocProject/Help/html
168 |
169 | # Click-Once directory
170 | publish/
171 |
172 | # Publish Web Output
173 | *.[Pp]ublish.xml
174 | *.azurePubxml
175 | # Note: Comment the next line if you want to checkin your web deploy settings,
176 | # but database connection strings (with potential passwords) will be unencrypted
177 | *.pubxml
178 | *.publishproj
179 |
180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
181 | # checkin your Azure Web App publish settings, but sensitive information contained
182 | # in these scripts will be unencrypted
183 | PublishScripts/
184 |
185 | # NuGet Packages
186 | *.nupkg
187 | # NuGet Symbol Packages
188 | *.snupkg
189 | # The packages folder can be ignored because of Package Restore
190 | **/[Pp]ackages/*
191 | # except build/, which is used as an MSBuild target.
192 | !**/[Pp]ackages/build/
193 | # Uncomment if necessary however generally it will be regenerated when needed
194 | #!**/[Pp]ackages/repositories.config
195 | # NuGet v3's project.json files produces more ignorable files
196 | *.nuget.props
197 | *.nuget.targets
198 |
199 | # Microsoft Azure Build Output
200 | csx/
201 | *.build.csdef
202 |
203 | # Microsoft Azure Emulator
204 | ecf/
205 | rcf/
206 |
207 | # Windows Store app package directories and files
208 | AppPackages/
209 | BundleArtifacts/
210 | Package.StoreAssociation.xml
211 | _pkginfo.txt
212 | *.appx
213 | *.appxbundle
214 | *.appxupload
215 |
216 | # Visual Studio cache files
217 | # files ending in .cache can be ignored
218 | *.[Cc]ache
219 | # but keep track of directories ending in .cache
220 | !?*.[Cc]ache/
221 |
222 | # Others
223 | ClientBin/
224 | ~$*
225 | *~
226 | *.dbmdl
227 | *.dbproj.schemaview
228 | *.jfm
229 | *.pfx
230 | *.publishsettings
231 | orleans.codegen.cs
232 |
233 | # Including strong name files can present a security risk
234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
235 | #*.snk
236 |
237 | # Since there are multiple workflows, uncomment next line to ignore bower_components
238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
239 | #bower_components/
240 |
241 | # RIA/Silverlight projects
242 | Generated_Code/
243 |
244 | # Backup & report files from converting an old project file
245 | # to a newer Visual Studio version. Backup files are not needed,
246 | # because we have git ;-)
247 | _UpgradeReport_Files/
248 | Backup*/
249 | UpgradeLog*.XML
250 | UpgradeLog*.htm
251 | ServiceFabricBackup/
252 | *.rptproj.bak
253 |
254 | # SQL Server files
255 | *.mdf
256 | *.ldf
257 | *.ndf
258 |
259 | # Business Intelligence projects
260 | *.rdl.data
261 | *.bim.layout
262 | *.bim_*.settings
263 | *.rptproj.rsuser
264 | *- [Bb]ackup.rdl
265 | *- [Bb]ackup ([0-9]).rdl
266 | *- [Bb]ackup ([0-9][0-9]).rdl
267 |
268 | # Microsoft Fakes
269 | FakesAssemblies/
270 |
271 | # GhostDoc plugin setting file
272 | *.GhostDoc.xml
273 |
274 | # Node.js Tools for Visual Studio
275 | .ntvs_analysis.dat
276 | node_modules/
277 |
278 | # Visual Studio 6 build log
279 | *.plg
280 |
281 | # Visual Studio 6 workspace options file
282 | *.opt
283 |
284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
285 | *.vbw
286 |
287 | # Visual Studio LightSwitch build output
288 | **/*.HTMLClient/GeneratedArtifacts
289 | **/*.DesktopClient/GeneratedArtifacts
290 | **/*.DesktopClient/ModelManifest.xml
291 | **/*.Server/GeneratedArtifacts
292 | **/*.Server/ModelManifest.xml
293 | _Pvt_Extensions
294 |
295 | # Paket dependency manager
296 | .paket/paket.exe
297 | paket-files/
298 |
299 | # FAKE - F# Make
300 | .fake/
301 |
302 | # CodeRush personal settings
303 | .cr/personal
304 |
305 | # Python Tools for Visual Studio (PTVS)
306 | __pycache__/
307 | *.pyc
308 |
309 | # Cake - Uncomment if you are using it
310 | # tools/**
311 | # !tools/packages.config
312 |
313 | # Tabs Studio
314 | *.tss
315 |
316 | # Telerik's JustMock configuration file
317 | *.jmconfig
318 |
319 | # BizTalk build output
320 | *.btp.cs
321 | *.btm.cs
322 | *.odx.cs
323 | *.xsd.cs
324 |
325 | # OpenCover UI analysis results
326 | OpenCover/
327 |
328 | # Azure Stream Analytics local run output
329 | ASALocalRun/
330 |
331 | # MSBuild Binary and Structured Log
332 | *.binlog
333 |
334 | # NVidia Nsight GPU debugger configuration file
335 | *.nvuser
336 |
337 | # MFractors (Xamarin productivity tool) working folder
338 | .mfractor/
339 |
340 | # Local History for Visual Studio
341 | .localhistory/
342 |
343 | # BeatPulse healthcheck temp database
344 | healthchecksdb
345 |
346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
347 | MigrationBackup/
348 |
349 | # Ionide (cross platform F# VS Code tools) working folder
350 | .ionide/
351 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Controls/Setting.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Windows;
3 | using System.Windows.Automation;
4 | using System.Windows.Controls;
5 |
6 | namespace WSATools.Controls
7 | {
8 | ///
9 | /// 按照步骤 1a 或 1b 操作,然后执行步骤 2 以在 XAML 文件中使用此自定义控件。
10 | ///
11 | /// 步骤 1a) 在当前项目中存在的 XAML 文件中使用该自定义控件。
12 | /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
13 | /// 元素中:
14 | ///
15 | /// xmlns:MyNamespace="clr-namespace:WSATools.Controls"
16 | ///
17 | ///
18 | /// 步骤 1b) 在其他项目中存在的 XAML 文件中使用该自定义控件。
19 | /// 将此 XmlNamespace 特性添加到要使用该特性的标记文件的根
20 | /// 元素中:
21 | ///
22 | /// xmlns:MyNamespace="clr-namespace:WSATools.Controls;assembly=WSATools.Controls"
23 | ///
24 | /// 您还需要添加一个从 XAML 文件所在的项目到此项目的项目引用,
25 | /// 并重新生成以避免编译错误:
26 | ///
27 | /// 在解决方案资源管理器中右击目标项目,然后依次单击
28 | /// “添加引用”->“项目”->[浏览查找并选择此项目]
29 | ///
30 | ///
31 | /// 步骤 2)
32 | /// 继续操作并在 XAML 文件中使用控件。
33 | ///
34 | ///
35 | ///
36 | ///
37 | [TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
38 | [TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")]
39 | [TemplatePart(Name = RightIconPresenter, Type = typeof(Border))]
40 | [TemplatePart(Name = PartIconPresenter, Type = typeof(ContentPresenter))]
41 | [TemplatePart(Name = PartDescriptionPresenter, Type = typeof(ContentPresenter))]
42 | public class Setting : ContentControl
43 | {
44 | private const string PartIconPresenter = "IconPresenter";
45 | private const string PartDescriptionPresenter = "DescriptionPresenter";
46 | private const string RightIconPresenter = "ExpandCollapseChevronBorder";
47 | private Border _rightIconPresenter;
48 | private ContentPresenter _iconPresenter;
49 | private ContentPresenter _descriptionPresenter;
50 | private Setting _setting;
51 |
52 | public Setting()
53 | {
54 | DefaultStyleKey = typeof(Setting);
55 | }
56 |
57 | public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register(
58 | "Header",
59 | typeof(string),
60 | typeof(Setting),
61 | new PropertyMetadata(default(string), OnHeaderChanged));
62 |
63 | public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
64 | "Description",
65 | typeof(object),
66 | typeof(Setting),
67 | new PropertyMetadata(null, OnDescriptionChanged));
68 |
69 | public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
70 | "Icon",
71 | typeof(object),
72 | typeof(Setting),
73 | new PropertyMetadata(default(string), OnIconChanged));
74 |
75 | public static readonly DependencyProperty RightIconProperty = DependencyProperty.Register(
76 | "RightIcon",
77 | typeof(string),
78 | typeof(Setting),
79 | new PropertyMetadata(null, OnIconChanged));
80 |
81 | public static readonly DependencyProperty ActionContentProperty = DependencyProperty.Register(
82 | "ActionContent",
83 | typeof(object),
84 | typeof(Setting),
85 | null);
86 |
87 | //public static readonly DependencyProperty RightIconVisibilityProperty = DependencyProperty.Register(
88 | // "RightIconVisibility",
89 | // typeof(Visibility),
90 | // typeof(Setting),
91 | // new PropertyMetadata(null, OnIconChanged));
92 |
93 | [Localizable(true)]
94 | public string Header
95 | {
96 | get => (string)GetValue(HeaderProperty);
97 | set => SetValue(HeaderProperty, value);
98 | }
99 |
100 | [Localizable(true)]
101 | public object Description
102 | {
103 | get => GetValue(DescriptionProperty);
104 | set => SetValue(DescriptionProperty, value);
105 | }
106 |
107 | public object Icon
108 | {
109 | get => GetValue(IconProperty);
110 | set => SetValue(IconProperty, value);
111 | }
112 |
113 | public string RightIcon
114 | {
115 | get => (string)GetValue(RightIconProperty);
116 | set => SetValue(RightIconProperty, value);
117 | }
118 |
119 | public object ActionContent
120 | {
121 | get => GetValue(ActionContentProperty);
122 | set => SetValue(ActionContentProperty, value);
123 | }
124 |
125 | //public Visibility RightIconVisibility
126 | //{
127 | // get => (Visibility)GetValue(RightIconVisibilityProperty);
128 | // set => SetValue(RightIconVisibilityProperty, value);
129 | //}
130 |
131 | public override void OnApplyTemplate()
132 | {
133 | IsEnabledChanged -= Setting_IsEnabledChanged;
134 | _setting = this;
135 | _rightIconPresenter = (Border)_setting.GetTemplateChild(RightIconPresenter);
136 | _iconPresenter = (ContentPresenter)_setting.GetTemplateChild(PartIconPresenter);
137 | _descriptionPresenter = (ContentPresenter)_setting.GetTemplateChild(PartDescriptionPresenter);
138 | Update();
139 | SetEnabledState();
140 | IsEnabledChanged += Setting_IsEnabledChanged;
141 | base.OnApplyTemplate();
142 | }
143 |
144 | private static void OnHeaderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
145 | {
146 | ((Setting)d).Update();
147 | }
148 |
149 | private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
150 | {
151 | ((Setting)d).Update();
152 | }
153 |
154 | private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
155 | {
156 | ((Setting)d).Update();
157 | }
158 |
159 | private void Setting_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
160 | {
161 | SetEnabledState();
162 | }
163 |
164 | private void SetEnabledState()
165 | {
166 | VisualStateManager.GoToState(this, IsEnabled ? "Normal" : "Disabled", true);
167 | }
168 |
169 | private void Update()
170 | {
171 | if (_setting == null)
172 | {
173 | return;
174 | }
175 |
176 | if (_setting.ActionContent != null)
177 | {
178 | if (_setting.ActionContent.GetType() != typeof(Button))
179 | {
180 | // We do not want to override the default AutomationProperties.Name of a button. Its Content property already describes what it does.
181 | if (!string.IsNullOrEmpty(_setting.Header))
182 | {
183 | AutomationProperties.SetName((UIElement)_setting.ActionContent, _setting.Header);
184 | }
185 | }
186 | }
187 |
188 | if (_setting._iconPresenter != null)
189 | {
190 | if (_setting.Icon == null)
191 | {
192 | _setting._iconPresenter.Visibility = Visibility.Collapsed;
193 | }
194 | else
195 | {
196 | _setting._iconPresenter.Visibility = Visibility.Visible;
197 | }
198 | }
199 |
200 | if (_setting.RightIcon == null)
201 | {
202 | _setting._rightIconPresenter.Visibility = Visibility.Collapsed;
203 | }
204 | else
205 | {
206 | _setting._rightIconPresenter.Visibility = Visibility.Visible;
207 | }
208 |
209 | if (_setting.Description == null)
210 | {
211 | _setting._descriptionPresenter.Visibility = Visibility.Collapsed;
212 | }
213 | else
214 | {
215 | _setting._descriptionPresenter.Visibility = Visibility.Visible;
216 | }
217 | }
218 | }
219 | }
220 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Styles/Setting.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
77 |
83 |
84 |
85 |
86 |
87 |
93 |
94 |
104 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/HomePage.xaml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
29 |
30 |
31 |
36 |
41 |
42 |
43 |
44 |
45 |
46 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
75 |
81 |
87 |
93 |
99 |
105 |
111 |
117 |
123 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
142 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/SettingsPages/SettingsPage.xaml:
--------------------------------------------------------------------------------
1 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
33 |
38 |
39 |
40 |
41 |
42 |
46 |
50 |
56 |
63 |
64 |
65 |
66 |
67 |
72 |
73 |
74 |
79 |
84 |
85 |
86 |
87 |
88 |
93 |
94 |
95 |
100 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
116 |
117 |
118 |
123 |
128 |
129 |
130 |
131 |
132 |
133 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/WSATools/WSATools.Package/WSATools.Package.wapproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 15.0
5 |
6 |
7 |
8 | Debug
9 | x86
10 |
11 |
12 | Release
13 | x86
14 |
15 |
16 | Debug
17 | x64
18 |
19 |
20 | Release
21 | x64
22 |
23 |
24 | Debug
25 | ARM
26 |
27 |
28 | Release
29 | ARM
30 |
31 |
32 | Debug
33 | ARM64
34 |
35 |
36 | Release
37 | ARM64
38 |
39 |
40 | Debug
41 | AnyCPU
42 |
43 |
44 | Release
45 | AnyCPU
46 |
47 |
48 |
49 | $(MSBuildExtensionsPath)\Microsoft\DesktopBridge\
50 |
51 |
52 |
53 | 2d2b8ac2-e1ca-4d65-9a12-4cc863008d20
54 | 10.0.22000.0
55 | 10.0.14393.0
56 | zh-CN
57 | True
58 | $(NoWarn);NU1702
59 | 0CDF4A03E9BE9DD789894BB3C7AD3DEDECD9AB25
60 | False
61 | http://timestamp.digicert.com
62 | SHA256
63 | False
64 | True
65 | neutral
66 | 0
67 | ..\WSATools\WSATools.csproj
68 |
69 |
70 | Always
71 |
72 |
73 | Always
74 |
75 |
76 | Always
77 |
78 |
79 | Always
80 |
81 |
82 | Always
83 |
84 |
85 | Always
86 |
87 |
88 | Always
89 |
90 |
91 | Always
92 |
93 |
94 | Always
95 |
96 |
97 | Always
98 |
99 |
100 |
101 | Designer
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
--------------------------------------------------------------------------------
/WSATools/WSATools/FodyWeavers.xsd:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
13 |
14 |
15 |
16 |
17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
18 |
19 |
20 |
21 |
22 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks
23 |
24 |
25 |
26 |
27 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.
28 |
29 |
30 |
31 |
32 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks.
33 |
34 |
35 |
36 |
37 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks.
38 |
39 |
40 |
41 |
42 | The order of preloaded assemblies, delimited with line breaks.
43 |
44 |
45 |
46 |
47 |
48 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.
49 |
50 |
51 |
52 |
53 | Controls if .pdbs for reference assemblies are also embedded.
54 |
55 |
56 |
57 |
58 | Controls if runtime assemblies are also embedded.
59 |
60 |
61 |
62 |
63 | Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.
64 |
65 |
66 |
67 |
68 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.
69 |
70 |
71 |
72 |
73 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.
74 |
75 |
76 |
77 |
78 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.
79 |
80 |
81 |
82 |
83 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.
84 |
85 |
86 |
87 |
88 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
89 |
90 |
91 |
92 |
93 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.
94 |
95 |
96 |
97 |
98 | A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |
99 |
100 |
101 |
102 |
103 | A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.
104 |
105 |
106 |
107 |
108 | A list of unmanaged 32 bit assembly names to include, delimited with |.
109 |
110 |
111 |
112 |
113 | A list of unmanaged 64 bit assembly names to include, delimited with |.
114 |
115 |
116 |
117 |
118 | The order of preloaded assemblies, delimited with |.
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
127 |
128 |
129 |
130 |
131 | A comma-separated list of error codes that can be safely ignored in assembly verification.
132 |
133 |
134 |
135 |
136 | 'false' to turn off automatic generation of the XML Schema file.
137 |
138 |
139 |
140 |
141 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Pages/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using ModernWpf;
2 | using ModernWpf.Controls;
3 | using ModernWpf.Media.Animation;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Windows;
8 | using System.Windows.Media;
9 | using System.Windows.Navigation;
10 | using WSATools.Controls;
11 | using WSATools.Helpers;
12 | using WSATools.Pages.SettingsPages;
13 |
14 | namespace WSATools.Pages
15 | {
16 | ///
17 | /// MainPage.xaml 的交互逻辑
18 | ///
19 | public partial class MainPage : Page
20 | {
21 | public PageHeader PageHeader => NavigationView.FindDescendant();
22 |
23 | private readonly List<(string Tag, Type Page)> _pages = new()
24 | {
25 | ("Home", typeof(HomePage)),
26 | ("Apps", typeof(AppsPage)),
27 | };
28 |
29 | public MainPage()
30 | {
31 | InitializeComponent();
32 | UIHelper.MainPage = this;
33 | NavigationView.PaneDisplayMode = NavigationViewPaneDisplayMode.Left;
34 | }
35 |
36 | private void NavigationView_Loaded(object sender, RoutedEventArgs e)
37 | {
38 | // Add handler for ContentFrame navigation.
39 | NavigationViewFrame.Navigated += On_Navigated;
40 | NavigationView.SelectedItem = NavigationView.MenuItems[0];
41 | NavigationView.PaneDisplayMode = NavigationViewPaneDisplayMode.Auto;
42 | }
43 |
44 | private void NavigationView_Navigate(string NavItemTag, NavigationTransitionInfo TransitionInfo)
45 | {
46 | Type _page = null;
47 | if (NavItemTag == "settings")
48 | {
49 | _page = typeof(SettingsPage);
50 | }
51 | else
52 | {
53 | (string Tag, Type Page) item = _pages.FirstOrDefault(p => p.Tag.Equals(NavItemTag, StringComparison.Ordinal));
54 | _page = item.Page;
55 | }
56 | // Get the page type before navigation so you can prevent duplicate
57 | // entries in the backstack.
58 | Type PreNavPageType = NavigationViewFrame.CurrentSourcePageType;
59 |
60 | // Only navigate if the selected page isn't currently loaded.
61 | if (!(_page is null) && !Equals(PreNavPageType, _page))
62 | {
63 | _ = NavigationViewFrame.Navigate(_page, null, TransitionInfo);
64 | }
65 | }
66 |
67 | private void NavigationView_BackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) => _ = TryGoBack();
68 |
69 | private void NavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
70 | {
71 | if (args.IsSettingsSelected)
72 | {
73 | _ = NavigationViewFrame.Navigate(typeof(SettingsPage), null, args.RecommendedNavigationTransitionInfo);
74 | }
75 | else if (args.SelectedItemContainer != null)
76 | {
77 | string NavItemTag = args.SelectedItemContainer.Tag.ToString();
78 | NavigationView_Navigate(NavItemTag, args.RecommendedNavigationTransitionInfo);
79 | }
80 | }
81 |
82 | private bool TryGoBack()
83 | {
84 | if (!NavigationViewFrame.CanGoBack)
85 | { return false; }
86 |
87 | // Don't go back if the nav pane is overlayed.
88 | if (NavigationView.IsPaneOpen &&
89 | (NavigationView.DisplayMode == NavigationViewDisplayMode.Compact ||
90 | NavigationView.DisplayMode == NavigationViewDisplayMode.Minimal))
91 | { return false; }
92 |
93 | NavigationViewFrame.GoBack();
94 | return true;
95 | }
96 |
97 | private void On_Navigated(object _, NavigationEventArgs e)
98 | {
99 | NavigationView.IsBackEnabled = NavigationViewFrame.CanGoBack;
100 | if (NavigationViewFrame.SourcePageType == typeof(SettingsPage))
101 | {
102 | // SettingsItem is not part of NavView.MenuItems, and doesn't have a Tag.
103 | NavigationView.SelectedItem = (NavigationViewItem)NavigationView.SettingsItem;
104 | NavigationView.Header = "设置";
105 | }
106 | else if (NavigationViewFrame.SourcePageType == typeof(TestPage))
107 | {
108 | NavigationView.Header = "测试";
109 | }
110 | else if (NavigationViewFrame.SourcePageType != null)
111 | {
112 | (string Tag, Type Page) item = _pages.FirstOrDefault(p => p.Page == e.Content.GetType());
113 |
114 | try
115 | {
116 | NavigationView.SelectedItem = NavigationView.MenuItems
117 | .OfType()
118 | .First(n => n.Tag.Equals(item.Tag));
119 | }
120 | catch
121 | {
122 | try
123 | {
124 | NavigationView.SelectedItem = NavigationView.FooterMenuItems
125 | .OfType()
126 | .First(n => n.Tag.Equals(item.Tag));
127 | }
128 | catch { }
129 | }
130 |
131 | NavigationView.Header = (((NavigationViewItem)NavigationView.SelectedItem)?.Content?.ToString());
132 | }
133 | }
134 |
135 | private void NavigationViewControl_PaneClosing(NavigationView sender, NavigationViewPaneClosingEventArgs args)
136 | {
137 | UpdateAppTitleMargin(sender);
138 | }
139 |
140 | private void NavigationViewControl_PaneOpening(NavigationView sender, object args)
141 | {
142 | UpdateAppTitleMargin(sender);
143 | }
144 |
145 | private void NavigationViewControl_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)
146 | {
147 | Thickness currMargin = AppTitleBar.Margin;
148 |
149 | AppTitleBar.Margin = sender.DisplayMode == NavigationViewDisplayMode.Minimal &&
150 | sender.IsBackButtonVisible != NavigationViewBackButtonVisible.Collapsed
151 | ? new Thickness((sender.CompactPaneLength * 2) - 8, currMargin.Top, currMargin.Right, currMargin.Bottom)
152 | : new Thickness(sender.CompactPaneLength, currMargin.Top, currMargin.Right, currMargin.Bottom);
153 |
154 | UpdateAppTitleMargin(sender);
155 | UpdateHeaderMargin(sender);
156 | }
157 |
158 | private void UpdateAppTitleMargin(NavigationView sender)
159 | {
160 | const int smallLeftIndent = 4, largeLeftIndent = 24;
161 |
162 | Thickness currMargin = AppTitle.Margin;
163 |
164 | AppTitle.Margin = (sender.DisplayMode == NavigationViewDisplayMode.Expanded && sender.IsPaneOpen) ||
165 | (sender.DisplayMode == NavigationViewDisplayMode.Compact && sender.IsPaneOpen) ||
166 | sender.DisplayMode == NavigationViewDisplayMode.Minimal
167 | ? new Thickness(smallLeftIndent, currMargin.Top, currMargin.Right, currMargin.Bottom)
168 | : new Thickness(largeLeftIndent, currMargin.Top, currMargin.Right, currMargin.Bottom);
169 | }
170 |
171 | private void UpdateHeaderMargin(NavigationView sender)
172 | {
173 | if (PageHeader != null)
174 | {
175 | PageHeader.HeaderPadding = sender.DisplayMode == NavigationViewDisplayMode.Minimal
176 | ? (Thickness)Application.Current.Resources["PageHeaderMinimalPadding"]
177 | : (Thickness)Application.Current.Resources["PageHeaderDefaultPadding"];
178 |
179 | Thickness currMargin = PageHeader.Margin;
180 |
181 | PageHeader.Margin = sender.DisplayMode == NavigationViewDisplayMode.Minimal &&
182 | sender.IsBackButtonVisible != NavigationViewBackButtonVisible.Collapsed
183 | ? new Thickness(-sender.CompactPaneLength + 8, currMargin.Top, currMargin.Right, currMargin.Bottom)
184 | : new Thickness(0, currMargin.Top, currMargin.Right, currMargin.Bottom);
185 | }
186 | }
187 |
188 | #region 状态栏
189 | public enum MessageColor
190 | {
191 | Red,
192 | Blue,
193 | Green,
194 | Yellow,
195 | }
196 |
197 | public void ShowProgressRing()
198 | {
199 | if (PageHeader != null)
200 | {
201 | PageHeader.ProgressRing.Visibility = Visibility.Visible;
202 | PageHeader.ProgressRing.IsActive = true;
203 | }
204 | }
205 |
206 | public void HideProgressRing()
207 | {
208 | if (PageHeader != null)
209 | {
210 | PageHeader.ProgressRing.IsActive = false;
211 | PageHeader.ProgressRing.Visibility = Visibility.Collapsed;
212 | }
213 | }
214 |
215 | public void ShowProgressBar()
216 | {
217 | ProgressBar.Visibility = Visibility.Visible;
218 | ProgressBar.IsIndeterminate = true;
219 | ProgressBar.ShowError = false;
220 | ProgressBar.ShowPaused = false;
221 | }
222 |
223 | public void PausedProgressBar()
224 | {
225 | ProgressBar.Visibility = Visibility.Visible;
226 | ProgressBar.IsIndeterminate = true;
227 | ProgressBar.ShowError = false;
228 | ProgressBar.ShowPaused = true;
229 | }
230 |
231 | public void ErrorProgressBar()
232 | {
233 | ProgressBar.Visibility = Visibility.Visible;
234 | ProgressBar.IsIndeterminate = true;
235 | ProgressBar.ShowPaused = false;
236 | ProgressBar.ShowError = true;
237 | }
238 |
239 | public void HideProgressBar()
240 | {
241 | ProgressBar.Visibility = Visibility.Collapsed;
242 | ProgressBar.IsIndeterminate = false;
243 | ProgressBar.ShowError = false;
244 | ProgressBar.ShowPaused = false;
245 | }
246 |
247 | public void ShowMessage(string message, string info, MessageColor color)
248 | {
249 | if (PageHeader != null)
250 | {
251 | PageHeader.Message.Text = message;
252 | PageHeader.MessageInfo.Glyph = info;
253 | PageHeader.MessageInfo.Foreground = color switch
254 | {
255 | MessageColor.Red => new SolidColorBrush(Color.FromArgb(255, 245, 88, 98)),
256 | MessageColor.Blue => new SolidColorBrush(Color.FromArgb(255, 119, 220, 255)),
257 | MessageColor.Green => new SolidColorBrush(Color.FromArgb(255, 155, 230, 155)),
258 | MessageColor.Yellow => new SolidColorBrush(Color.FromArgb(255, 254, 228, 160)),
259 | _ => new SolidColorBrush(Colors.Yellow),
260 | };
261 | PageHeader?.RectanglePointerEntered();
262 | }
263 | }
264 |
265 | public void HideMessage()
266 | {
267 | PageHeader?.RectanglePointerExited();
268 | }
269 |
270 | #endregion
271 | }
272 | }
273 |
--------------------------------------------------------------------------------
/WSATools/WSATools/Styles/SettingExpander.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 | 0
8 | 56, 8, 40, 8
9 |
10 | Transparent
11 |
12 |
13 |
14 |
22 |
23 | 0,0,8,0
24 |
25 |
26 |
33 |
34 |
35 |
45 |
46 |
50 |
51 |
113 |
114 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/WSATools.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31825.309
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "WSATools.Package", "WSATools\WSATools.Package\WSATools.Package.wapproj", "{2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WSATools.Core", "WSATools\WSATools.Core\WSATools.Core.csproj", "{6B116676-7C7B-4AAF-BF6E-8060804C619B}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libs", "Libs", "{9EF757D5-BA69-4C91-80D4-DC9EC0A20C39}"
11 | EndProject
12 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WSATools", "WSATools\WSATools\WSATools.csproj", "{222EEE21-5499-4AC8-80AA-61EFB3306331}"
13 | EndProject
14 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "APPXManager", "..\APPX-Manager\APPXManager\APPXManager.csproj", "{E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}"
15 | EndProject
16 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdvancedSharpAdbClient", "..\AdvancedSharpAdbClient\AdvancedSharpAdbClient\AdvancedSharpAdbClient.csproj", "{4D438611-FD98-4398-A7D2-6536722E072A}"
17 | EndProject
18 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernWpf", "..\ModernWpf\ModernWpf\ModernWpf.csproj", "{FA1A05E8-4239-4F3F-AF62-79C80FCE776F}"
19 | EndProject
20 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModernWpf.Controls", "..\ModernWpf\ModernWpf.Controls\ModernWpf.Controls.csproj", "{0D6C32F1-6CA0-41A1-8797-66819EB61896}"
21 | EndProject
22 | Global
23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
24 | Debug|Any CPU = Debug|Any CPU
25 | Debug|ARM = Debug|ARM
26 | Debug|ARM64 = Debug|ARM64
27 | Debug|x64 = Debug|x64
28 | Debug|x86 = Debug|x86
29 | Release|Any CPU = Release|Any CPU
30 | Release|ARM = Release|ARM
31 | Release|ARM64 = Release|ARM64
32 | Release|x64 = Release|x64
33 | Release|x86 = Release|x86
34 | EndGlobalSection
35 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
36 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
37 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|Any CPU.Build.0 = Debug|Any CPU
38 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
39 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|ARM.ActiveCfg = Debug|ARM
40 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|ARM.Build.0 = Debug|ARM
41 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|ARM.Deploy.0 = Debug|ARM
42 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|ARM64.ActiveCfg = Debug|ARM64
43 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|ARM64.Build.0 = Debug|ARM64
44 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|ARM64.Deploy.0 = Debug|ARM64
45 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|x64.ActiveCfg = Debug|x64
46 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|x64.Build.0 = Debug|x64
47 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|x64.Deploy.0 = Debug|x64
48 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|x86.ActiveCfg = Debug|x86
49 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|x86.Build.0 = Debug|x86
50 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Debug|x86.Deploy.0 = Debug|x86
51 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|Any CPU.ActiveCfg = Release|Any CPU
52 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|Any CPU.Build.0 = Release|Any CPU
53 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|Any CPU.Deploy.0 = Release|Any CPU
54 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|ARM.ActiveCfg = Release|ARM
55 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|ARM.Build.0 = Release|ARM
56 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|ARM.Deploy.0 = Release|ARM
57 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|ARM64.ActiveCfg = Release|ARM64
58 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|ARM64.Build.0 = Release|ARM64
59 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|ARM64.Deploy.0 = Release|ARM64
60 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|x64.ActiveCfg = Release|x64
61 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|x64.Build.0 = Release|x64
62 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|x64.Deploy.0 = Release|x64
63 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|x86.ActiveCfg = Release|x86
64 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|x86.Build.0 = Release|x86
65 | {2D2B8AC2-E1CA-4D65-9A12-4CC863008D20}.Release|x86.Deploy.0 = Release|x86
66 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
67 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|Any CPU.Build.0 = Debug|Any CPU
68 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|ARM.ActiveCfg = Debug|Any CPU
69 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|ARM.Build.0 = Debug|Any CPU
70 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|ARM64.ActiveCfg = Debug|Any CPU
71 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|ARM64.Build.0 = Debug|Any CPU
72 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|x64.ActiveCfg = Debug|Any CPU
73 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|x64.Build.0 = Debug|Any CPU
74 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|x86.ActiveCfg = Debug|Any CPU
75 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Debug|x86.Build.0 = Debug|Any CPU
76 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|Any CPU.ActiveCfg = Release|Any CPU
77 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|Any CPU.Build.0 = Release|Any CPU
78 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|ARM.ActiveCfg = Release|Any CPU
79 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|ARM.Build.0 = Release|Any CPU
80 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|ARM64.ActiveCfg = Release|Any CPU
81 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|ARM64.Build.0 = Release|Any CPU
82 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|x64.ActiveCfg = Release|Any CPU
83 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|x64.Build.0 = Release|Any CPU
84 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|x86.ActiveCfg = Release|Any CPU
85 | {6B116676-7C7B-4AAF-BF6E-8060804C619B}.Release|x86.Build.0 = Release|Any CPU
86 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
87 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|Any CPU.Build.0 = Debug|Any CPU
88 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|ARM.ActiveCfg = Debug|Any CPU
89 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|ARM.Build.0 = Debug|Any CPU
90 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|ARM64.ActiveCfg = Debug|Any CPU
91 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|ARM64.Build.0 = Debug|Any CPU
92 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|x64.ActiveCfg = Debug|Any CPU
93 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|x64.Build.0 = Debug|Any CPU
94 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|x86.ActiveCfg = Debug|Any CPU
95 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Debug|x86.Build.0 = Debug|Any CPU
96 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|Any CPU.ActiveCfg = Release|Any CPU
97 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|Any CPU.Build.0 = Release|Any CPU
98 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|ARM.ActiveCfg = Release|Any CPU
99 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|ARM.Build.0 = Release|Any CPU
100 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|ARM64.ActiveCfg = Release|Any CPU
101 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|ARM64.Build.0 = Release|Any CPU
102 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|x64.ActiveCfg = Release|Any CPU
103 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|x64.Build.0 = Release|Any CPU
104 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|x86.ActiveCfg = Release|Any CPU
105 | {222EEE21-5499-4AC8-80AA-61EFB3306331}.Release|x86.Build.0 = Release|Any CPU
106 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
107 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
108 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|ARM.ActiveCfg = Debug|Any CPU
109 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|ARM.Build.0 = Debug|Any CPU
110 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|ARM64.ActiveCfg = Debug|Any CPU
111 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|ARM64.Build.0 = Debug|Any CPU
112 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|x64.ActiveCfg = Debug|Any CPU
113 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|x64.Build.0 = Debug|Any CPU
114 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|x86.ActiveCfg = Debug|Any CPU
115 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Debug|x86.Build.0 = Debug|Any CPU
116 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
117 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|Any CPU.Build.0 = Release|Any CPU
118 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|ARM.ActiveCfg = Release|Any CPU
119 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|ARM.Build.0 = Release|Any CPU
120 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|ARM64.ActiveCfg = Release|Any CPU
121 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|ARM64.Build.0 = Release|Any CPU
122 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|x64.ActiveCfg = Release|Any CPU
123 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|x64.Build.0 = Release|Any CPU
124 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|x86.ActiveCfg = Release|Any CPU
125 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E}.Release|x86.Build.0 = Release|Any CPU
126 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
127 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|Any CPU.Build.0 = Debug|Any CPU
128 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|ARM.ActiveCfg = Debug|Any CPU
129 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|ARM.Build.0 = Debug|Any CPU
130 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
131 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|ARM64.Build.0 = Debug|Any CPU
132 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|x64.ActiveCfg = Debug|Any CPU
133 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|x64.Build.0 = Debug|Any CPU
134 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|x86.ActiveCfg = Debug|Any CPU
135 | {4D438611-FD98-4398-A7D2-6536722E072A}.Debug|x86.Build.0 = Debug|Any CPU
136 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|Any CPU.ActiveCfg = Release|Any CPU
137 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|Any CPU.Build.0 = Release|Any CPU
138 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|ARM.ActiveCfg = Release|Any CPU
139 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|ARM.Build.0 = Release|Any CPU
140 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|ARM64.ActiveCfg = Release|Any CPU
141 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|ARM64.Build.0 = Release|Any CPU
142 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|x64.ActiveCfg = Release|Any CPU
143 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|x64.Build.0 = Release|Any CPU
144 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|x86.ActiveCfg = Release|Any CPU
145 | {4D438611-FD98-4398-A7D2-6536722E072A}.Release|x86.Build.0 = Release|Any CPU
146 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
147 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|Any CPU.Build.0 = Debug|Any CPU
148 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|ARM.ActiveCfg = Debug|Any CPU
149 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|ARM.Build.0 = Debug|Any CPU
150 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
151 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|ARM64.Build.0 = Debug|Any CPU
152 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|x64.ActiveCfg = Debug|Any CPU
153 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|x64.Build.0 = Debug|Any CPU
154 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|x86.ActiveCfg = Debug|Any CPU
155 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Debug|x86.Build.0 = Debug|Any CPU
156 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|Any CPU.ActiveCfg = Release|Any CPU
157 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|Any CPU.Build.0 = Release|Any CPU
158 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|ARM.ActiveCfg = Release|Any CPU
159 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|ARM.Build.0 = Release|Any CPU
160 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|ARM64.ActiveCfg = Release|Any CPU
161 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|ARM64.Build.0 = Release|Any CPU
162 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|x64.ActiveCfg = Release|Any CPU
163 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|x64.Build.0 = Release|Any CPU
164 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|x86.ActiveCfg = Release|Any CPU
165 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F}.Release|x86.Build.0 = Release|Any CPU
166 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
167 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|Any CPU.Build.0 = Debug|Any CPU
168 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|ARM.ActiveCfg = Debug|Any CPU
169 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|ARM.Build.0 = Debug|Any CPU
170 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|ARM64.ActiveCfg = Debug|Any CPU
171 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|ARM64.Build.0 = Debug|Any CPU
172 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|x64.ActiveCfg = Debug|Any CPU
173 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|x64.Build.0 = Debug|Any CPU
174 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|x86.ActiveCfg = Debug|Any CPU
175 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Debug|x86.Build.0 = Debug|Any CPU
176 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|Any CPU.ActiveCfg = Release|Any CPU
177 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|Any CPU.Build.0 = Release|Any CPU
178 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|ARM.ActiveCfg = Release|Any CPU
179 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|ARM.Build.0 = Release|Any CPU
180 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|ARM64.ActiveCfg = Release|Any CPU
181 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|ARM64.Build.0 = Release|Any CPU
182 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|x64.ActiveCfg = Release|Any CPU
183 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|x64.Build.0 = Release|Any CPU
184 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|x86.ActiveCfg = Release|Any CPU
185 | {0D6C32F1-6CA0-41A1-8797-66819EB61896}.Release|x86.Build.0 = Release|Any CPU
186 | EndGlobalSection
187 | GlobalSection(SolutionProperties) = preSolution
188 | HideSolutionNode = FALSE
189 | EndGlobalSection
190 | GlobalSection(NestedProjects) = preSolution
191 | {E1C60DB9-E39F-4FD1-8101-E4D03E608B0E} = {9EF757D5-BA69-4C91-80D4-DC9EC0A20C39}
192 | {4D438611-FD98-4398-A7D2-6536722E072A} = {9EF757D5-BA69-4C91-80D4-DC9EC0A20C39}
193 | {FA1A05E8-4239-4F3F-AF62-79C80FCE776F} = {9EF757D5-BA69-4C91-80D4-DC9EC0A20C39}
194 | {0D6C32F1-6CA0-41A1-8797-66819EB61896} = {9EF757D5-BA69-4C91-80D4-DC9EC0A20C39}
195 | EndGlobalSection
196 | GlobalSection(ExtensibilityGlobals) = postSolution
197 | SolutionGuid = {0F361E18-34D0-4ADB-9027-73C449E873E6}
198 | EndGlobalSection
199 | EndGlobal
200 |
--------------------------------------------------------------------------------