將寫死改成活讀

This commit is contained in:
DangHome
2023-07-03 01:51:09 +08:00
parent a48d7b8d56
commit a8fd8f3f46
27 changed files with 703 additions and 546 deletions

27
CMMModel/CMMModel.csproj Normal file
View File

@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<AssemblyName>CMM.Model</AssemblyName>
<RootNamespace>CMM.Model</RootNamespace>
<Product>ControlMyMonitorManagement</Product>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Company>Dang</Company>
<Copyright>Copyright © DangWang $([System.DateTime]::Now.ToString(yyyy))</Copyright>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<Major>1</Major>
<Minor>0</Minor>
<ProjectStartedDate>$([System.DateTime]::op_Subtraction($([System.DateTime]::get_Now().get_Date()),$([System.DateTime]::new(2017,9,17))).get_TotalDays())</ProjectStartedDate>
<DaysSinceProjectStarted>$([System.DateTime]::Now.ToString(Hmm))</DaysSinceProjectStarted>
<DateTimeSuffix>$([System.DateTime]::Now.ToString(yyyyMMdd))</DateTimeSuffix>
<VersionSuffix>$(Major).$(Minor).$(ProjectStartedDate).$(DaysSinceProjectStarted)</VersionSuffix>
<AssemblyVersion Condition=" '$(DateTimeSuffix)' == '' ">0.0.0.1</AssemblyVersion>
<AssemblyVersion Condition=" '$(DateTimeSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
<Version Condition=" '$(DateTimeSuffix)' == '' ">0.0.0.1</Version>
<Version Condition=" '$(DateTimeSuffix)' != '' ">$(DateTimeSuffix)</Version>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,17 @@
using System.Text.Json.Serialization;
public class SMonitorModel
{
[JsonPropertyName("VCP Code")]
public string? VCPCode { get; set; }
[JsonPropertyName("VCP Code Name")]
public string? VCPCodeName { get; set; }
[JsonPropertyName("Read-Write")]
public string? ReadWrite { get; set; }
[JsonPropertyName("Current Value")]
public string? CurrentValue { get; set; }
[JsonPropertyName("Maximum Value")]
public string? MaximumValue { get; set; }
[JsonPropertyName("Possible Values")]
public string? PossibleValues { get; set; }
}

View File

@@ -0,0 +1,32 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<AssemblyName>CMM.Service</AssemblyName>
<RootNamespace>CMM.Service</RootNamespace>
<Product>ControlMyMonitorManagement</Product>
<Nullable>enable</Nullable>
<Company>Dang</Company>
<Copyright>Copyright © DangWang $([System.DateTime]::Now.ToString(yyyy))</Copyright>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<Major>1</Major>
<Minor>0</Minor>
<ProjectStartedDate>$([System.DateTime]::op_Subtraction($([System.DateTime]::get_Now().get_Date()),$([System.DateTime]::new(2023,7,2))).get_TotalDays())</ProjectStartedDate>
<DaysSinceProjectStarted>$([System.DateTime]::Now.ToString(Hmm))</DaysSinceProjectStarted>
<DateTimeSuffix>$([System.DateTime]::Now.ToString(yyyyMMdd))</DateTimeSuffix>
<VersionSuffix>$(Major).$(Minor).$(ProjectStartedDate).$(DaysSinceProjectStarted)</VersionSuffix>
<AssemblyVersion Condition=" '$(DateTimeSuffix)' == '' ">0.0.0.1</AssemblyVersion>
<AssemblyVersion Condition=" '$(DateTimeSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
<Version Condition=" '$(DateTimeSuffix)' == '' ">0.0.0.1</Version>
<Version Condition=" '$(DateTimeSuffix)' != '' ">$(DateTimeSuffix)</Version>
</PropertyGroup>
<ItemGroup>
<Folder Include="Interface\" />
<Folder Include="Service\" />
</ItemGroup>
</Project>

View File

@@ -11,7 +11,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Language", "Language\Langua
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tester", "Tester\Tester.csproj", "{0D34DD73-3282-40EB-8F59-DF190944BF12}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tester", "Tester\Tester.csproj", "{0D34DD73-3282-40EB-8F59-DF190944BF12}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DellMonitorControl", "DellMonitorControl\DellMonitorControl.csproj", "{64E96610-D431-40B9-A00B-55CE195B4B58}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DellMonitorControl", "DellMonitorControl\DellMonitorControl.csproj", "{64E96610-D431-40B9-A00B-55CE195B4B58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CMMService", "CMMService\CMMService.csproj", "{FEA2B019-32BC-4704-939F-1CD26F373F55}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CMMModel", "CMMModel\CMMModel.csproj", "{88440737-DB6E-4ACA-B1BC-E40350153F96}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -39,6 +43,14 @@ Global
{64E96610-D431-40B9-A00B-55CE195B4B58}.Debug|Any CPU.Build.0 = Debug|Any CPU {64E96610-D431-40B9-A00B-55CE195B4B58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{64E96610-D431-40B9-A00B-55CE195B4B58}.Release|Any CPU.ActiveCfg = Release|Any CPU {64E96610-D431-40B9-A00B-55CE195B4B58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{64E96610-D431-40B9-A00B-55CE195B4B58}.Release|Any CPU.Build.0 = Release|Any CPU {64E96610-D431-40B9-A00B-55CE195B4B58}.Release|Any CPU.Build.0 = Release|Any CPU
{FEA2B019-32BC-4704-939F-1CD26F373F55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FEA2B019-32BC-4704-939F-1CD26F373F55}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FEA2B019-32BC-4704-939F-1CD26F373F55}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FEA2B019-32BC-4704-939F-1CD26F373F55}.Release|Any CPU.Build.0 = Release|Any CPU
{88440737-DB6E-4ACA-B1BC-E40350153F96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88440737-DB6E-4ACA-B1BC-E40350153F96}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88440737-DB6E-4ACA-B1BC-E40350153F96}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88440737-DB6E-4ACA-B1BC-E40350153F96}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<RootNamespace>CMM.Management</RootNamespace> <RootNamespace>CMM.Management</RootNamespace>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<Copyright>Copyright © DangWang $([System.DateTime]::Now.ToString(yyyy))</Copyright> <Copyright>Copyright © DangWang $([System.DateTime]::Now.ToString(yyyy))</Copyright>

View File

@@ -7,21 +7,8 @@
mc:Ignorable="d"> mc:Ignorable="d">
<Grid> <Grid>
<Border Background="{DynamicResource H3}" CornerRadius="10" MouseLeave="Border_MouseLeave"/> <Border Background="{DynamicResource H3}" CornerRadius="10" MouseLeave="Border_MouseLeave"/>
<StackPanel> <StackPanel Name="sp" Margin="10">
<StackPanel Orientation="Vertical" Margin="10,5,5,0">
<TextBlock Text="DELL U3223QE (Center)" Style="{StaticResource TitleStyle}" HorizontalAlignment="Left"/>
<Button Tag="BR974P3" Content="Sleep" Click="ToggleButton_Checked" Style="{StaticResource TextButtonStyle}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="10,5,5,0">
<TextBlock Text="DELL U3223QE (Right)" Style="{StaticResource TitleStyle}" HorizontalAlignment="Left"/>
<Button Tag="CBBP3P3" Content="Sleep" Click="ToggleButton_Checked" Style="{StaticResource TextButtonStyle}"/>
</StackPanel>
<StackPanel Orientation="Vertical" Margin="10,5,5,0">
<TextBlock Text="DELL UP2716D (Left)" Style="{StaticResource TitleStyle}" HorizontalAlignment="Left"/>
<Button Tag="KV97067ICLCL" Content="Sleep" Click="ToggleButton_Checked" Style="{StaticResource TextButtonStyle}"/>
</StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -1,7 +1,8 @@
using CMM.Library.Method; using CMM.Library.Method;
using CMM.Library.ViewModel;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
namespace DellMonitorControl; namespace DellMonitorControl;
@@ -16,25 +17,68 @@ public partial class ControlPanel : UserControl
InitializeComponent(); InitializeComponent();
} }
private void Border_MouseLeave(object sender, MouseEventArgs e) public async Task Init()
{ {
await CMMCommand.ScanMonitor();
var monitors = await CMMCommand.ReadMonitorsData();
foreach (var m in monitors)
{
var status = await CMMCommand.GetMonPowerStatus(m.SerialNumber);
var ctrl = CreatControl(m, status);
sp.Children.Add(ctrl);
}
} }
private async void ToggleButton_Checked(object sender, RoutedEventArgs e) private StackPanel CreatControl(XMonitor monitorModel, string powerStatus)
{ {
var toggle = sender as Button; var _sp = new StackPanel();
var tag = toggle?.Tag.ToString();
var content = toggle?.Content as string; _sp.Orientation = Orientation.Vertical;
_sp.Margin = new Thickness(10, 5, 5, 0);
var tb = new TextBlock
{
Text = monitorModel.MonitorName,
HorizontalAlignment = HorizontalAlignment.Left,
Style = (Style)FindResource("LableStyle")
};
var btn = new Button
{
Tag = monitorModel.SerialNumber,
Content = powerStatus,
Style = (Style)FindResource("TextButtonStyle")
};
btn.Click += async (s, e) => await ToggleButton_Checked(s, e);
_sp.Children.Add(tb);
_sp.Children.Add(btn);
return _sp;
}
private void Border_MouseLeave(object sender, MouseEventArgs e)
{
}
private async Task ToggleButton_Checked(object sender, RoutedEventArgs e)
{
var btn = sender as Button;
var tag = btn?.Tag.ToString();
var content = btn?.Content as string;
if (content == "Sleep") if (content == "Sleep")
{ {
await CMMCommand.Sleep(tag); await CMMCommand.PowerOn(tag);
toggle!.Content = "PowerOn";
} }
else else
{ {
await CMMCommand.PowerOn(tag); await CMMCommand.Sleep(tag);
toggle!.Content = "Sleep";
} }
await Task.Delay(1000);
btn!.Content = await CMMCommand.GetMonPowerStatus(tag);
} }
} }

View File

@@ -2,12 +2,27 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AssemblyName>DellMonitorControl</AssemblyName> <AssemblyName>DellMonitorControl</AssemblyName>
<RootNamespace>DellMonitorControl</RootNamespace> <RootNamespace>DellMonitorControl</RootNamespace>
<Product>DellMonitorControl</Product> <Product>ControlMyMonitorManagement</Product>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<Company>Dang</Company>
<Copyright>Copyright © DangWang $([System.DateTime]::Now.ToString(yyyy))</Copyright>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<Major>1</Major>
<Minor>0</Minor>
<ProjectStartedDate>$([System.DateTime]::op_Subtraction($([System.DateTime]::get_Now().get_Date()),$([System.DateTime]::new(2023,7,2))).get_TotalDays())</ProjectStartedDate>
<DaysSinceProjectStarted>$([System.DateTime]::Now.ToString(Hmm))</DaysSinceProjectStarted>
<DateTimeSuffix>$([System.DateTime]::Now.ToString(yyyyMMdd))</DateTimeSuffix>
<VersionSuffix>$(Major).$(Minor).$(ProjectStartedDate).$(DaysSinceProjectStarted)</VersionSuffix>
<AssemblyVersion Condition=" '$(DateTimeSuffix)' == '' ">0.0.0.1</AssemblyVersion>
<AssemblyVersion Condition=" '$(DateTimeSuffix)' != '' ">$(VersionSuffix)</AssemblyVersion>
<Version Condition=" '$(DateTimeSuffix)' == '' ">0.0.0.1</Version>
<Version Condition=" '$(DateTimeSuffix)' != '' ">$(DateTimeSuffix)</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -20,6 +35,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Hardcodet.Wpf.TaskbarNotification.Net6" Version="1.0.0" /> <PackageReference Include="Hardcodet.Wpf.TaskbarNotification.Net6" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -6,15 +6,16 @@
xmlns:tb="clr-namespace:Hardcodet.Wpf.TaskbarNotification;assembly=Hardcodet.Wpf.TaskbarNotification.Net6" xmlns:tb="clr-namespace:Hardcodet.Wpf.TaskbarNotification;assembly=Hardcodet.Wpf.TaskbarNotification.Net6"
xmlns:local="clr-namespace:DellMonitorControl" xmlns:local="clr-namespace:DellMonitorControl"
mc:Ignorable="d" mc:Ignorable="d"
Loaded="Window_Loaded"
Title="MainWindow" Height="450" Width="800"> Title="MainWindow" Height="450" Width="800">
<Grid> <Grid>
<tb:TaskbarIcon x:Name="taskbar" <tb:TaskbarIcon x:Name="taskbar"
IconSource="/DellLogo.ico" IconSource="/DellLogo.ico"
ToolTipText="調整效能" ToolTipText="螢幕開關"
PopupActivation="LeftOrDoubleClick"> PopupActivation="LeftOrDoubleClick">
<tb:TaskbarIcon.TrayPopup> <tb:TaskbarIcon.TrayPopup>
<local:ControlPanel/> <local:ControlPanel x:Name="comtrolPanel"/>
</tb:TaskbarIcon.TrayPopup> </tb:TaskbarIcon.TrayPopup>
</tb:TaskbarIcon> </tb:TaskbarIcon>
</Grid> </Grid>

