將寫死改成活讀
This commit is contained in:
27
CMMModel/CMMModel.csproj
Normal file
27
CMMModel/CMMModel.csproj
Normal 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>
|
||||||
17
CMMModel/Model/SMonitorModel.cs
Normal file
17
CMMModel/Model/SMonitorModel.cs
Normal 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; }
|
||||||
|
}
|
||||||
32
CMMService/CMMService.csproj
Normal file
32
CMMService/CMMService.csproj
Normal 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>
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"/>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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) { }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.");
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
38
Tester/CommnadTest.cs
Normal 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");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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>
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
namespace CMM.Tester
|
|
||||||
{
|
|
||||||
public class Tests
|
|
||||||
{
|
|
||||||
[SetUp]
|
|
||||||
public void Setup()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void Test1()
|
|
||||||
{
|
|
||||||
Assert.Pass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user