add power on/off functions, some other options and bug fixes

This commit is contained in:
Vincent Maas committed 2020-08-29 14:39:27 +02:00
1 parent 7b056c9dea
commit 3fa2c3dec4
16 files changed
+920 -198

No files matched your search

+8
View File
@@ -9,6 +9,14 @@
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.4.0" newVersion="4.1.4.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<System.Windows.Forms.ApplicationConfigurationSection>
+37 -2
View File
@@ -26,8 +26,8 @@
<UpdateUrl>https://www.maassoft.com/downloads/ColorControl/</UpdateUrl>
<ProductName>ColorControl</ProductName>
<PublisherName>Maassoft</PublisherName>
<ApplicationRevision>1</ApplicationRevision>
<ApplicationVersion>1.0.3.%2a</ApplicationVersion>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.1.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
@@ -122,11 +122,31 @@
<Reference Include="NWin32, Version=1.0.6.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\NWin32.1.0.6\lib\net46\NWin32.dll</HintPath>
</Reference>
<Reference Include="PacketDotNet, Version=1.0.5.0, Culture=neutral, PublicKeyToken=451414c7667b2a58, processorArchitecture=MSIL">
<HintPath>..\packages\PacketDotNet.1.0.5\lib\net45\PacketDotNet.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="SharpPcap, Version=5.2.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SharpPcap.5.2.0\lib\netstandard2.0\SharpPcap.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Configuration" />
<Reference Include="System.Configuration.Install" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.4.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Runtime.WindowsRuntime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -149,8 +169,12 @@
<Reference Include="Windows">
<HintPath>..\..\..\..\..\..\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd</HintPath>
</Reference>
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="StartUpParams.cs" />
<Compile Include="LgServiceConfig.cs" />
<Compile Include="WOL.cs" />
<Compile Include="RestartDetector.cs" />
<Compile Include="ExceptionExtensions.cs" />
<Compile Include="lgtv\App.cs" />
@@ -234,5 +258,16 @@
<ItemGroup>
<Folder Include="bin\x64\Debug\" />
</ItemGroup>
<ItemGroup>
<COMReference Include="IWshRuntimeLibrary">
<Guid>{F935DC20-1CF0-11D0-ADB9-00C04FD58A0B}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
+8
View File
@@ -6,9 +6,17 @@
public int DisplaySettingsDelay { get; set; }
public string ScreenSaverShortcut { get; set; }
public int FormWidth { get; set; }
public int FormHeight { get; set; }
public Config()
{
DisplaySettingsDelay = 1000;
ScreenSaverShortcut = string.Empty;
FormWidth = 900;
FormHeight = 600;
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ namespace ColorControl
/// </summary>
/// <param name="exception">Exception object.</param>
/// <param name="environmentStackTrace">Environment stack trace, for pulling additional stack frames.</param>
public static string ToLogString(this Exception exception, string environmentStackTrace)
public static string ToLogString(this Exception exception, string environmentStackTrace = "")
{
List<string> environmentStackTraceLines = ExceptionExtensions.GetUserStackTraceLines(environmentStackTrace);
environmentStackTraceLines.RemoveAt(0);
+125 -11
View File
@@ -1,4 +1,6 @@
using LgTv;
using Newtonsoft.Json;
using NLog.Config;
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -17,6 +19,8 @@ namespace ColorControl
public static string LgControllerExe = "LgController.exe";
public static string LgListAppsJson = "listApps.json";
public static string LgDeviceSearchKey = "OLED55C9PLA";
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
public string FriendlyScreenName { get; private set; }
@@ -24,10 +28,19 @@ namespace ColorControl
public List<PnpDev> Devices { get; private set; }
public PnpDev SelectedDevice { get; set; }
private LgTvApi _lgTvApi;
public LgServiceConfig Config { get; private set; }
public LgService()
private LgTvApi _lgTvApi;
private string _dataDir;
private string _configFilename;
private bool _allowPowerOn;
public LgService(string dataDir, bool allowPowerOn)
{
_dataDir = dataDir;
_allowPowerOn = allowPowerOn;
LoadConfig();
foreach (var screen in Screen.AllScreens)
{
var name = screen.DeviceFriendlyName();
@@ -42,17 +55,44 @@ namespace ColorControl
~LgService()
{
SaveConfig();
}
private void LoadConfig()
{
_configFilename = Path.Combine(_dataDir, "LgConfig.json");
if (File.Exists(_configFilename))
{
Config = JsonConvert.DeserializeObject<LgServiceConfig>(File.ReadAllText(_configFilename));
}
else
{
Config = new LgServiceConfig();
}
}
public void SaveConfig()
{
var json = JsonConvert.SerializeObject(Config);
File.WriteAllText(_configFilename, json);
}
public void RefreshDevices(Action callBack = null)
{
Utils.GetPnpDevices("[LG]", Utils.PKEY_PNPX_IpAddress).ContinueWith((task) =>
Utils.GetPnpDevices(LgDeviceSearchKey).ContinueWith((task) =>
{
SetDevicesTask(task);
callBack?.Invoke();
if (callBack == null && SelectedDevice != null)
{
ConnectToSelectedDevice();
if (Config.PowerOnAfterStartup && _allowPowerOn)
{
WakeAndConnectToSelectedDevice(0);
}
else
{
ConnectToSelectedDevice();
}
}
}
);
@@ -67,23 +107,23 @@ namespace ColorControl
}
}
public async Task<bool> ConnectToSelectedDevice(int retries = 1)
public async Task<bool> ConnectToSelectedDevice(int retries = 3)
{
try
{
DisposeConnection();
_lgTvApi = await LgTvApi.CreateLgTvApi(SelectedDevice.ipAddress, retries);
return true;
_lgTvApi = await LgTvApi.CreateLgTvApi(SelectedDevice.IpAddress, retries);
return _lgTvApi != null;
}
catch (Exception ex)
{
string logMessage = ex.ToLogString(Environment.StackTrace);
Logger.Error($"Error while connecting to {SelectedDevice.ipAddress}: {logMessage}");
Logger.Error($"Error while connecting to {SelectedDevice.IpAddress}: {logMessage}");
return false;
}
}
public async Task<bool> ApplyPreset(LgPreset preset, bool reconnect = false)
private async Task<bool> Connected(bool reconnect = false)
{
if (SelectedDevice == null)
{
@@ -91,7 +131,7 @@ namespace ColorControl
return false;
}
if (reconnect || _lgTvApi == null || !string.Equals(_lgTvApi.GetIpAddress(), SelectedDevice.ipAddress))
if (reconnect || _lgTvApi == null || !string.Equals(_lgTvApi.GetIpAddress(), SelectedDevice.IpAddress))
{
if (!await ConnectToSelectedDevice())
{
@@ -99,6 +139,16 @@ namespace ColorControl
return false;
}
}
return true;
}
public async Task<bool> ApplyPreset(LgPreset preset, bool reconnect = false)
{
if (!await Connected(reconnect))
{
return false;
}
var hasApp = !string.IsNullOrEmpty(preset.appId);
@@ -128,6 +178,12 @@ namespace ColorControl
return true;
}
public async Task PowerOn()
{
var mouse = await _lgTvApi.GetMouse();
mouse.SendButton(ButtonType.POWER);
}
private async Task ExecuteSteps(LgTvApi api, LgPreset preset)
{
var mouse = await api.GetMouse();
@@ -164,7 +220,7 @@ namespace ColorControl
return null;
}
var api = await LgTvApi.CreateLgTvApi(SelectedDevice.ipAddress);
var api = await LgTvApi.CreateLgTvApi(SelectedDevice.IpAddress);
var list = await api.GetApps(force);
return list.ToList();
@@ -178,5 +234,63 @@ namespace ColorControl
_lgTvApi = null;
}
}
internal async Task<bool> PowerOff()
{
if (!await Connected(true))
{
return false;
}
await _lgTvApi.TurnOff();
return true;
}
internal void WakeSelectedDevice()
{
if (SelectedDevice != null)
{
WOL.WakeFunction(SelectedDevice.MacAddress);
}
else
{
Logger.Debug("Cannot wake device: no device has been selected");
}
}
internal void WakeAfterResume()
{
if (Config.PowerOnAfterResume)
{
WakeAndConnectToSelectedDevice(Config.PowerOnDelayAfterResume);
}
}
private void WakeAndConnectToSelectedDevice(int wakeDelay = 5000, int connectDelay = 1000)
{
Task.Run(async () =>
{
try
{
//if (wakeDelay == 0)
//{
// if (await ConnectToSelectedDevice())
// {
// Logger.Debug("Already connected, no wake needed?");
// return;
// };
//}
await Task.Delay(wakeDelay);
WakeSelectedDevice();
await Task.Delay(connectDelay);
await ConnectToSelectedDevice();
}
catch (Exception e)
{
Logger.Error("WakeAndConnectToSelectedDevice: " + e.ToLogString());
}
});
}
}
}
+20
View File
@@ -0,0 +1,20 @@
namespace ColorControl
{
class LgServiceConfig
{
public bool PowerOnAfterStartup { get; set; }
public bool PowerOnAfterResume { get; set; }
public bool PowerOffOnShutdown { get; set; }
public bool PowerOffOnStandby { get; set; }
public int PowerOnDelayAfterResume { get; set; }
public LgServiceConfig()
{
PowerOnDelayAfterResume = 5000;
}
}
}
+214 -34
View File
@@ -59,6 +59,7 @@
this.btnApply = new System.Windows.Forms.Button();
this.lvNvPresets = new System.Windows.Forms.ListView();
this.tabLG = new System.Windows.Forms.TabPage();
this.clbLgPower = new System.Windows.Forms.CheckedListBox();
this.btnLgAddButton = new System.Windows.Forms.Button();
this.mnuLgButtons = new System.Windows.Forms.ContextMenuStrip(this.components);
this.label3 = new System.Windows.Forms.Label();
@@ -82,10 +83,21 @@
this.btnApplyLg = new System.Windows.Forms.Button();
this.lvLgPresets = new System.Windows.Forms.ListView();
this.tabOptions = new System.Windows.Forms.TabPage();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.grpMiscellaneousOptions = new System.Windows.Forms.GroupBox();
this.btnSetShortcutScreenSaver = new System.Windows.Forms.Button();
this.label11 = new System.Windows.Forms.Label();
this.edtBlankScreenSaverShortcut = new System.Windows.Forms.TextBox();
this.label10 = new System.Windows.Forms.Label();
this.chkFixChromeFonts = new System.Windows.Forms.CheckBox();
this.grpLGOptions = new System.Windows.Forms.GroupBox();
this.btnLGTestPower = new System.Windows.Forms.Button();
this.label9 = new System.Windows.Forms.Label();
this.edtLgPowerOnAfterResumeDelay = new System.Windows.Forms.NumericUpDown();
this.label8 = new System.Windows.Forms.Label();
this.grpHDROptions = new System.Windows.Forms.GroupBox();
this.edtDelayDisplaySettings = new System.Windows.Forms.NumericUpDown();
this.label6 = new System.Windows.Forms.Label();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.grpGeneralOptions = new System.Windows.Forms.GroupBox();
this.chkStartMinimized = new System.Windows.Forms.CheckBox();
this.chkStartAfterLogin = new System.Windows.Forms.CheckBox();
this.tabLog = new System.Windows.Forms.TabPage();
@@ -103,9 +115,12 @@
this.mnuNvPresets.SuspendLayout();
this.tabLG.SuspendLayout();
this.tabOptions.SuspendLayout();
this.groupBox2.SuspendLayout();
this.grpMiscellaneousOptions.SuspendLayout();
this.grpLGOptions.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.edtLgPowerOnAfterResumeDelay)).BeginInit();
this.grpHDROptions.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.edtDelayDisplaySettings)).BeginInit();
this.groupBox1.SuspendLayout();
this.grpGeneralOptions.SuspendLayout();
this.tabLog.SuspendLayout();
this.tabInfo.SuspendLayout();
this.grpNVIDIAInfo.SuspendLayout();
@@ -400,6 +415,7 @@
//
// tabLG
//
this.tabLG.Controls.Add(this.clbLgPower);
this.tabLG.Controls.Add(this.btnLgAddButton);
this.tabLG.Controls.Add(this.label3);
this.tabLG.Controls.Add(this.cbxLgDevices);
@@ -429,6 +445,27 @@
this.tabLG.Text = "LG controller";
this.tabLG.UseVisualStyleBackColor = true;
//
// clbLgPower
//
this.clbLgPower.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.clbLgPower.CheckOnClick = true;
this.clbLgPower.FormattingEnabled = true;
this.clbLgPower.Items.AddRange(new object[] {
"Automatically power on after startup. Requires \"Automatically start after login\" " +
"- see Options.",
"Automatically power on after resume from standby. Needs a system dependent delay " +
"before waking TV, see Options.",
"Automatically power off on shutdown. Because this app cannot detect a restart, re" +
"starting could also trigger this. Hold down SHIFT on restart to prevent power of" +
"f.",
"Automatically power off on standby"});
this.clbLgPower.Location = new System.Drawing.Point(6, 33);
this.clbLgPower.Name = "clbLgPower";
this.clbLgPower.Size = new System.Drawing.Size(829, 64);
this.clbLgPower.TabIndex = 34;
this.clbLgPower.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.clbLgPower_ItemCheck);
//
// btnLgAddButton
//
this.btnLgAddButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
@@ -525,7 +562,7 @@
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(384, 10);
this.label4.Location = new System.Drawing.Point(466, 9);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(110, 13);
this.label4.TabIndex = 24;
@@ -534,7 +571,7 @@
// edtLgTvName
//
this.edtLgTvName.Enabled = false;
this.edtLgTvName.Location = new System.Drawing.Point(497, 7);
this.edtLgTvName.Location = new System.Drawing.Point(579, 6);
this.edtLgTvName.Name = "edtLgTvName";
this.edtLgTvName.Size = new System.Drawing.Size(142, 20);
this.edtLgTvName.TabIndex = 23;
@@ -654,10 +691,10 @@
| System.Windows.Forms.AnchorStyles.Right)));
this.lvLgPresets.FullRowSelect = true;
this.lvLgPresets.HideSelection = false;
this.lvLgPresets.Location = new System.Drawing.Point(6, 33);
this.lvLgPresets.Location = new System.Drawing.Point(6, 103);
this.lvLgPresets.MultiSelect = false;
this.lvLgPresets.Name = "lvLgPresets";
this.lvLgPresets.Size = new System.Drawing.Size(829, 315);
this.lvLgPresets.Size = new System.Drawing.Size(829, 245);
this.lvLgPresets.TabIndex = 8;
this.lvLgPresets.UseCompatibleStateImageBehavior = false;
this.lvLgPresets.View = System.Windows.Forms.View.Details;
@@ -666,8 +703,10 @@
//
// tabOptions
//
this.tabOptions.Controls.Add(this.groupBox2);
this.tabOptions.Controls.Add(this.groupBox1);
this.tabOptions.Controls.Add(this.grpMiscellaneousOptions);
this.tabOptions.Controls.Add(this.grpLGOptions);
this.tabOptions.Controls.Add(this.grpHDROptions);
this.tabOptions.Controls.Add(this.grpGeneralOptions);
this.tabOptions.Location = new System.Drawing.Point(4, 22);
this.tabOptions.Name = "tabOptions";
this.tabOptions.Padding = new System.Windows.Forms.Padding(3);
@@ -676,16 +715,140 @@
this.tabOptions.Text = "Options";
this.tabOptions.UseVisualStyleBackColor = true;
//
// groupBox2
// grpMiscellaneousOptions
//
this.groupBox2.Controls.Add(this.edtDelayDisplaySettings);
this.groupBox2.Controls.Add(this.label6);
this.groupBox2.Location = new System.Drawing.Point(6, 119);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(376, 107);
this.groupBox2.TabIndex = 3;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "HDR";
this.grpMiscellaneousOptions.Controls.Add(this.btnSetShortcutScreenSaver);
this.grpMiscellaneousOptions.Controls.Add(this.label11);
this.grpMiscellaneousOptions.Controls.Add(this.edtBlankScreenSaverShortcut);
this.grpMiscellaneousOptions.Controls.Add(this.label10);
this.grpMiscellaneousOptions.Controls.Add(this.chkFixChromeFonts);
this.grpMiscellaneousOptions.Location = new System.Drawing.Point(6, 275);
this.grpMiscellaneousOptions.Name = "grpMiscellaneousOptions";
this.grpMiscellaneousOptions.Size = new System.Drawing.Size(400, 130);
this.grpMiscellaneousOptions.TabIndex = 5;
this.grpMiscellaneousOptions.TabStop = false;
this.grpMiscellaneousOptions.Text = "Miscellaneous";
//
// btnSetShortcutScreenSaver
//
this.btnSetShortcutScreenSaver.Location = new System.Drawing.Point(154, 90);
this.btnSetShortcutScreenSaver.Name = "btnSetShortcutScreenSaver";
this.btnSetShortcutScreenSaver.Size = new System.Drawing.Size(34, 23);
this.btnSetShortcutScreenSaver.TabIndex = 10;
this.btnSetShortcutScreenSaver.Text = "Set";
this.btnSetShortcutScreenSaver.UseVisualStyleBackColor = true;
this.btnSetShortcutScreenSaver.Click += new System.EventHandler(this.btnSetShortcutScreenSaver_Click);
//
// label11
//
this.label11.AutoSize = true;
this.label11.Location = new System.Drawing.Point(3, 74);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(219, 13);
this.label11.TabIndex = 9;
this.label11.Text = "Set a shortcut to start the blank screensaver:";
//
// edtBlankScreenSaverShortcut
//
this.edtBlankScreenSaverShortcut.Location = new System.Drawing.Point(6, 92);
this.edtBlankScreenSaverShortcut.Name = "edtBlankScreenSaverShortcut";
this.edtBlankScreenSaverShortcut.ReadOnly = true;
this.edtBlankScreenSaverShortcut.Size = new System.Drawing.Size(142, 20);
this.edtBlankScreenSaverShortcut.TabIndex = 7;
this.edtBlankScreenSaverShortcut.KeyDown += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyDown);
this.edtBlankScreenSaverShortcut.KeyUp += new System.Windows.Forms.KeyEventHandler(this.edtShortcut_KeyUp);
//
// label10
//
this.label10.AutoSize = true;
this.label10.Location = new System.Drawing.Point(3, 39);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(373, 13);
this.label10.TabIndex = 6;
this.label10.Text = "This will add the parameter --disable-lcd-text to Chrome and requires elevation.";
//
// chkFixChromeFonts
//
this.chkFixChromeFonts.AutoSize = true;
this.chkFixChromeFonts.Location = new System.Drawing.Point(6, 19);
this.chkFixChromeFonts.Name = "chkFixChromeFonts";
this.chkFixChromeFonts.Size = new System.Drawing.Size(335, 17);
this.chkFixChromeFonts.TabIndex = 4;
this.chkFixChromeFonts.Text = "ClearType: fix bad fonts in Chrome (turn on grayscale anti-aliasing)";
this.chkFixChromeFonts.UseVisualStyleBackColor = true;
this.chkFixChromeFonts.CheckedChanged += new System.EventHandler(this.chkFixChromeFonts_CheckedChanged);
//
// grpLGOptions
//
this.grpLGOptions.Controls.Add(this.btnLGTestPower);
this.grpLGOptions.Controls.Add(this.label9);
this.grpLGOptions.Controls.Add(this.edtLgPowerOnAfterResumeDelay);
this.grpLGOptions.Controls.Add(this.label8);
this.grpLGOptions.Location = new System.Drawing.Point(6, 162);
this.grpLGOptions.Name = "grpLGOptions";
this.grpLGOptions.Size = new System.Drawing.Size(403, 107);
this.grpLGOptions.TabIndex = 4;
this.grpLGOptions.TabStop = false;
this.grpLGOptions.Text = "LG controller";
//
// btnLGTestPower
//
this.btnLGTestPower.Location = new System.Drawing.Point(9, 68);
this.btnLGTestPower.Name = "btnLGTestPower";
this.btnLGTestPower.Size = new System.Drawing.Size(143, 23);
this.btnLGTestPower.TabIndex = 6;
this.btnLGTestPower.Text = "Test power off/on";
this.btnLGTestPower.UseVisualStyleBackColor = true;
this.btnLGTestPower.Click += new System.EventHandler(this.btnLGTestPower_Click);
//
// label9
//
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(6, 40);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(332, 13);
this.label9.TabIndex = 5;
this.label9.Text = "This delay is necessary to wait for the network link to be established. ";
//
// edtLgPowerOnAfterResumeDelay
//
this.edtLgPowerOnAfterResumeDelay.Increment = new decimal(new int[] {
100,
0,
0,
0});
this.edtLgPowerOnAfterResumeDelay.Location = new System.Drawing.Point(299, 17);
this.edtLgPowerOnAfterResumeDelay.Maximum = new decimal(new int[] {
5000,
0,
0,
0});
this.edtLgPowerOnAfterResumeDelay.Name = "edtLgPowerOnAfterResumeDelay";
this.edtLgPowerOnAfterResumeDelay.ReadOnly = true;
this.edtLgPowerOnAfterResumeDelay.Size = new System.Drawing.Size(74, 20);
this.edtLgPowerOnAfterResumeDelay.TabIndex = 1;
this.edtLgPowerOnAfterResumeDelay.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.edtLgPowerOnAfterResumeDelay.ValueChanged += new System.EventHandler(this.edtLgPowerOnAfterResumeDelay_ValueChanged);
//
// label8
//
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(6, 19);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(214, 13);
this.label8.TabIndex = 0;
this.label8.Text = "Delay before powering on after resume (ms):";
//
// grpHDROptions
//
this.grpHDROptions.Controls.Add(this.edtDelayDisplaySettings);
this.grpHDROptions.Controls.Add(this.label6);
this.grpHDROptions.Location = new System.Drawing.Point(6, 84);
this.grpHDROptions.Name = "grpHDROptions";
this.grpHDROptions.Size = new System.Drawing.Size(400, 72);
this.grpHDROptions.TabIndex = 3;
this.grpHDROptions.TabStop = false;
this.grpHDROptions.Text = "HDR";
//
// edtDelayDisplaySettings
//
@@ -716,16 +879,16 @@
this.label6.TabIndex = 0;
this.label6.Text = "Delay opening display settings (ms):";
//
// groupBox1
// grpGeneralOptions
//
this.groupBox1.Controls.Add(this.chkStartMinimized);
this.groupBox1.Controls.Add(this.chkStartAfterLogin);
this.groupBox1.Location = new System.Drawing.Point(6, 6);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(376, 107);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "General";
this.grpGeneralOptions.Controls.Add(this.chkStartMinimized);
this.grpGeneralOptions.Controls.Add(this.chkStartAfterLogin);
this.grpGeneralOptions.Location = new System.Drawing.Point(6, 6);
this.grpGeneralOptions.Name = "grpGeneralOptions";
this.grpGeneralOptions.Size = new System.Drawing.Size(400, 72);
this.grpGeneralOptions.TabIndex = 2;
this.grpGeneralOptions.TabStop = false;
this.grpGeneralOptions.Text = "General";
//
// chkStartMinimized
//
@@ -881,11 +1044,16 @@
this.tabLG.ResumeLayout(false);
this.tabLG.PerformLayout();
this.tabOptions.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.grpMiscellaneousOptions.ResumeLayout(false);
this.grpMiscellaneousOptions.PerformLayout();
this.grpLGOptions.ResumeLayout(false);
this.grpLGOptions.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.edtLgPowerOnAfterResumeDelay)).EndInit();
this.grpHDROptions.ResumeLayout(false);
this.grpHDROptions.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.edtDelayDisplaySettings)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.grpGeneralOptions.ResumeLayout(false);
this.grpGeneralOptions.PerformLayout();
this.tabLog.ResumeLayout(false);
this.tabLog.PerformLayout();
this.tabInfo.ResumeLayout(false);
@@ -941,10 +1109,10 @@
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.Button btnDeleteLg;
private System.Windows.Forms.Button btnAddLg;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox grpGeneralOptions;
private System.Windows.Forms.CheckBox chkStartMinimized;
private System.Windows.Forms.CheckBox chkStartAfterLogin;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox grpHDROptions;
private System.Windows.Forms.NumericUpDown edtDelayDisplaySettings;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.ToolStripMenuItem mnuNvDisplay;
@@ -966,6 +1134,18 @@
private System.Windows.Forms.ContextMenuStrip mnuLgButtons;
private System.Windows.Forms.ToolStripMenuItem mnuNvPresetsColorSettings;
private System.Windows.Forms.ToolStripMenuItem miNvPresetColorSettings;
private System.Windows.Forms.CheckedListBox clbLgPower;
private System.Windows.Forms.GroupBox grpLGOptions;
private System.Windows.Forms.NumericUpDown edtLgPowerOnAfterResumeDelay;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Button btnLGTestPower;
private System.Windows.Forms.Label label9;
private System.Windows.Forms.GroupBox grpMiscellaneousOptions;
private System.Windows.Forms.CheckBox chkFixChromeFonts;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.Button btnSetShortcutScreenSaver;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.TextBox edtBlankScreenSaverShortcut;
}
}
+205 -63
View File
@@ -45,6 +45,7 @@ namespace ColorControl
private static int WM_HOTKEY = 0x0312;
private static string TS_TASKNAME = "ColorControl";
private static bool SystemShutdown = false;
private static int SHORTCUTID_SCREENSAVER = -100;
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
@@ -74,9 +75,12 @@ namespace ColorControl
private MenuItem _nvTrayMenu;
private MenuItem _lgTrayMenu;
public MainForm()
private StartUpParams StartUpParams { get; }
public MainForm(StartUpParams startUpParams)
{
InitializeComponent();
StartUpParams = startUpParams;
_dataDir = Utils.GetDataPath();
@@ -103,6 +107,12 @@ namespace ColorControl
chkStartAfterLogin.Checked = TaskExists(true);
chkFixChromeFonts.Enabled = Utils.IsChromeInstalled();
if (chkFixChromeFonts.Enabled)
{
chkFixChromeFonts.Checked = Utils.IsChromeFixInstalled();
}
_JsonSerializer = new JavaScriptSerializer();
_JsonDeserializer = new JavaScriptSerializer();
@@ -139,14 +149,18 @@ namespace ColorControl
}
try
{
_lgService = new LgService();
_lgService = new LgService(_dataDir, StartUpParams.RunningFromScheduledTask);
clbLgPower.SetItemChecked(0, _lgService.Config.PowerOnAfterStartup);
clbLgPower.SetItemChecked(1, _lgService.Config.PowerOnAfterResume);
clbLgPower.SetItemChecked(2, _lgService.Config.PowerOffOnShutdown);
clbLgPower.SetItemChecked(3, _lgService.Config.PowerOffOnStandby);
edtLgPowerOnAfterResumeDelay.Value = _lgService.Config.PowerOnDelayAfterResume;
}
catch (Exception e)
{
Debug.WriteLine(e);
}
//_nvService.SetDithering(true);
//_nvService.SetRefreshRate(120);
InitInfo();
@@ -162,11 +176,16 @@ namespace ColorControl
item.Click += miLgAddButton_Click;
}
SystemEvents.SessionEnded += new SessionEndedEventHandler(SessionEnded);
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(PowerModeChanged);
if (_lgService != null)
{
SystemEvents.SessionEnded += new SessionEndedEventHandler(SessionEnded);
SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(PowerModeChanged);
}
_restartDetector = new RestartDetector();
//Scale(new SizeF(1.25F, 1.25F));
_initialized = true;
}
@@ -174,35 +193,32 @@ namespace ColorControl
{
var powerOn = e.Mode == PowerModes.Resume;
Logger.Debug($"PowerModeChanged: {e.Mode}");
if (powerOn)
{
_lgService.DisposeConnection();
_lgService.WakeAfterResume();
return;
}
Logger.Debug($"PowerModeChanged: {e.Mode}");
ExecPowerOffPreset();
if (_lgService.Config.PowerOffOnStandby)
{
_lgService.PowerOff();
}
}
private void SessionEnded(object sender, SessionEndedEventArgs e)
{
if (e.Reason == SessionEndReasons.SystemShutdown)
{
Logger.Debug($"SessionEnded: {e.Reason}");
//if (e.Reason == SessionEndReasons.SystemShutdown)
//{
// Logger.Debug($"SessionEnded: {e.Reason}");
ExecPowerOffPreset();
}
}
private void ExecPowerOffPreset(bool wait = false)
{
var preset = _lgPresets.FirstOrDefault(x => x.steps.Contains("POWER"));
if (preset != null)
{
Logger.Debug($"ExecPowerOffPreset: preset found: {preset.name}");
ApplyLgPreset(preset, wait: wait);
}
// if (_lgService.Config.PowerOffOnShutdown)
// {
// _lgService.PowerOff();
// }
//}
}
private void InitLogger()
@@ -316,23 +332,23 @@ namespace ColorControl
foreach (var preset in _presets)
{
AddOrUpdateItem(preset);
RegisterShortcut(preset);
RegisterShortcut(preset.id, preset.shortcut);
}
//UpdateTrayMenuNv();
}
private void RegisterShortcut(PresetBase preset, bool clear = false)
private void RegisterShortcut(int id, string shortcut, bool clear = false)
{
if (clear)
{
UnregisterHotKey(Handle, preset.id);
UnregisterHotKey(Handle, id);
}
if (!string.IsNullOrEmpty(preset.shortcut))
if (!string.IsNullOrEmpty(shortcut))
{
var (mods, key) = Utils.ParseShortcut(preset.shortcut);
bool registered = RegisterHotKey(Handle, preset.id, mods, key);
var (mods, key) = Utils.ParseShortcut(shortcut);
bool registered = RegisterHotKey(Handle, id, mods, key);
}
}
@@ -380,18 +396,24 @@ namespace ColorControl
SaveLgPresets();
SaveConfig();
if (SystemShutdown)
if (SystemShutdown && _lgService.Config.PowerOffOnShutdown)
{
Logger.Debug($"MainForm_FormClosing: SystemShutdown");
if (_restartDetector != null && _restartDetector.RestartDetected)
if (_restartDetector != null && (_restartDetector.RestartDetected || _restartDetector.IsRebootInProgress()))
{
Logger.Debug("Not powering off because of a restart");
}
else if (NativeMethods.GetAsyncKeyState(NativeConstants.VK_LSHIFT) < 0 || NativeMethods.GetAsyncKeyState(NativeConstants.VK_RSHIFT) < 0)
{
Logger.Debug("Not powering off because SHIFT-key is down");
}
else
{
ExecPowerOffPreset(true);
var task = _lgService.PowerOff();
Utils.WaitForTask(task);
//ExecPowerOffPreset(true);
}
}
}
@@ -443,17 +465,24 @@ namespace ColorControl
// MessageBox.Show(string.Format("Hotkey #{0} pressed", id));
// 6. Handle what will happen once a respective hotkey is pressed
var preset = _presets.FirstOrDefault(x => x.id == id);
if (preset != null)
if (id == SHORTCUTID_SCREENSAVER)
{
ApplyNvPreset(preset);
var screenSaver = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "scrnsave.scr");
Process.Start(screenSaver);
}
var lgPreset = _lgPresets.FirstOrDefault(x => x.id == id);
if (lgPreset != null)
else
{
ApplyLgPreset(lgPreset);
var preset = _presets.FirstOrDefault(x => x.id == id);
if (preset != null)
{
ApplyNvPreset(preset);
}
var lgPreset = _lgPresets.FirstOrDefault(x => x.id == id);
if (lgPreset != null)
{
ApplyLgPreset(lgPreset);
}
}
//switch (id)
@@ -523,7 +552,7 @@ namespace ColorControl
AddOrUpdateItem();
RegisterShortcut(preset, clear);
RegisterShortcut(preset.id, preset.shortcut, clear);
}
private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
@@ -555,24 +584,31 @@ namespace ColorControl
var file = Assembly.GetExecutingAssembly().Location;
var directory = Path.GetDirectoryName(file);
using (TaskService ts = new TaskService())
try
{
if (enabled)
using (TaskService ts = new TaskService())
{
TaskDefinition td = ts.NewTask();
td.RegistrationInfo.Description = "Start ColorControl";
if (enabled)
{
TaskDefinition td = ts.NewTask();
td.RegistrationInfo.Description = "Start ColorControl";
td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name });
td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name });
td.Actions.Add(new ExecAction(file, null, directory));
td.Actions.Add(new ExecAction(file, StartUpParams.RunningFromScheduledTaskParam, directory));
ts.RootFolder.RegisterTaskDefinition(TS_TASKNAME, td);
}
else
{
ts.RootFolder.DeleteTask(TS_TASKNAME, false);
ts.RootFolder.RegisterTaskDefinition(TS_TASKNAME, td);
}
else
{
ts.RootFolder.DeleteTask(TS_TASKNAME, false);
}
}
}
catch (Exception e)
{
ErrorOk("Could not create/delete task: " + e.Message);
}
}
private bool TaskExists(bool update)
@@ -617,14 +653,32 @@ namespace ColorControl
chkStartMinimized.Checked = _config.StartMinimized;
edtDelayDisplaySettings.Value = _config.DisplaySettingsDelay;
edtBlankScreenSaverShortcut.Text = _config.ScreenSaverShortcut;
if (!string.IsNullOrEmpty(_config.ScreenSaverShortcut))
{
RegisterShortcut(SHORTCUTID_SCREENSAVER, _config.ScreenSaverShortcut);
}
Width = _config.FormWidth;
Height = _config.FormHeight;
}
private void SaveConfig()
{
_config.StartMinimized = chkStartMinimized.Checked;
_config.FormWidth = Width;
_config.FormHeight = Height;
var data = _JsonSerializer.Serialize(_config);
File.WriteAllText(_configFilename, data);
try
{
var data = _JsonSerializer.Serialize(_config);
File.WriteAllText(_configFilename, data);
}
catch (Exception e)
{
Logger.Error(e.ToLogString());
}
}
private void MainForm_Load(object sender, EventArgs e)
@@ -1021,7 +1075,7 @@ namespace ColorControl
foreach (var preset in _lgPresets)
{
AddOrUpdateItemLg(preset);
RegisterShortcut(preset);
RegisterShortcut(preset.id, preset.shortcut);
}
}
@@ -1183,7 +1237,7 @@ namespace ColorControl
if (shortcutChanged)
{
RegisterShortcut(preset, clear);
RegisterShortcut(preset.id, preset.shortcut, clear);
}
}
@@ -1474,11 +1528,7 @@ namespace ColorControl
var applyTask = _lgService.ApplyPreset(preset, reconnect).ContinueWith((task) => BeginInvoke(new Action<Task<bool>>(LgPresetApplied), new[] { task }));
if (wait)
{
while (applyTask != null && (applyTask.Status < TaskStatus.WaitingForChildrenToComplete))
{
Thread.Sleep(100);
Application.DoEvents();
}
Utils.WaitForTask(applyTask);
}
}
@@ -1540,6 +1590,11 @@ namespace ColorControl
MessageBox.Show(text, Text, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private DialogResult QuestionYesNo(string text)
{
return MessageBox.Show(text, Text, MessageBoxButtons.YesNo, MessageBoxIcon.Information);
}
private void lvLgPresets_DoubleClick(object sender, EventArgs e)
{
ApplySelectedLgPreset();
@@ -1600,5 +1655,92 @@ namespace ColorControl
}
edtStepsLg.Text = text.Trim();
}
private void clbLgPower_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (!_initialized)
{
return;
}
if (!(_lgService.Config.PowerOnAfterResume || _lgService.Config.PowerOnAfterStartup))
{
InfoOk(
@"Be sure to activate the following setting on the TV, or the app will not be able to wake the TV:
Connection > Mobile TV On > Turn on via Wi-Fi
See Options to test this functionality."
);
}
this.BeginInvoke(new Action(() =>
{
_lgService.Config.PowerOnAfterStartup = clbLgPower.GetItemChecked(0);
_lgService.Config.PowerOnAfterResume = clbLgPower.GetItemChecked(1);
_lgService.Config.PowerOffOnShutdown = clbLgPower.GetItemChecked(2);
_lgService.Config.PowerOffOnStandby = clbLgPower.GetItemChecked(3);
}));
}
private void edtLgPowerOnAfterResumeDelay_ValueChanged(object sender, EventArgs e)
{
_lgService.Config.PowerOnDelayAfterResume = (int)edtLgPowerOnAfterResumeDelay.Value;
}
private void chkFixChromeFonts_CheckedChanged(object sender, EventArgs e)
{
if (_initialized)
{
if (chkFixChromeFonts.Checked)
{
Utils.ExecuteElevated(StartUpParams.ActivateChromeFontFixParam);
}
else
{
Utils.ExecuteElevated(StartUpParams.DeactivateChromeFontFixParam);
}
}
}
private void btnLGTestPower_Click(object sender, EventArgs e)
{
var text =
@"The TV will now power off. Please wait for the TV to be powered off completely (relay click) and press ENTER to wake it again.
For waking up to work, you need to activate the following setting on the TV:
Connection > Mobile TV On > Turn on via Wi-Fi
It will also work over a wired connection.
Do you want to continue?";
if (QuestionYesNo(text) == DialogResult.Yes)
{
_lgService.PowerOff();
InfoOk("Press ENTER to wake the TV.");
_lgService.WakeSelectedDevice();
}
}
private void btnSetShortcutScreenSaver_Click(object sender, EventArgs e)
{
var shortcut = edtBlankScreenSaverShortcut.Text.Trim();
if (!string.IsNullOrWhiteSpace(shortcut) && !shortcut.Contains("+"))
{
WarningOk("Invalid shortcut. The shortcut should have modifiers and a normal key.");
return;
}
var oldShortcut = _config.ScreenSaverShortcut;
var clear = !string.IsNullOrEmpty(oldShortcut);
_config.ScreenSaverShortcut = shortcut;
RegisterShortcut(SHORTCUTID_SCREENSAVER, shortcut, clear);
}
}
}
+16 -8
View File
@@ -1,22 +1,30 @@
using System.Collections.Generic;
using System.Linq;
using Windows.Devices.Enumeration;
using Windows.Devices.Enumeration.Pnp;
namespace ColorControl
{
class PnpDev
{
public string name { get; set; }
public string ipAddress { get; set; }
public DeviceInformation DevInfo { get; private set; }
public PnpObject PnpObject { get; private set; }
public PnpDev(string name, string ipAddress)
public string Name { get; private set; }
public string IpAddress { get; private set; }
public string MacAddress { get; private set; }
public PnpDev(DeviceInformation devInfo, PnpObject pnpObject, string name, string ipAddress, string macAddress)
{
this.name = name;
this.ipAddress = ipAddress;
DevInfo = devInfo;
PnpObject = pnpObject;
Name = name;
IpAddress = ipAddress;
MacAddress = macAddress;
}
public override string ToString()
{
return name + " (" + ipAddress + ")";
return Name + " (" + IpAddress + ")";
}
}
}
+10 -5
View File
@@ -1,8 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ColorControl
@@ -13,8 +10,16 @@ namespace ColorControl
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
static void Main(string[] args)
{
var startUpParams = StartUpParams.Parse(args);
if (startUpParams.ActivateChromeFontFix || startUpParams.DeactivateChromeFontFix)
{
Utils.InstallChromeFix(startUpParams.ActivateChromeFontFix);
return;
}
string mutexId = $"Global\\{typeof(MainForm).GUID}";
bool mutexCreated;
var mutex = new Mutex(true, mutexId, out mutexCreated);
@@ -28,7 +33,7 @@ namespace ColorControl
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
Application.Run(new MainForm(startUpParams));
}
}
finally
+2 -2
View File
@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.3.0")]
[assembly: AssemblyFileVersion("1.0.3.0")]
[assembly: AssemblyVersion("1.1.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")]
+10 -1
View File
@@ -1,6 +1,8 @@
using NLog;
using Microsoft.Win32;
using NLog;
using System;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
namespace ColorControl
{
@@ -35,6 +37,13 @@ namespace ColorControl
}
}
public bool IsRebootInProgress()
{
var registry = Registry.LocalMachine;
var subKey = registry.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Component Based Servicing");
return subKey.GetValueNames().Any(x => x.Equals("RebootInProgress"));
}
public void EventLogEventRead(object obj, EventRecordWrittenEventArgs arg)
{
RestartDetected = false;
+42
View File
@@ -0,0 +1,42 @@
using System.Collections.Generic;
namespace ColorControl
{
public class StartUpParams
{
public const string RunningFromScheduledTaskParam = "--scheduled";
public const string ActivateChromeFontFixParam = "--activate-chrome-font-fix";
public const string DeactivateChromeFontFixParam = "--deactivate-chrome-font-fix";
public bool RunningFromScheduledTask { get; private set; }
public bool ActivateChromeFontFix { get; private set; }
public bool DeactivateChromeFontFix { get; private set; }
public static StartUpParams Parse(IEnumerable<string> args)
{
var settings = new StartUpParams();
foreach (var arg in args)
{
switch (arg.ToLowerInvariant())
{
case RunningFromScheduledTaskParam:
{
settings.RunningFromScheduledTask = true;
break;
}
case ActivateChromeFontFixParam:
{
settings.ActivateChromeFontFix = true;
break;
}
case DeactivateChromeFontFixParam:
{
settings.DeactivateChromeFontFix = true;
break;
}
}
}
return settings;
}
}
}
+143 -71
View File
@@ -1,10 +1,12 @@
using NWin32.NativeTypes;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Windows.Devices.Enumeration;
@@ -23,7 +25,8 @@ namespace ColorControl
Win = 8
}
public static string PKEY_PNPX_IpAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12297";
public static string PKEY_PNPX_IpAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12297";
public static string PKEY_PNPX_PhysicalAddress = "{656a3bb3-ecc0-43fd-8477-4ae0404a96cd} 12294";
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
@@ -121,76 +124,150 @@ namespace ColorControl
return (mods, key);
}
public static async Task<string> GetDeviceProperty(string deviceName, string propertyName)
internal static bool ExecuteElevated(string args)
{
string value = null;
string name = null;
var list = await DeviceInformation.FindAllAsync("", new List<string>());
var reqs = new List<string>();
reqs.Add(propertyName);
foreach (var dev in list)
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location, args)
{
name = dev.Name;
if (dev.IsEnabled && dev.Name.Contains(deviceName))
Verb = "runas", // indicates to elevate privileges
};
var process = new Process
{
EnableRaisingEvents = true, // enable WaitForExit()
StartInfo = info
};
try
{
process.Start();
process.WaitForExit(); // sleep calling process thread until evoked process exit
return true;
}
catch (Exception e)
{
Logger.Error("ExecuteElevated: " + e.Message);
}
return false;
}
internal static bool IsChromeFixInstalled()
{
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command");
return key != null && key.GetValue(null).ToString().Contains("--disable-lcd-text");
}
internal static bool InstallChromeFix(bool install)
{
//var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command", true);
//if (key != null)
//{
// var value = key.GetValue(null).ToString();
// if (install)
// {
// value = value.Replace("chrome.exe\" -- \"", "chrome.exe\" --disable-lcd-text -- \"");
// }
// else
// {
// value = value.Replace("chrome.exe\" --disable-lcd-text -- \"", "chrome.exe\" -- \"");
// }
// key.SetValue(null, value);
//}
var argument = "--disable-lcd-text";
var roamingFolder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
UpdateShortcut(Path.Combine(roamingFolder, @"Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Google Chrome.lnk"), argument, !install);
UpdateShortcut(Path.Combine(roamingFolder, @"Microsoft\Internet Explorer\Quick Launch\Google Chrome.lnk"), argument, !install);
var allUsersStartMenuFolder = Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu);
UpdateShortcut(Path.Combine(allUsersStartMenuFolder, @"Programs\Google Chrome.lnk"), argument, !install);
return true;
}
internal static bool IsChromeInstalled()
{
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command");
return key != null;
}
internal static bool UpdateShortcut(string path, string arguments, bool removeArguments = false)
{
if (File.Exists(path))
{
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
// C:\Users\All Users\Microsoft\Windows\Start Menu\Programs
// C:\Users\vinni\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch
// C:\Users\vinni\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar\Google Chrome.lnk
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(path);
shortcut.Arguments = shortcut.Arguments.Replace(arguments, "");
if (!removeArguments)
{
//Debug.WriteLine(dev.Name);
//foreach (var key in dev.Properties.Keys)
//{
// Debug.WriteLine($"* {key}: {dev.Properties[key]}");
//}
var guid = dev.Properties["System.Devices.DeviceInstanceId"];
var aqs = "System.Devices.DeviceInstanceId:=\"" + guid + "\"";
var list2 = await PnpObject.FindAllAsync(PnpObjectType.Device, reqs, aqs);
foreach (var dev2 in list2)
if (!string.IsNullOrEmpty(shortcut.Arguments))
{
foreach (var key in dev2.Properties.Keys)
{
var obj = dev2.Properties[key];
string newValue = null;
if (obj is string[])
{
var arr = obj as string[];
if (arr.Length > 0)
{
newValue = arr[0];
}
}
else
{
newValue = dev2.Properties[key].ToString();
}
if (newValue != value)
{
value = newValue;
Logger.Debug($"LG TV with name {dev.Name} found at {value}");
}
//Debug.WriteLine($"* {key}: {value}");
}
shortcut.Arguments = shortcut.Arguments + " ";
}
shortcut.Arguments = shortcut.Arguments + arguments;
}
// save it / create
shortcut.Save();
return true;
}
return false;
}
public static string GetDeviceProperty(PnpObject device, string propertyName)
{
object objValue;
string value = null;
foreach (var key in device.Properties.Keys)
{
Debug.WriteLine(key);
}
if (device.Properties.TryGetValue(propertyName, out objValue))
{
if (objValue is string[])
{
var arr = objValue as string[];
if (arr.Length > 0)
{
value = arr[0];
}
}
else if (objValue is byte[])
{
value = BitConverter.ToString((byte[])objValue);
}
else
{
value = objValue.ToString();
}
}
return value;
}
public static async Task<List<PnpDev>> GetPnpDevices(string deviceName, string propertyName)
public static async Task<List<PnpDev>> GetPnpDevices(string deviceName)
{
var devices = new List<PnpDev>();
var list = await DeviceInformation.FindAllAsync("", new List<string>());
var reqs = new List<string>();
reqs.Add(propertyName);
reqs.Add(PKEY_PNPX_IpAddress);
reqs.Add(PKEY_PNPX_PhysicalAddress);
foreach (var dev in list)
{
string name = dev.Name;
if (dev.IsEnabled && dev.Name.Contains(deviceName))
if (/*dev.IsEnabled &&*/ dev.Name.Contains(deviceName))
{
var guid = dev.Properties["System.Devices.DeviceInstanceId"];
@@ -199,27 +276,13 @@ namespace ColorControl
foreach (var dev2 in list2)
{
foreach (var key in dev2.Properties.Keys)
var ipAddress = GetDeviceProperty(dev2, "System.Devices.IpAddress");
var macAddress = GetDeviceProperty(dev2, PKEY_PNPX_PhysicalAddress);
if (!devices.Any(x => x.Name.Equals(name) && x.IpAddress.Equals(ipAddress)))
{
var obj = dev2.Properties[key];
string value = null;
if (obj is string[])
{
var arr = obj as string[];
if (arr.Length > 0)
{
value = arr[0];
}
}
else
{
value = dev2.Properties[key].ToString();
}
if (!devices.Any(x => x.name.Equals(name) && x.ipAddress.Equals(value)))
{
var device = new PnpDev(name, value);
devices.Add(device);
}
var device = new PnpDev(dev, dev2, name, ipAddress, macAddress);
devices.Add(device);
}
}
@@ -227,5 +290,14 @@ namespace ColorControl
}
return devices;
}
public static void WaitForTask(Task task)
{
while (task != null && (task.Status < TaskStatus.WaitingForChildrenToComplete))
{
Thread.Sleep(100);
Application.DoEvents();
}
}
}
}
+73
View File
@@ -0,0 +1,73 @@
using NLog;
using System;
using System.Globalization;
using PacketDotNet;
using System.Net.NetworkInformation;
using SharpPcap;
using System.Diagnostics;
using SharpPcap.Npcap;
using System.Linq;
namespace ColorControl
{
class WOL
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
//You need SharpPcap for this to work
public static void WakeFunction(string macAddress)
{
/* Retrieve the device list */
var devices = CaptureDeviceList.Instance;
Logger.Debug("Waking device with MAC-address " + macAddress);
/*If no device exists, print error */
if (devices.Count < 1)
{
Logger.Debug("No network device found on this machine");
return;
}
foreach (var device in devices)
{
if (device is NpcapDevice npcapDevice)
{
if (!npcapDevice.Interface.GatewayAddresses.Any())
{
continue;
}
}
Logger.Debug("Opening network device: " + device.Name);
//Open the device
device.Open();
//A magic packet is a broadcast frame containing anywhere within its payload: 6 bytes of ones
//(resulting in hexadecimal FF FF FF FF FF FF), followed by sixteen repetitions
string response = macAddress.Replace(":", "-");
var address = PhysicalAddress.Parse("FFFFFFFFFFFF");
EthernetPacket ethernet = new EthernetPacket(address, address, EthernetType.WakeOnLan);
ethernet.PayloadPacket = new WakeOnLanPacket(PhysicalAddress.Parse(response));
byte[] bytes = ethernet.Bytes;
try
{
//Send the packet out the network device
device.SendPacket(bytes);
}
catch (Exception e)
{
Logger.Debug(e.Message);
}
device.Close();
}
}
}
}
+6
View File
@@ -6,5 +6,11 @@
<package id="NStandard" version="0.4.3" targetFramework="net472" />
<package id="NvAPIWrapper.Net" version="0.8.0.98" targetFramework="net472" />
<package id="NWin32" version="1.0.6" targetFramework="net472" />
<package id="PacketDotNet" version="1.0.5" targetFramework="net472" />
<package id="SharpPcap" version="5.2.0" targetFramework="net472" />
<package id="System.Buffers" version="4.5.1" targetFramework="net472" />
<package id="System.Memory" version="4.5.4" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.5.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.7.0" targetFramework="net472" />
<package id="TaskScheduler" version="2.8.20" targetFramework="net472" />
</packages>