View File

@@ -10,6 +10,11 @@ public partial class MainWindow : Window
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
this.Hide(); this.Hide();
await comtrolPanel.Init();
} }
} }

View File

@@ -15,7 +15,6 @@
</Style.Triggers> </Style.Triggers>
</Style> </Style>
<Style x:Key="TextBorderStyle" TargetType="{x:Type Border}"> <Style x:Key="TextBorderStyle" TargetType="{x:Type Border}">
<Setter Property="Background" Value="{StaticResource F3}"/> <Setter Property="Background" Value="{StaticResource F3}"/>
<Setter Property="BorderBrush" Value="#C1272C"/> <Setter Property="BorderBrush" Value="#C1272C"/>

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<RootNamespace>CMM.Language</RootNamespace> <RootNamespace>CMM.Language</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>

View File

@@ -1,70 +1,67 @@
using System; using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized; using System.Collections.Specialized;
namespace CMM.Library.Base namespace CMM.Library.Base;
/// <summary>
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed.
/// </summary>
/// <typeparam name="T"></typeparam>
public class ObservableRangeCollection<T> : ObservableCollection<T>
{ {
/// <summary> /// <summary>
/// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed. /// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> public void AddRange(IEnumerable<T> collection)
public class ObservableRangeCollection<T> : ObservableCollection<T>
{ {
/// <summary> if (collection == null) throw new ArgumentNullException("collection");
/// Adds the elements of the specified collection to the end of the ObservableCollection(Of T).
/// </summary>
public void AddRange(IEnumerable<T> collection)
{
if (collection == null) throw new ArgumentNullException("collection");
foreach (var i in collection) Items.Add(i); foreach (var i in collection) Items.Add(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T).
/// </summary>
public void RemoveRange(IEnumerable<T> collection)
{
if (collection == null) throw new ArgumentNullException("collection");
foreach (var i in collection) Items.Remove(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Clears the current collection and replaces it with the specified item.
/// </summary>
public void Replace(T item)
{
ReplaceRange(new T[] { item });
}
/// <summary>
/// Clears the current collection and replaces it with the specified collection.
/// </summary>
public void ReplaceRange(IEnumerable<T> collection)
{
if (collection == null) throw new ArgumentNullException("collection");
Items.Clear();
foreach (var i in collection) Items.Add(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
/// </summary>
public ObservableRangeCollection()
: base() { }
/// <summary>
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection.
/// </summary>
/// <param name="collection">collection: The collection from which the elements are copied.</param>
/// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception>
public ObservableRangeCollection(IEnumerable<T> collection)
: base(collection) { }
} }
/// <summary>
/// Removes the first occurence of each item in the specified collection from ObservableCollection(Of T).
/// </summary>
public void RemoveRange(IEnumerable<T> collection)
{
if (collection == null) throw new ArgumentNullException("collection");
foreach (var i in collection) Items.Remove(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Clears the current collection and replaces it with the specified item.
/// </summary>
public void Replace(T item)
{
ReplaceRange(new T[] { item });
}
/// <summary>
/// Clears the current collection and replaces it with the specified collection.
/// </summary>
public void ReplaceRange(IEnumerable<T> collection)
{
if (collection == null) throw new ArgumentNullException("collection");
Items.Clear();
foreach (var i in collection) Items.Add(i);
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
}
/// <summary>
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class.
/// </summary>
public ObservableRangeCollection()
: base() { }
/// <summary>
/// Initializes a new instance of the System.Collections.ObjectModel.ObservableCollection(Of T) class that contains elements copied from the specified collection.
/// </summary>
/// <param name="collection">collection: The collection from which the elements are copied.</param>
/// <exception cref="System.ArgumentNullException">The collection parameter cannot be null.</exception>
public ObservableRangeCollection(IEnumerable<T> collection)
: base(collection) { }
} }

View File

@@ -1,31 +1,30 @@
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace CMM.Library.Base namespace CMM.Library.Base;
public class PropertyBase : INotifyPropertyChanged
{ {
public class PropertyBase : INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged;
virtual internal protected void OnPropertyChanged(string propertyName)
{ {
public event PropertyChangedEventHandler PropertyChanged; if (this.PropertyChanged != null)
virtual internal protected void OnPropertyChanged(string propertyName)
{ {
if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return;
storage = value;
this.OnPropertyChanged(propertyName);
} }
} }
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (object.Equals(storage, value)) return;
storage = value;
this.OnPropertyChanged(propertyName);
}
} }

View File

@@ -2,75 +2,69 @@
using CMM.Library.Base; using CMM.Library.Base;
using CMM.Library.Helpers; using CMM.Library.Helpers;
using CMM.Library.Method; using CMM.Library.Method;
using System;
using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
namespace CMM.Library.Config namespace CMM.Library.Config;
public class XConfig : PropertyBase
{ {
public class XConfig : PropertyBase [JsonIgnore]
public string Version { get; private set; }
public static string ConfigFileName => Path.Combine(AssemblyData.Path, "Config.cfg");
#region Language
[JsonIgnore]
public CultureInfo Culture
{ {
[JsonIgnore] get => _Culture;
public string Version { get; private set; } set
public static string ConfigFileName => Path.Combine(AssemblyData.Path, "Config.cfg");
#region Language
[JsonIgnore]
public CultureInfo Culture
{ {
get => _Culture; SetProperty(ref _Culture, value);
set LoadCultures();
{
SetProperty(ref _Culture, value);
LoadCultures();
}
} }
CultureInfo _Culture; }
public string Language { get; set; } = null; CultureInfo _Culture;
CulturesHelper CulturesHelper { get; init; } = new(); public string Language { get; set; } = null;
public void LoadCultures() CulturesHelper CulturesHelper { get; init; } = new();
{ public void LoadCultures()
if (CulturesHelper == null) return; {
if (CulturesHelper == null) return;
CulturesHelper.ChangeCulture(Culture); CulturesHelper.ChangeCulture(Culture);
} }
#endregion #endregion
public virtual void Load() public virtual void Load()
{ {
XConfig _base = null; XConfig _base = null;
if (new FileInfo(ConfigFileName).Exists) if (new FileInfo(ConfigFileName).Exists)
{
try
{
_base = ConfigFileName.JsonFormFile<XConfig>();
}
catch (Exception ex)
{
MessageBox.Show($"{Lang.Find("LoadConfigErr")}{ex.Message}", "failed", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
this.Culture = _base?.Culture ?? new CultureInfo(_base?.Language ?? "en-US", false);
this.Version = $"{AssemblyData.AppName} {AssemblyData.AppVersion}";
}
public virtual void Save()
{ {
try try
{ {
this.FileToJson(ConfigFileName); _base = ConfigFileName.JsonFormFile<XConfig>();
} }
catch (Exception ex) catch (Exception ex)
{ {
MessageBox.Show($"{Lang.Find("SaveConfigErr")}{ex.Message}", "failed", MessageBoxButton.OK, MessageBoxImage.Error); MessageBox.Show($"{Lang.Find("LoadConfigErr")}{ex.Message}", "failed", MessageBoxButton.OK, MessageBoxImage.Error);
} }
} }
this.Culture = _base?.Culture ?? new CultureInfo(_base?.Language ?? "en-US", false);
this.Version = $"{AssemblyData.AppName} {AssemblyData.AppVersion}";
}
public virtual void Save()
{
try
{
this.FileToJson(ConfigFileName);
}
catch (Exception ex)
{
MessageBox.Show($"{Lang.Find("SaveConfigErr")}{ex.Message}", "failed", MessageBoxButton.OK, MessageBoxImage.Error);
}
} }
} }

View File

@@ -1,71 +1,79 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMM.Library.Helpers namespace CMM.Library.Helpers;
internal class ConsoleHelper
{ {
internal class ConsoleHelper const string cmdFileName = "cmd.exe";
private static Process CreatProcess(string fileName) =>
new Process()
{
StartInfo = new ProcessStartInfo
{
FileName = fileName,
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
}
};
public static async Task<string> ExecuteCommand(string command)
{ {
const string cmdFileName = "cmd.exe"; Process p = new Process();
private static Process CreatProcess(string fileName) => p.StartInfo.UseShellExecute = false;
new Process() p.StartInfo.CreateNoWindow = true;
{ p.StartInfo.RedirectStandardOutput = true;
StartInfo = new ProcessStartInfo p.StartInfo.FileName = command;
{ p.Start();
FileName = fileName, var output = await p.StandardOutput.ReadToEndAsync();
UseShellExecute = false, await p.WaitForExitAsync();
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
}
};
public static async Task<string> CmdCommandAsync(params string[] cmds) => return output;
await CommandAsync(cmdFileName, cmds); }
public static string CmdCommand(params string[] cmds) => public static async Task<string> CmdCommandAsync(params string[] cmds) =>
Command(cmdFileName, cmds); await CommandAsync(cmdFileName, cmds);
public static async Task<string> CommandAsync(string fileName, params string[] cmds) public static string CmdCommand(params string[] cmds) =>
Command(cmdFileName, cmds);
public static async Task<string> CommandAsync(string fileName, params string[] cmds)
{
var p = CreatProcess(fileName);
p.Start();
foreach (var cmd in cmds)
{ {
var p = CreatProcess(fileName); p.StandardInput.WriteLine(cmd);
p.Start();
foreach (var cmd in cmds)
{
p.StandardInput.WriteLine(cmd);
}
p.StandardInput.WriteLine("exit");
var result = await p.StandardOutput.ReadToEndAsync();
var error = await p.StandardError.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(error))
result = result + "\r\n<Error Message>:\r\n" + error;
await p.WaitForExitAsync();
p.Close();
Debug.WriteLine(result);
return result;
} }
p.StandardInput.WriteLine("exit");
var result = await p.StandardOutput.ReadToEndAsync();
var error = await p.StandardError.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(error))
result = result + "\r\n<Error Message>:\r\n" + error;
await p.WaitForExitAsync();
p.Close();
Debug.WriteLine(result);
return result;
}
public static string Command(string fileName, params string[] cmds) public static string Command(string fileName, params string[] cmds)
{
var p = CreatProcess(fileName);
p.Start();
foreach (var cmd in cmds)
{ {
var p = CreatProcess(fileName); p.StandardInput.WriteLine(cmd);
p.Start();
foreach (var cmd in cmds)
{
p.StandardInput.WriteLine(cmd);
}
p.StandardInput.WriteLine("exit");
var result = p.StandardOutput.ReadToEnd();
var error = p.StandardError.ReadToEnd();
if (!string.IsNullOrWhiteSpace(error))
result = result + "\r\n<Error Message>:\r\n" + error;
p.WaitForExit();
p.Close();
Debug.WriteLine(result);
return result;
} }
p.StandardInput.WriteLine("exit");
var result = p.StandardOutput.ReadToEnd();
var error = p.StandardError.ReadToEnd();
if (!string.IsNullOrWhiteSpace(error))
result = result + "\r\n<Error Message>:\r\n" + error;
p.WaitForExit();
p.Close();
Debug.WriteLine(result);
return result;
} }
} }

View File

@@ -1,131 +1,126 @@
using System; using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Text.Encodings.Web; using System.Text.Encodings.Web;
using System.Text.Json; using System.Text.Json;
using System.Threading.Tasks;
namespace CMM.Library.Helpers namespace CMM.Library.Helpers;
static class JsonSerializerExtensions
{ {
static class JsonSerializerExtensions public static JsonSerializerOptions defaultSettings = new JsonSerializerOptions()
{ {
public static JsonSerializerOptions defaultSettings = new JsonSerializerOptions() WriteIndented = true,
IgnoreNullValues = true,
PropertyNamingPolicy = null,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
}
public static class JsonHelper
{
/// <summary>
/// 複製整個obj全部結構
/// </summary>
public static T DeepCopy<T>(T RealObject) =>
JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(RealObject, JsonSerializerExtensions.defaultSettings));
public static string JsonFormResource(this string fileName)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName =
assembly.GetManifestResourceNames().
Where(str => str.Contains(fileName)).FirstOrDefault();
if (resourceName == null) return "";
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var reader = new StreamReader(stream, Encoding.UTF8))
{ {
WriteIndented = true, return reader.ReadToEnd();
IgnoreNullValues = true, }
PropertyNamingPolicy = null,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
};
} }
internal static class JsonHelper public static T JsonFormResource<T>(this string fileName) =>
JsonFormString<T>(JsonFormResource(fileName));
public static T JsonFormFile<T>(this string fileName) =>
JsonFormString<T>(Load(fileName));
public static T JsonFormString<T>(this string json) =>
JsonSerializer.Deserialize<T>(json);
public static void FileToJson<T>(this T payload, string savePath) =>
Save(savePath, payload.ToJson());
public static string ToJson<T>(this T payload) =>
JsonSerializer.Serialize(payload, JsonSerializerExtensions.defaultSettings);
/// <summary>
/// 從Embedded resource讀string
/// </summary>
/// <param name="aFileName">resource位置不含副檔名</param>
public static string GetResource(this Assembly assembly, string aFileName)
{ {
/// <summary> var resourceName = assembly
/// 複製整個obj全部結構 .GetManifestResourceNames()
/// </summary> .Where(str => str.Contains(aFileName))
public static T DeepCopy<T>(T RealObject) => .FirstOrDefault();
JsonSerializer.Deserialize<T>(JsonSerializer.Serialize(RealObject, JsonSerializerExtensions.defaultSettings)); if (resourceName == null) return "";
public static string JsonFormResource(this string fileName) using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var sr = new StreamReader(stream, Encoding.UTF8))
{ {
var assembly = Assembly.GetExecutingAssembly(); return sr.ReadToEnd();
var resourceName =
assembly.GetManifestResourceNames().
Where(str => str.Contains(fileName)).FirstOrDefault();
if (resourceName == null) return "";
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
return reader.ReadToEnd();
}
} }
}
public static T JsonFormResource<T>(this string fileName) => public static string Load(string aFileName) =>
JsonFormString<T>(JsonFormResource(fileName)); Load(new FileInfo(aFileName));
public static T JsonFormFile<T>(this string fileName) => public static string Load(FileInfo aFi)
JsonFormString<T>(Load(fileName)); {
if (aFi.Exists)
public static T JsonFormString<T>(this string json) =>
JsonSerializer.Deserialize<T>(json);
public static void FileToJson<T>(this T payload, string savePath) =>
Save(savePath, payload.ToJson());
public static string ToJson<T>(this T payload) =>
JsonSerializer.Serialize(payload, JsonSerializerExtensions.defaultSettings);
/// <summary>
/// 從Embedded resource讀string
/// </summary>
/// <param name="aFileName">resource位置不含副檔名</param>
public static string GetResource(this Assembly assembly, string aFileName)
{ {
var resourceName = assembly string _Json = string.Empty;
.GetManifestResourceNames()
.Where(str => str.Contains(aFileName))
.FirstOrDefault();
if (resourceName == null) return "";
using (var stream = assembly.GetManifestResourceStream(resourceName))
using (var sr = new StreamReader(stream, Encoding.UTF8))
{
return sr.ReadToEnd();
}
}
public static string Load(string aFileName) =>
Load(new FileInfo(aFileName));
public static string Load(FileInfo aFi)
{
if (aFi.Exists)
{
string _Json = string.Empty;
try
{
var sr = new StreamReader(aFi.FullName);
_Json = sr.ReadToEnd();
sr.Close();
}
catch (IOException) { throw; }
catch (Exception) { throw; }
return _Json;
}
throw new Exception("開檔失敗。");
}
public static void Save(string filePath, string content) =>
Save(new FileInfo(filePath), content);
public static void Save(FileInfo aFi, string aContent)
{
if (!aFi.Directory.Exists)
{
aFi.Directory.Create();
}
if (aFi.Exists)
{
aFi.Delete();
}
aFi.Refresh();
if (aFi.Exists) throw new Exception("寫檔失敗,檔案已存在或已開啟。");
try try
{ {
File.WriteAllText(aFi.FullName, aContent); var sr = new StreamReader(aFi.FullName);
_Json = sr.ReadToEnd();
sr.Close();
} }
catch (IOException) { throw; } catch (IOException) { throw; }
catch (Exception) { throw; } catch (Exception) { throw; }
return _Json;
} }
throw new Exception("開檔失敗。");
}
public static void Save(string filePath, string content) =>
Save(new FileInfo(filePath), content);
public static void Save(FileInfo aFi, string aContent)
{
if (!aFi.Directory.Exists)
{
aFi.Directory.Create();
}
if (aFi.Exists)
{
aFi.Delete();
}
aFi.Refresh();
if (aFi.Exists) throw new Exception("寫檔失敗,檔案已存在或已開啟。");
try
{
File.WriteAllText(aFi.FullName, aContent);
}
catch (IOException) { throw; }
catch (Exception) { throw; }
} }
} }

View File

@@ -1,18 +1,16 @@
using System; using System.Security.Principal;
using System.Security.Principal;
namespace CMM.Library.Helpers namespace CMM.Library.Helpers;
public class UAC
{ {
public class UAC public static void Check()
{ {
public static void Check() var identity = WindowsIdentity.GetCurrent();
{ var principal = new WindowsPrincipal(identity);
var identity = WindowsIdentity.GetCurrent(); if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
var principal = new WindowsPrincipal(identity); throw new Exception($"Cannot delete task with your current identity '{identity.Name}' permissions level." +
if (!principal.IsInRole(WindowsBuiltInRole.Administrator)) "You likely need to run this application 'as administrator' even if you are using an administrator account.");
throw new Exception($"Cannot delete task with your current identity '{identity.Name}' permissions level." +
"You likely need to run this application 'as administrator' even if you are using an administrator account.");
}
} }
} }

View File

@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>CMM.Library</RootNamespace> <RootNamespace>CMM.Library</RootNamespace>
<AssemblyName>CMM.Library</AssemblyName>
<Product>ControlMyMonitorManagement</Product> <Product>ControlMyMonitorManagement</Product>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<Company>Dang</Company> <Company>Dang</Company>
@@ -34,7 +35,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\CMMModel\CMMModel.csproj" />
<ProjectReference Include="..\Language\Language.csproj" /> <ProjectReference Include="..\Language\Language.csproj" />
<ProjectReference Include="..\Tester\Tester.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,48 +1,42 @@
using System; using System.Diagnostics;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMM.Library.Method namespace CMM.Library.Method;
public static class AssemblyData
{ {
public static class AssemblyData /// <summary>
/// 當下Assembly名稱
/// </summary>
public static string AssemblyName => System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
public static string AppName => AppDomain.CurrentDomain.FriendlyName;
/// <summary>
/// 程式根目錄,無視工作目錄
/// </summary>
public static string Path => AppDomain.CurrentDomain.BaseDirectory;
/// <summary>
/// 版本
/// </summary>
public static string AssemblyVersion => GetAssemblyVersion();
public static string AppVersion => GetFileVersion(Process.GetCurrentProcess().MainModule.FileName);
/// <summary>
/// CCM 輸出
/// </summary>
public static string smonitors => System.IO.Path.Combine(Path, "smonitors.tmp");
static string GetAssemblyVersion()
{ {
/// <summary> var fi = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase.Replace(@"file:///", "");
/// 當下Assembly名稱 return GetFileVersion(fi);
/// </summary> }
public static string AssemblyName => System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
public static string AppName => AppDomain.CurrentDomain.FriendlyName; public static string GetFileVersion(string filePath)
{
/// <summary> var fvi = FileVersionInfo.GetVersionInfo(filePath);
/// 程式根目錄,無視工作目錄 return $"{fvi.FileMajorPart}." +
/// </summary> $"{fvi.FileMinorPart}." +
public static string Path => AppDomain.CurrentDomain.BaseDirectory; $"{fvi.FileBuildPart}." +
/// <summary> $"{fvi.FilePrivatePart}";
/// 版本
/// </summary>
public static string AssemblyVersion => GetAssemblyVersion();
public static string AppVersion => GetFileVersion(Process.GetCurrentProcess().MainModule.FileName);
/// <summary>
/// CCM 輸出
/// </summary>
public static string smonitors => System.IO.Path.Combine(Path, "smonitors.tmp");
static string GetAssemblyVersion()
{
var fi = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase.Replace(@"file:///", "");
return GetFileVersion(fi);
}
public static string GetFileVersion(string filePath)
{
var fvi = FileVersionInfo.GetVersionInfo(filePath);
return $"{fvi.FileMajorPart}." +
$"{fvi.FileMinorPart}." +
$"{fvi.FileBuildPart}." +
$"{fvi.FilePrivatePart}";
}
} }
} }

View File

@@ -2,6 +2,8 @@
using CMM.Library.Helpers; using CMM.Library.Helpers;
using CMM.Library.ViewModel; using CMM.Library.ViewModel;
using System.IO; using System.IO;
using System.Net.NetworkInformation;
using System.Threading;
namespace CMM.Library.Method; namespace CMM.Library.Method;
@@ -13,7 +15,6 @@ public static class CMMCommand
static readonly string CMMTmpFolder = Path.Combine(Path.GetTempPath(), $"CMM"); static readonly string CMMTmpFolder = Path.Combine(Path.GetTempPath(), $"CMM");
static readonly string CMMexe = Path.Combine(CMMTmpFolder, "ControlMyMonitor.exe"); static readonly string CMMexe = Path.Combine(CMMTmpFolder, "ControlMyMonitor.exe");
static readonly string CMMsMonitors = Path.Combine(CMMTmpFolder, "smonitors.tmp"); static readonly string CMMsMonitors = Path.Combine(CMMTmpFolder, "smonitors.tmp");
static readonly string CMMcfg = Path.Combine(CMMTmpFolder, "ControlMyMonitor.cfg");
public static async Task ScanMonitor() public static async Task ScanMonitor()
{ {
@@ -21,80 +22,92 @@ public static class CMMCommand
await ConsoleHelper.CmdCommandAsync($"{CMMexe} /smonitors {CMMsMonitors}"); await ConsoleHelper.CmdCommandAsync($"{CMMexe} /smonitors {CMMsMonitors}");
} }
public static async Task PowerOn(string MonitorSn) public static Task PowerOn(string monitorSN)
{ {
await ConsoleHelper.CmdCommandAsync($"{CMMexe} /SetValue {MonitorSn} D6 1"); return ConsoleHelper.CmdCommandAsync($"{CMMexe} /SetValue {monitorSN} D6 1");
} }
public static async Task Sleep(string MonitorSn) public static Task Sleep(string monitorSN)
{ {
await ConsoleHelper.CmdCommandAsync($"{CMMexe} /SetValue {MonitorSn} D6 4"); return ConsoleHelper.CmdCommandAsync($"{CMMexe} /SetValue {monitorSN} D6 4");
} }
public static async Task ScanMonitorInterfaces(IEnumerable<XMonitor> monitors) private static async Task<string> GetMonitorValue(string monitorSN)
{ {
var taskList = new List<Task>(); var cmdFileName = Path.Combine(CMMTmpFolder, $"{Guid.NewGuid()}.bat");
foreach (var mon in monitors) var cmd = $"{CMMexe} /GetValue {monitorSN} D6\r\n" +
$"echo %errorlevel%";
File.WriteAllText(cmdFileName, cmd);
var values = await ConsoleHelper.ExecuteCommand(cmdFileName);
File.Delete(cmdFileName);
return values.Split("\r\n", StringSplitOptions.RemoveEmptyEntries).LastOrDefault();
}
public static async Task<string> GetMonPowerStatus(string monitorSN)
{
var status = await GetMonitorValue(monitorSN);
return status switch
{ {
taskList.Add(Task.Run(async () => await "1" => "PowerOn",
ScanMonitorInterfaces($"{CMMTmpFolder}\\{mon.SerialNumber}.tmp", mon))); "4" => "Sleep",
} "5" => "PowerOff",
_ => string.Empty
await Task.WhenAll(taskList.ToArray()); };
} }
static async Task ScanMonitorInterfaces(string savePath, XMonitor mon) public static async Task ScanMonitorStatus(IEnumerable<XMonitor> monitors)
{ {
await ConsoleHelper.CmdCommandAsync($"{CMMexe} /scomma {savePath} {mon.MonitorID}"); var taskList = monitors.Select(x =>
await mon.ReadMonitorStatus(savePath); {
return ScanMonitorStatus($"{CMMTmpFolder}\\{x.SerialNumber}.tmp", x);
});
await Task.WhenAll(taskList);
}
static async Task ScanMonitorStatus(string savePath, XMonitor mon)
{
await ConsoleHelper.CmdCommandAsync($"{CMMexe} /sjson {savePath} {mon.MonitorID}");
var monitorModel = JsonHelper.JsonFormFile<IEnumerable<SMonitorModel>>(savePath);
var status = monitorModel.ReadMonitorStatus();
mon.Status = new ObservableRangeCollection<XMonitorStatus>(status);
} }
/// <summary> /// <summary>
/// 取得螢幕狀態 /// 取得螢幕狀態
/// </summary> /// </summary>
public static async Task ReadMonitorStatus(this XMonitor @this, string filePath) public static IEnumerable<XMonitorStatus> ReadMonitorStatus(this IEnumerable<SMonitorModel> monitorModel)
{ {
var statusColle = new ObservableRangeCollection<XMonitorStatus>(); foreach (var m in monitorModel)
{
if (!File.Exists(filePath)) return; yield return new XMonitorStatus
foreach (var line in await File.ReadAllLinesAsync(filePath))
{
var sp = line.Split(",");
if (sp.Length < 6) continue;
statusColle.Add(new XMonitorStatus
{ {
VCP_Code = StrTrim(sp[0]), VCP_Code = m.VCPCode,
VCPCodeName = StrTrim(sp[1]), VCPCodeName = m.VCPCodeName,
Read_Write = StrTrim(sp[2]), Read_Write = m.ReadWrite,
CurrentValue = TryGetInt(sp[3]), CurrentValue = TryGetInt(m.CurrentValue),
MaximumValue = TryGetInt(sp[4]), MaximumValue = TryGetInt(m.MaximumValue),
PossibleValues = TryGetArrStr(sp), PossibleValues = TryGetArrStr(m.PossibleValues),
}); };
} }
@this.Status = statusColle; IEnumerable<int> TryGetArrStr(string str)
string StrTrim(string str)
{ {
if (string.IsNullOrEmpty(str)) return null; return str.Split(",", StringSplitOptions.RemoveEmptyEntries)
return str; .Select(x => TryGetInt(x))
} .Where(x => x != null)
.Select(x => (int)x)
string TryGetArrStr(string[] strArr) .ToList();
{
if (strArr.Length < 7) return null;
var outStr = string.Join(",", strArr[5..]);
outStr = outStr.Substring(1, outStr.Length - 2);
return outStr;
} }
int? TryGetInt(string str) int? TryGetInt(string str)
{ {
if (int.TryParse(str, out var value)) return value; return int.TryParse(str, out var value)
return null; ? value
: null;
} }
} }

View File

@@ -1,29 +1,23 @@
using CMM.Library.Base; using CMM.Library.Base;
using CMM.Library.ViewModel; using CMM.Library.ViewModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMM.Library.Method namespace CMM.Library.Method;
public class CMMMgr : PropertyBase
{ {
public class CMMMgr : PropertyBase public ObservableRangeCollection<XMonitor> Monitors
{ {
public ObservableRangeCollection<XMonitor> Monitors get => _Monitors;
{ set { SetProperty(ref _Monitors, value); }
get => _Monitors; }
set { SetProperty(ref _Monitors, value); } ObservableRangeCollection<XMonitor> _Monitors = new ();
}
ObservableRangeCollection<XMonitor> _Monitors = new ();
public async Task Init() public async Task Init()
{ {
await CMMCommand.ScanMonitor(); await CMMCommand.ScanMonitor();
var monColle = new ObservableRangeCollection<XMonitor>(); var monColle = new ObservableRangeCollection<XMonitor>();
monColle.AddRange(await CMMCommand.ReadMonitorsData()); monColle.AddRange(await CMMCommand.ReadMonitorsData());
Monitors = monColle; Monitors = monColle;
await CMMCommand.ScanMonitorInterfaces(monColle); await CMMCommand.ScanMonitorStatus(monColle);
}
} }
} }

View File

@@ -1,72 +1,66 @@
using CMM.Library.Base; using CMM.Library.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMM.Library.ViewModel namespace CMM.Library.ViewModel;
public class XMonitor : PropertyBase
{ {
public class XMonitor : PropertyBase /// <summary>
/// 裝置路徑
/// </summary>
public string MonitorDeviceName
{ {
/// <summary> get => _MonitorDeviceName;
/// 裝置路徑 set { SetProperty(ref _MonitorDeviceName, value); }
/// </summary>
public string MonitorDeviceName
{
get => _MonitorDeviceName;
set { SetProperty(ref _MonitorDeviceName, value); }
}
string _MonitorDeviceName;
/// <summary>
/// 裝置名稱
/// </summary>
public string MonitorName
{
get => _MonitorName;
set { SetProperty(ref _MonitorName, value); }
}
string _MonitorName;
/// <summary>
/// 裝置序號
/// </summary>
public string SerialNumber
{
get => _SerialNumber;
set { SetProperty(ref _SerialNumber, value); }
}
string _SerialNumber;
/// <summary>
/// 訊號裝置
/// </summary>
public string AdapterName
{
get => _AdapterName;
set { SetProperty(ref _AdapterName, value); }
}
string _AdapterName;
/// <summary>
/// 裝置識別碼
/// </summary>
public string MonitorID
{
get => _MonitorID;
set { SetProperty(ref _MonitorID, value); }
}
string _MonitorID;
/// <summary>
/// 狀態
/// </summary>
public ObservableRangeCollection<XMonitorStatus> Status
{
get => _Status;
set { SetProperty(ref _Status, value); }
}
ObservableRangeCollection<XMonitorStatus> _Status = new();
} }
string _MonitorDeviceName;
/// <summary>
/// 裝置名稱
/// </summary>
public string MonitorName
{
get => _MonitorName;
set { SetProperty(ref _MonitorName, value); }
}
string _MonitorName;
/// <summary>
/// 裝置序號
/// </summary>
public string SerialNumber
{
get => _SerialNumber;
set { SetProperty(ref _SerialNumber, value); }
}
string _SerialNumber;
/// <summary>
/// 訊號裝置
/// </summary>
public string AdapterName
{
get => _AdapterName;
set { SetProperty(ref _AdapterName, value); }
}
string _AdapterName;
/// <summary>
/// 裝置識別碼
/// </summary>
public string MonitorID
{
get => _MonitorID;
set { SetProperty(ref _MonitorID, value); }
}
string _MonitorID;
/// <summary>
/// 狀態
/// </summary>
public ObservableRangeCollection<XMonitorStatus> Status
{
get => _Status;
set { SetProperty(ref _Status, value); }
}
ObservableRangeCollection<XMonitorStatus> _Status = new();
} }

View File

@@ -1,9 +1,4 @@
using CMM.Library.Base; using CMM.Library.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CMM.Library.ViewModel namespace CMM.Library.ViewModel
{ {
@@ -44,11 +39,11 @@ namespace CMM.Library.ViewModel
} }
int? _MaximumValue; int? _MaximumValue;
public string PossibleValues public IEnumerable<int> PossibleValues
{ {
get => _PossibleValues; get => _PossibleValues;
set { SetProperty(ref _PossibleValues, value); } set { SetProperty(ref _PossibleValues, value); }
} }
string _PossibleValues; IEnumerable<int> _PossibleValues;
} }
} }

38
Tester/CommnadTest.cs Normal file
View File

@@ -0,0 +1,38 @@
using CMM.Library.Base;
using CMM.Library.Helpers;
using CMM.Library.Method;
using CMM.Library.ViewModel;
namespace CMM.Tester;
public class CommnadTest
{
[SetUp]
public void Setup()
{
}
[Test]
public async Task Test1()
{
await CMMCommand.ScanMonitor();
var monColle = new ObservableRangeCollection<XMonitor>();
monColle.AddRange(await CMMCommand.ReadMonitorsData());
await CMMCommand.ScanMonitorStatus(monColle);
}
[Test]
public void JsonParserTest()
{
var path = @"C:\Users\shoop\AppData\Local\Temp\CMM\KV97067ICLCL.tmp";
var monitorModel = JsonHelper.JsonFormFile<IEnumerable<SMonitorModel>>(path);
}
[Test]
public async Task GetMonPowerStatus()
{
var status = await CMMCommand.GetMonPowerStatus("CBBP3P3");
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>CMM.Tester</RootNamespace> <RootNamespace>CMM.Tester</RootNamespace>
<Product>ControlMyMonitorManagement</Product> <Product>ControlMyMonitorManagement</Product>
@@ -18,4 +18,12 @@
<PackageReference Include="coverlet.collector" Version="3.1.2" /> <PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\CMMModel\CMMModel.csproj" />
<ProjectReference Include="..\CMMService\CMMService.csproj" />
<ProjectReference Include="..\Language\Language.csproj" />
<ProjectReference Include="..\Library\Library.csproj" />
</ItemGroup>
</Project> </Project>

View File

@@ -1,16 +0,0 @@
namespace CMM.Tester
{
public class Tests
{
[SetUp]
public void Setup()
{
}
[Test]
public void Test1()
{
Assert.Pass();
}
}
}