mirror of
https://github.com/mashed-potatoes/PotatoNV.git
synced 2024-09-20 04:54:00 +02:00
Add UsbController, make logging safe with Dispatcher
This commit is contained in:
parent
b9b3e40346
commit
cc44a41f52
8 changed files with 212 additions and 19 deletions
|
@ -8,13 +8,19 @@ EndProject
|
|||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Debug|x64.Build.0 = Debug|x64
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|x64.ActiveCfg = Release|x64
|
||||
{2F103DCF-DFBA-48B0-BEA4-D4B845532A42}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace PotatoNV_next.Controls
|
|||
private void TelegramButton_ButtonClicked(object sender, EventArgs e)
|
||||
{
|
||||
Log.Debug("Clicked to Telegram button!");
|
||||
Process.Start("https://t.me/RePotato");
|
||||
Process.Start("https://t.me/s/RePotato");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,7 @@
|
|||
using PotatoNV_next.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace PotatoNV_next.Controls
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<Grid Margin="4">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="16" />
|
||||
<RowDefinition x:Name="progressBarRowDefinition" Height="16" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBox x:Name="logBox"
|
||||
|
|
|
@ -28,17 +28,33 @@ namespace PotatoNV_next.Controls
|
|||
"ShowProgressBar",
|
||||
typeof(bool),
|
||||
typeof(LogBox),
|
||||
new PropertyMetadata(false)
|
||||
new PropertyMetadata(false, OnPropertyChangedCallback)
|
||||
);
|
||||
|
||||
private static void OnPropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
(sender as LogBox).OnChanged();
|
||||
}
|
||||
|
||||
protected virtual void OnChanged()
|
||||
{
|
||||
progressBarRowDefinition.Height = new GridLength(ShowProgressBar ? 16 : 0);
|
||||
}
|
||||
|
||||
private void AppendLine(LogEventArgs e)
|
||||
{
|
||||
if (!Dispatcher.CheckAccess())
|
||||
{
|
||||
Dispatcher.Invoke(() => logBox.AppendText(e.Message));
|
||||
return;
|
||||
}
|
||||
logBox.AppendText(e.Message);
|
||||
}
|
||||
|
||||
public LogBox()
|
||||
{
|
||||
InitializeComponent();
|
||||
OnChanged();
|
||||
#if DEBUG
|
||||
Log.PrintDebug = true;
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using PotatoNV_next.Utils;
|
||||
using Potato.Fastboot;
|
||||
using PotatoNV_next.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
@ -18,10 +19,22 @@ namespace PotatoNV_next
|
|||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private UsbController usbController = new UsbController();
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
Icon = MediaConverter.ImageSourceFromBitmap(Properties.Resources.Fire.ToBitmap());
|
||||
InitializeComponent();
|
||||
usbController.AddListener(HandleDevices);
|
||||
usbController.StartWorker();
|
||||
}
|
||||
|
||||
private void HandleDevices(UsbController.Device[] devices)
|
||||
{
|
||||
foreach (var device in devices)
|
||||
{
|
||||
Log.Debug($"{device.Mode} - {device.Description}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,6 +55,28 @@
|
|||
<PropertyGroup>
|
||||
<ApplicationIcon>Resources\fire.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>7.3</LangVersion>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>true</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="LibUsbDotNet, Version=3.0.0.0, Culture=neutral, PublicKeyToken=c677239abe1e02a9, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\LibUsbDotNet.3.0.81-alpha\lib\net45\LibUsbDotNet.dll</HintPath>
|
||||
|
@ -71,6 +93,7 @@
|
|||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Memory, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Memory.4.5.1\lib\netstandard2.0\System.Memory.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -108,6 +131,7 @@
|
|||
</Compile>
|
||||
<Compile Include="Utils\Log.cs" />
|
||||
<Compile Include="Utils\MediaConverter.cs" />
|
||||
<Compile Include="Utils\UsbController.cs" />
|
||||
<Page Include="Controls\AboutTab.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
|
149
PotatoNV-next/Utils/UsbController.cs
Normal file
149
PotatoNV-next/Utils/UsbController.cs
Normal file
|
@ -0,0 +1,149 @@
|
|||
using Potato.Fastboot;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PotatoNV_next.Utils
|
||||
{
|
||||
class UsbController
|
||||
{
|
||||
public struct Device
|
||||
{
|
||||
public enum DMode
|
||||
{
|
||||
DownloadVCOM,
|
||||
Fastboot
|
||||
}
|
||||
|
||||
public Device(DMode mode, string description)
|
||||
{
|
||||
Mode = mode;
|
||||
Description = description;
|
||||
}
|
||||
|
||||
public DMode Mode { get; }
|
||||
public string Description { get; }
|
||||
}
|
||||
|
||||
#region USB watcher
|
||||
private readonly BackgroundWorker usbWorker = new BackgroundWorker();
|
||||
private readonly Stopwatch watch = new Stopwatch();
|
||||
private long delta = 0;
|
||||
|
||||
private void Watcher_EventArrived(object sender, EventArrivedEventArgs e)
|
||||
{
|
||||
if (watch.ElapsedMilliseconds - delta < 100)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
delta = watch.ElapsedMilliseconds;
|
||||
|
||||
Log.Debug("New USB event, calling listener...");
|
||||
|
||||
UpdateList();
|
||||
}
|
||||
|
||||
private void UsbWorker_DoWork(object sender, DoWorkEventArgs e)
|
||||
{
|
||||
using (var watcher = new ManagementEventWatcher())
|
||||
{
|
||||
var query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2 OR EventType = 3");
|
||||
watcher.EventArrived += Watcher_EventArrived;
|
||||
watcher.Query = query;
|
||||
watcher.Start();
|
||||
watcher.WaitForNextEvent();
|
||||
}
|
||||
}
|
||||
|
||||
public void StartWorker()
|
||||
{
|
||||
usbWorker.DoWork += UsbWorker_DoWork;
|
||||
watch.Start();
|
||||
usbWorker.RunWorkerAsync();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Device list
|
||||
private const int VID = 0x12D1, PID = 0x3609;
|
||||
private Device[] cachedDevices = null;
|
||||
|
||||
private Device[] GetDownloadVCOMDevices()
|
||||
{
|
||||
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE ClassGuid=\"{4d36e978-e325-11ce-bfc1-08002be10318}\"");
|
||||
var list = searcher.Get();
|
||||
var devices = new List<Device>();
|
||||
|
||||
foreach (ManagementObject obj in list)
|
||||
{
|
||||
// Excepted format: USB\VID_12D1&PID_3609\6&127ABA2B&0&2
|
||||
var sdata = obj["DeviceID"].ToString().Split('\\');
|
||||
|
||||
if (sdata.Length < 2 || sdata[1] != string.Format("VID_{0:X4}&PID_{1:X4}", VID, PID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var match = Regex.Match(obj["Name"].ToString(), @"COM\d+");
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
devices.Add(new Device(
|
||||
Device.DMode.DownloadVCOM,
|
||||
$"{match.Value}: {obj["Description"]}"
|
||||
));
|
||||
}
|
||||
}
|
||||
return devices.ToArray();
|
||||
}
|
||||
|
||||
private Device[] GetFastbootDevices()
|
||||
{
|
||||
return Fastboot.GetDevices()
|
||||
.Select(x => new Device(Device.DMode.Fastboot, x))
|
||||
.ToArray();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Caller
|
||||
private List<Action<Device[]>> listeners = new List<Action<Device[]>>();
|
||||
|
||||
private void UpdateList()
|
||||
{
|
||||
try
|
||||
{
|
||||
var list = new List<Device>();
|
||||
list.AddRange(GetDownloadVCOMDevices());
|
||||
list.AddRange(GetFastbootDevices());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex.Message);
|
||||
Log.Debug(ex.StackTrace);
|
||||
}
|
||||
|
||||
//if (!Enumerable.SequenceEqual(list, cachedDevices))
|
||||
//{
|
||||
// Log.Debug("Sequence equal");
|
||||
// return;
|
||||
//}
|
||||
|
||||
//foreach (var listener in listeners)
|
||||
//{
|
||||
// listener?.Invoke(list.ToArray());
|
||||
//}
|
||||
}
|
||||
|
||||
public void AddListener(Action<Device[]> action)
|
||||
{
|
||||
listeners.Add(action);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue