mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-21 16:12:18 -05:00
fix WOL issues, add Windows Service
This commit is contained in:
1 parent
a8d41f67c9
commit
452206729b
20 files changed
+1517
-266
No files matched your search
+1
-1
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.0.32014.148
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ColorControl", "ColorControl\ColorControl.csproj", "{A6005D08-70F0-44CB-A384-9219EBA84F21}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nspector", "Nspector\Nspector.csproj", "{76797290-48F5-4A82-86C3-FAD25DAE4500}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nspector", "Nspector\Nspector.csproj", "{76797290-48F5-4A82-86C3-FAD25DAE4500}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
||||
@@ -1,32 +1,33 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0-windows10.0.20348.0</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>false</MapFileExtensions>
|
||||
<UpdateUrl>https://www.maassoft.com/downloads/ColorControl/</UpdateUrl>
|
||||
<ProductName>ColorControl</ProductName>
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<TargetFramework>net6.0-windows10.0.20348.0</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>false</MapFileExtensions>
|
||||
<UpdateUrl>https://www.maassoft.com/downloads/ColorControl/</UpdateUrl>
|
||||
<ProductName>ColorControl</ProductName>
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<Company>Maassoft</Company>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>7.3.0.0</ApplicationVersion>
|
||||
<Version>7.3.0.0</Version>
|
||||
<ApplicationVersion>8.0.0.0</ApplicationVersion>
|
||||
<Version>8.0.0.0</Version>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>false</UseWPF>
|
||||
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<UseWPF>false</UseWPF>
|
||||
<ImportWindowsDesktopTargets>true</ImportWindowsDesktopTargets>
|
||||
<ApplicationIcon>pngbarn.ico</ApplicationIcon>
|
||||
<SupportedOSPlatformVersion>10.0.20348.0</SupportedOSPlatformVersion>
|
||||
<Copyright>2020-2022 Maassoft</Copyright>
|
||||
@@ -40,68 +41,70 @@
|
||||
<AssemblyOriginatorKeyFile>ColorControl_TemporaryKey.pfx</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Services\Common\QuickAccessForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="services\lg\RemoteControlPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Resources\LG_register.json" />
|
||||
<EmbeddedResource Include="Resources\RC_coords.txt" />
|
||||
<EmbeddedResource Include="Resources\LG_remote.jpg" />
|
||||
<Content Include="LgPresets.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Compile Update="Properties\Settings.Designer.cs">
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Services\Common\QuickAccessForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="services\lg\RemoteControlPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<EmbeddedResource Include="Resources\LG_register.json" />
|
||||
<EmbeddedResource Include="Resources\RC_coords.txt" />
|
||||
<EmbeddedResource Include="Resources\LG_remote.jpg" />
|
||||
<Content Include="LgPresets.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="pngbarn.ico" />
|
||||
<Content Include="pngbarn.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="bin\x64\Debug\" />
|
||||
<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>
|
||||
<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>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.1" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="5.0.2" />
|
||||
<PackageReference Include="NStandard" Version="0.10.0.1" />
|
||||
<PackageReference Include="NvAPIWrapper.Net" Version="0.8.1.101" />
|
||||
<PackageReference Include="NWin32" Version="1.2.3" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.10.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="NLog" Version="5.0.4" />
|
||||
<PackageReference Include="NStandard" Version="0.15.2" />
|
||||
<PackageReference Include="NvAPIWrapper.Net" Version="0.8.1.101" />
|
||||
<PackageReference Include="NWin32" Version="1.2.3" />
|
||||
<PackageReference Include="TaskScheduler" Version="2.10.1" />
|
||||
<PackageReference Include="Vanara.PInvoke.IpHlpApi" Version="3.4.9" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Nspector\Nspector.csproj" />
|
||||
<ProjectReference Include="..\Nspector\Nspector.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<None Update="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,83 @@
|
||||
using ColorControl.Svc;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO.Pipes;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace ColorControl.Common
|
||||
{
|
||||
public static class PipeUtils
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public static string SendMessage(string message)
|
||||
{
|
||||
var pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None);
|
||||
try
|
||||
{
|
||||
pipeClient.Connect(500);
|
||||
try
|
||||
{
|
||||
var ss = new StreamString(pipeClient);
|
||||
|
||||
ss.WriteString(message);
|
||||
|
||||
var result = ss.ReadString();
|
||||
|
||||
return result;
|
||||
}
|
||||
finally
|
||||
{
|
||||
pipeClient.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex, "PipeUtils.SendMessage");
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static SvcResultMessage SendMessage(SvcMessage message)
|
||||
{
|
||||
var messageJson = JsonConvert.SerializeObject(message);
|
||||
|
||||
var resultJson = SendMessage(messageJson);
|
||||
|
||||
if (resultJson == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var resultMessage = JsonConvert.DeserializeObject<SvcResultMessage>(resultJson);
|
||||
|
||||
return resultMessage;
|
||||
}
|
||||
|
||||
public static SvcResultMessage SendMessage(SvcMessageType messageType)
|
||||
{
|
||||
var message = new SvcMessage { MessageType = messageType };
|
||||
|
||||
return SendMessage(message);
|
||||
}
|
||||
|
||||
public static bool? SendRpcMessage(string command)
|
||||
{
|
||||
var message = new SvcMessage { MessageType = SvcMessageType.ExecuteRpc, Data = command };
|
||||
|
||||
var messageJson = JsonConvert.SerializeObject(message);
|
||||
|
||||
var resultJson = SendMessage(messageJson);
|
||||
|
||||
if (resultJson == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var resultMessage = JsonConvert.DeserializeObject<SvcResultMessage>(resultJson);
|
||||
|
||||
return resultMessage.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace ColorControl.Common
|
||||
{
|
||||
public class StreamString
|
||||
{
|
||||
private Stream ioStream;
|
||||
private UnicodeEncoding streamEncoding;
|
||||
|
||||
public StreamString(Stream ioStream)
|
||||
{
|
||||
this.ioStream = ioStream;
|
||||
streamEncoding = new UnicodeEncoding();
|
||||
}
|
||||
|
||||
public string ReadString()
|
||||
{
|
||||
var lenBytes = new byte[4];
|
||||
|
||||
var read = ioStream.Read(lenBytes, 0, lenBytes.Length);
|
||||
|
||||
if (read < lenBytes.Length)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var len = BitConverter.ToInt32(lenBytes);
|
||||
|
||||
var inBuffer = new byte[len];
|
||||
ioStream.Read(inBuffer, 0, len);
|
||||
|
||||
return streamEncoding.GetString(inBuffer);
|
||||
}
|
||||
|
||||
public int WriteString(string outString)
|
||||
{
|
||||
var outBuffer = streamEncoding.GetBytes(outString);
|
||||
var len = outBuffer.Length;
|
||||
|
||||
var lenBytes = BitConverter.GetBytes(len);
|
||||
|
||||
ioStream.Write(lenBytes, 0, lenBytes.Length);
|
||||
ioStream.Write(outBuffer, 0, len);
|
||||
ioStream.Flush();
|
||||
|
||||
return outBuffer.Length + lenBytes.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
+280
-27
@@ -14,9 +14,12 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
@@ -49,6 +52,23 @@ namespace ColorControl.Common
|
||||
private static bool WinKeyDown = false;
|
||||
private static Keys[] KeysWithoutModifiers = new[] { Keys.F13, Keys.F14, Keys.F15, Keys.F16, Keys.F17, Keys.F18, Keys.F19, Keys.F20, Keys.F21, Keys.F22, Keys.F23, Keys.F24 };
|
||||
|
||||
private static string SERVICE_NAME = "Color Control Service";
|
||||
|
||||
public static string ELEVATION_MSG = @"Elevation is needed in some cases where ColorControl needs administrator rights.
|
||||
Some operations like installing a service, changing the priority of a process or creating a temporary IP-route for improved WOL-functionality will not work without those rights.
|
||||
|
||||
These methods are available:
|
||||
|
||||
- None: no administrator operations can be executed (unless program already manually is started as admin)
|
||||
|
||||
- Run as admin: only available when starting automatically after login (configures scheduled task with highest privileges)
|
||||
|
||||
- Use Windows Service: this will install a Windows Service that handles the operations which need admin rights. This is the preferred method.
|
||||
|
||||
- Use dedicated elevated process: a second ColorControl-process will be spawned that is run as administrator.
|
||||
|
||||
The best and suggested method to provide this is via a Windows Service. Only when installing the service a User Account Control window may popup.";
|
||||
|
||||
public static Bitmap SubPixelShift(Bitmap bitmap)
|
||||
{
|
||||
Bitmap bitmap2 = (Bitmap)bitmap.Clone();
|
||||
@@ -170,15 +190,34 @@ namespace ColorControl.Common
|
||||
return keys;
|
||||
}
|
||||
|
||||
static bool IsAdministrator()
|
||||
private static bool? _IsAdministrator;
|
||||
|
||||
public static bool IsAdministrator()
|
||||
{
|
||||
if (_IsAdministrator.HasValue)
|
||||
{
|
||||
return _IsAdministrator.Value;
|
||||
}
|
||||
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
return principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
_IsAdministrator = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
return _IsAdministrator.Value;
|
||||
}
|
||||
|
||||
internal static int ExecuteElevated(string args, bool wait = true, bool skipDedicated = false)
|
||||
internal static int ExecuteElevated(string args, bool wait = true, bool skipDedicated = false, bool skipService = false)
|
||||
{
|
||||
if (!skipService && IsServiceRunning())
|
||||
{
|
||||
var result = PipeUtils.SendRpcMessage(args);
|
||||
|
||||
if (result.HasValue)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (UseDedicatedElevatedProcess && !skipDedicated)
|
||||
{
|
||||
CheckElevatedProcess();
|
||||
@@ -188,7 +227,9 @@ namespace ColorControl.Common
|
||||
return 0;
|
||||
}
|
||||
|
||||
var info = new ProcessStartInfo(Process.GetCurrentProcess().MainModule.FileName, args)
|
||||
var fileName = Process.GetCurrentProcess().MainModule.FileName;
|
||||
|
||||
var info = new ProcessStartInfo(fileName, args)
|
||||
{
|
||||
Verb = "runas", // indicates to elevate privileges
|
||||
UseShellExecute = true,
|
||||
@@ -225,11 +266,24 @@ namespace ColorControl.Common
|
||||
|
||||
if (ElevatedProcessWindowHandle == IntPtr.Zero)
|
||||
{
|
||||
ExecuteElevated(StartUpParams.StartElevatedParam, false, true);
|
||||
ExecuteElevated(StartUpParams.StartElevatedParam, false, true, true);
|
||||
|
||||
Thread.Sleep(500);
|
||||
var delay = 1000;
|
||||
|
||||
ElevatedProcessWindowHandle = NativeMethods.FindWindowW(null, "ElevatedForm");
|
||||
while (delay >= 0)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
ElevatedProcessWindowHandle = NativeMethods.FindWindowW(null, "ElevatedForm");
|
||||
|
||||
if (ElevatedProcessWindowHandle != IntPtr.Zero)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
break;
|
||||
}
|
||||
|
||||
delay -= 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -494,11 +548,11 @@ namespace ColorControl.Common
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void RegisterTask(string taskName, bool enabled)
|
||||
public static void RegisterTask(string taskName, bool enabled, TaskRunLevel runLevel = TaskRunLevel.LUA)
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated(enabled ? StartUpParams.EnableAutoStartParam : StartUpParams.DisableAutoStartParam);
|
||||
ExecuteElevated(enabled ? $"{StartUpParams.EnableAutoStartParam} {(int)runLevel}" : StartUpParams.DisableAutoStartParam, skipService: true);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -511,8 +565,10 @@ namespace ColorControl.Common
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
TaskDefinition td = ts.NewTask();
|
||||
var td = ts.NewTask();
|
||||
|
||||
td.RegistrationInfo.Description = "Start ColorControl";
|
||||
td.Principal.RunLevel = runLevel;
|
||||
|
||||
td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name });
|
||||
|
||||
@@ -528,32 +584,18 @@ namespace ColorControl.Common
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//MessageForms.ErrorOk("Could not create/delete task: " + e.Message);
|
||||
Logger.Error($"Could not create/delete task: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TaskExists(string taskName, bool update)
|
||||
public static bool TaskExists(string taskName)
|
||||
{
|
||||
var file = Assembly.GetExecutingAssembly().Location;
|
||||
using (TaskService ts = new TaskService())
|
||||
{
|
||||
var task = ts.RootFolder.Tasks.FirstOrDefault(x => x.Name.Equals(taskName));
|
||||
|
||||
if (task != null)
|
||||
{
|
||||
//var action = task.Definition.Actions.FirstOrDefault(x => x.ActionType == TaskActionType.Execute);
|
||||
//if (action != null)
|
||||
//{
|
||||
// var execAction = action as ExecAction;
|
||||
// if (!execAction.Path.Equals(file))
|
||||
// {
|
||||
// RegisterTask(taskName, false);
|
||||
// RegisterTask(taskName, true);
|
||||
// }
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return task != null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -871,5 +913,216 @@ namespace ColorControl.Common
|
||||
{
|
||||
return str1.Trim().Replace(" ", string.Empty).Equals(str2.Trim().Replace(" ", string.Empty), StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static void StartService()
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated(StartUpParams.StartServiceParam);
|
||||
return;
|
||||
}
|
||||
|
||||
var controller = new ServiceController(SERVICE_NAME);
|
||||
|
||||
if (controller.Status == ServiceControllerStatus.Stopped)
|
||||
{
|
||||
controller.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void StopService()
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated(StartUpParams.StopServiceParam);
|
||||
return;
|
||||
}
|
||||
|
||||
var controller = new ServiceController(SERVICE_NAME);
|
||||
|
||||
if (controller.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
controller.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsServiceInstalled()
|
||||
{
|
||||
return GetServiceStatus() != 0;
|
||||
}
|
||||
|
||||
public static bool IsServiceRunning()
|
||||
{
|
||||
return GetServiceStatus() == ServiceControllerStatus.Running;
|
||||
}
|
||||
|
||||
public static ServiceControllerStatus GetServiceStatus()
|
||||
{
|
||||
var controller = new ServiceController(SERVICE_NAME);
|
||||
|
||||
try
|
||||
{
|
||||
return controller.Status;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InstallService()
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated(StartUpParams.InstallServiceParam, skipService: true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!IsServiceInstalled())
|
||||
{
|
||||
StartProcess("sc.exe", @$"create ""{SERVICE_NAME}"" binpath=""{Process.GetCurrentProcess().MainModule.FileName}"" start=auto", wait: true);
|
||||
StartProcess("sc.exe", @$"description ""{SERVICE_NAME}"" ""Executes tasks for Color Control that require elevation. If this service is stopped, functions like WOL might be impacted.""", wait: true);
|
||||
}
|
||||
|
||||
StartService();
|
||||
}
|
||||
|
||||
internal static void UninstallService()
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated(StartUpParams.UninstallServiceParam, skipService: true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!IsServiceInstalled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StopService();
|
||||
|
||||
StartProcess("sc.exe", @$"delete ""{SERVICE_NAME}""", wait: true);
|
||||
}
|
||||
|
||||
public static bool PingHost(string nameOrAddress)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var pinger = new Ping();
|
||||
var reply = pinger.Send(nameOrAddress);
|
||||
return reply.Status == IPStatus.Success;
|
||||
}
|
||||
catch (PingException)
|
||||
{
|
||||
// Discard PingExceptions and return false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool WriteText(string fileName, string data)
|
||||
{
|
||||
var doWrite = !File.Exists(fileName);
|
||||
|
||||
if (!doWrite)
|
||||
{
|
||||
var writtenData = File.ReadAllText(fileName);
|
||||
|
||||
doWrite = !writtenData.Equals(data);
|
||||
}
|
||||
|
||||
if (doWrite)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllText(fileName, data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
}
|
||||
|
||||
return doWrite;
|
||||
}
|
||||
|
||||
public static string ReadText(string fileName, bool reverse = false)
|
||||
{
|
||||
var exists = File.Exists(fileName);
|
||||
|
||||
if (!exists)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var lines = new StringBuilder();
|
||||
|
||||
using var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
|
||||
using var reader = new StreamReader(fs);
|
||||
|
||||
string line;
|
||||
|
||||
while ((line = reader.ReadLine()) != null)
|
||||
{
|
||||
if (reverse)
|
||||
{
|
||||
lines.Insert(0, line + "\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
lines.AppendLine(line);
|
||||
}
|
||||
|
||||
return lines.ToString();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool WriteObject(string fileName, object value)
|
||||
{
|
||||
var data = JsonConvert.SerializeObject(value);
|
||||
|
||||
return WriteText(fileName, data);
|
||||
}
|
||||
|
||||
public static T DeserializeJson<T>(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = File.ReadAllText(fileName);
|
||||
var data = JsonConvert.DeserializeObject<T>(json);
|
||||
|
||||
return data;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Base64Encode(string plainText)
|
||||
{
|
||||
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
|
||||
return Convert.ToBase64String(plainTextBytes);
|
||||
}
|
||||
|
||||
public static string Base64Decode(string base64EncodedData)
|
||||
{
|
||||
var base64EncodedBytes = Convert.FromBase64String(base64EncodedData);
|
||||
return Encoding.UTF8.GetString(base64EncodedBytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
+169
-27
@@ -1,67 +1,97 @@
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using Vanara.PInvoke;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
|
||||
namespace ColorControl.Common
|
||||
{
|
||||
class WOL
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
||||
private const string ArgumentExceptionInvalidMacAddressLength = "Invalid MAC address length.";
|
||||
private const string ArgumentExceptionInvalidPasswordLength = "Invalid password length.";
|
||||
private const int DefaultWolPort = 9;
|
||||
|
||||
public static bool WakeFunction(string macAddress)
|
||||
public static bool WakeFunction(string macAddress, string ipAddress = null)
|
||||
{
|
||||
return WakeFunctionToAllNics(macAddress);
|
||||
return WakeFunctionToAllNics(macAddress, ipAddress);
|
||||
}
|
||||
|
||||
public static bool WakeFunctionToAllNics(string macAddress)
|
||||
public static bool WakeFunctionCheckAdmin(string macAddress, string ipAddress = null)
|
||||
{
|
||||
if (Utils.IsAdministrator())
|
||||
{
|
||||
return WakeFunction(macAddress, ipAddress);
|
||||
}
|
||||
|
||||
var result = PipeUtils.SendRpcMessage($"{StartUpParams.SendWakeOnLanParam} {macAddress} {ipAddress}");
|
||||
|
||||
// Execute local WOL anyway because pipe failed
|
||||
if (!result.HasValue)
|
||||
{
|
||||
result = WakeFunction(macAddress, ipAddress);
|
||||
}
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
|
||||
public static bool WakeFunctionToAllNics(string macAddress, string ipAddressString)
|
||||
{
|
||||
var result = false;
|
||||
Logger.Debug($"Sending WOL packet to MAC-address {macAddress}");
|
||||
|
||||
try
|
||||
{
|
||||
var address = PhysicalAddress.Parse(macAddress);
|
||||
var addressBytes = address.GetAddressBytes();
|
||||
var physicalAddress = PhysicalAddress.Parse(macAddress);
|
||||
var addressBytes = physicalAddress.GetAddressBytes();
|
||||
var data = GetWolPacket(addressBytes);
|
||||
var ipAddress = ipAddressString != null ? IPAddress.Parse(ipAddressString) : null;
|
||||
|
||||
var interfaces = NetworkInterface.GetAllNetworkInterfaces();
|
||||
|
||||
foreach (var ni in interfaces)
|
||||
{
|
||||
if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback || ni.Name.Contains("VirtualBox"))
|
||||
if (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback || ni.Name.Contains("VirtualBox") || ni.Name.Contains("vEthernet") || ni.Description.Contains("Virtual"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Logger.Debug($"Found network: {ni.Name} ({ni.Description}), type: {ni.NetworkInterfaceType}");
|
||||
try
|
||||
{
|
||||
if (/*ni.OperationalStatus == OperationalStatus.Up &&*/ ni.SupportsMulticast && ni.GetIPProperties().GetIPv4Properties() != null)
|
||||
if (ni.SupportsMulticast && ni.GetIPProperties().GetIPv4Properties() == null)
|
||||
{
|
||||
foreach (var uip in ni.GetIPProperties().UnicastAddresses)
|
||||
{
|
||||
if (uip.Address.ToString().StartsWith("169.254"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (uip.Address.AddressFamily == AddressFamily.InterNetwork)
|
||||
{
|
||||
Logger.Debug($"Broadcast WOL in network: {ni.Name} ({ni.Description}), local address: {uip.Address}");
|
||||
var local = new IPEndPoint(uip.Address, 0);
|
||||
var udpc = new UdpClient(local);
|
||||
udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
|
||||
udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
|
||||
var target = new IPEndPoint(IPAddress.Broadcast, DefaultWolPort);
|
||||
udpc.Send(data, data.Length, target);
|
||||
continue;
|
||||
}
|
||||
|
||||
result = true;
|
||||
}
|
||||
foreach (var uip in ni.GetIPProperties().UnicastAddresses)
|
||||
{
|
||||
if (uip.Address.ToString().StartsWith("169.254") || uip.Address.AddressFamily != AddressFamily.InterNetwork)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Logger.Debug($"Broadcast WOL in network: {ni.Name} ({ni.Description}), local address: {uip.Address}, destination IP-address: {ipAddressString ?? "broadcast"}");
|
||||
|
||||
if (ipAddress != null)
|
||||
{
|
||||
var localEP = new IPEndPoint(uip.Address, 0);
|
||||
|
||||
SendWolToIpAddress(uip.Address, ipAddress, data, physicalAddress);
|
||||
}
|
||||
|
||||
BroadcastWol(uip.Address, IPAddress.Broadcast, data);
|
||||
|
||||
var parts = uip.Address.ToString().Split(".").ToList();
|
||||
parts[3] = "0";
|
||||
var broadcastAddress = IPAddress.Parse(string.Join(".", parts));
|
||||
BroadcastWol(uip.Address, broadcastAddress, data);
|
||||
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -110,5 +140,117 @@ namespace ColorControl.Common
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
}
|
||||
|
||||
private static void BroadcastWol(IPAddress localAddress, IPAddress broadCastAddress, byte[] data)
|
||||
{
|
||||
//var localEP = new IPEndPoint(localAddress, 0);
|
||||
var udpc = new UdpClient();
|
||||
|
||||
udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
|
||||
//udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontRoute, 1);
|
||||
|
||||
var target = new IPEndPoint(broadCastAddress, DefaultWolPort);
|
||||
|
||||
udpc.Send(data, data.Length, target);
|
||||
}
|
||||
|
||||
private static void SendWolToIpAddress(IPAddress localAddress, IPAddress remoteAddress, byte[] data, PhysicalAddress physicalAddress)
|
||||
{
|
||||
//var localEP = new IPEndPoint(localAddress, 0);
|
||||
|
||||
var netLuid = CreateTransientLocalNetEntry(remoteAddress, physicalAddress);
|
||||
try
|
||||
{
|
||||
var udpc = new UdpClient();
|
||||
udpc.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
|
||||
|
||||
var target = new IPEndPoint(remoteAddress, DefaultWolPort);
|
||||
|
||||
udpc.Send(data, data.Length, target);
|
||||
}
|
||||
finally
|
||||
{
|
||||
DeleteNetEntry(netLuid, remoteAddress);
|
||||
}
|
||||
}
|
||||
|
||||
private static NET_LUID CreateTransientLocalNetEntry(IPAddress ipAddress, PhysicalAddress macAddress)
|
||||
{
|
||||
var ipBytes = ipAddress.GetAddressBytes();
|
||||
|
||||
var address = new Ws2_32.SOCKADDR_INET
|
||||
{
|
||||
si_family = Ws2_32.ADDRESS_FAMILY.AF_INET,
|
||||
Ipv4 = new Ws2_32.SOCKADDR_IN(new Ws2_32.IN_ADDR(ipBytes), DefaultWolPort),
|
||||
};
|
||||
|
||||
var net = new NET_LUID();
|
||||
var addr = new Ws2_32.SOCKADDR_INET();
|
||||
|
||||
MIB_IPFORWARD_ROW2 forwardRow;
|
||||
var result = GetBestRoute2(net, 0, addr, address, 0, out forwardRow, out _);
|
||||
|
||||
if (result != Win32Error.ERROR_SUCCESS)
|
||||
{
|
||||
Logger.Debug($"Cannot find best route: {result}");
|
||||
|
||||
var luidDummy = new NET_LUID();
|
||||
|
||||
return luidDummy;
|
||||
}
|
||||
var luid = forwardRow.InterfaceLuid;
|
||||
|
||||
var macAddressBytes = macAddress.GetAddressBytes();
|
||||
var bytes = new byte[32];
|
||||
|
||||
macAddressBytes.CopyTo(bytes, 0);
|
||||
|
||||
var row = new MIB_IPNET_ROW2
|
||||
{
|
||||
Address = address,
|
||||
InterfaceLuid = luid,
|
||||
PhysicalAddress = bytes,
|
||||
PhysicalAddressLength = 6
|
||||
};
|
||||
|
||||
result = CreateIpNetEntry2(ref row);
|
||||
|
||||
if (result != Win32Error.ERROR_SUCCESS)
|
||||
{
|
||||
Logger.Debug($"Cannot create ip net entry: {result}");
|
||||
}
|
||||
|
||||
return luid;
|
||||
}
|
||||
|
||||
private static void DeleteNetEntry(NET_LUID luid, IPAddress ipAddress)
|
||||
{
|
||||
if (luid.Value == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var ipBytes = ipAddress.GetAddressBytes();
|
||||
|
||||
var address = new Ws2_32.SOCKADDR_INET
|
||||
{
|
||||
si_family = Ws2_32.ADDRESS_FAMILY.AF_INET,
|
||||
Ipv4 = new Ws2_32.SOCKADDR_IN(new Ws2_32.IN_ADDR(ipBytes), DefaultWolPort)
|
||||
|
||||
};
|
||||
|
||||
var row = new MIB_IPNET_ROW2
|
||||
{
|
||||
Address = address,
|
||||
InterfaceLuid = luid,
|
||||
};
|
||||
|
||||
var result = DeleteIpNetEntry2(ref row);
|
||||
|
||||
if (result != Win32Error.ERROR_SUCCESS)
|
||||
{
|
||||
Logger.Debug($"Cannot delete ip net entry: {result}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
public enum ElevationMethod
|
||||
{
|
||||
None = 0,
|
||||
RunAsAdmin = 1,
|
||||
UseService = 2,
|
||||
UseElevatedProcess = 3
|
||||
}
|
||||
|
||||
public class ListViewSortState
|
||||
{
|
||||
public SortOrder SortOrder { get; set; }
|
||||
@@ -31,6 +39,8 @@ namespace ColorControl
|
||||
public string LgQuickAccessShortcut { get; set; }
|
||||
public string GameQuickAccessShortcut { get; set; }
|
||||
public bool UseDedicatedElevatedProcess { get; set; }
|
||||
public ElevationMethod ElevationMethod { get; set; }
|
||||
public bool ElevationMethodAsked { get; set; }
|
||||
|
||||
public Config()
|
||||
{
|
||||
@@ -43,6 +53,8 @@ namespace ColorControl
|
||||
FixChromeFonts = false;
|
||||
UseGdiScaling = true;
|
||||
UseDedicatedElevatedProcess = false;
|
||||
ElevationMethod = ElevationMethod.None;
|
||||
ElevationMethodAsked = false;
|
||||
LgPresetsSortState = new ListViewSortState();
|
||||
NvPresetsSortState = new ListViewSortState();
|
||||
AmdPresetsSortState = new ListViewSortState();
|
||||
|
||||
@@ -49,7 +49,7 @@ namespace ColorControl.Forms
|
||||
var container = (WinApi.COPYDATASTRUCT)m.GetLParam(typeof(WinApi.COPYDATASTRUCT));
|
||||
var message = Marshal.PtrToStringAnsi(container.lpData);
|
||||
|
||||
File.AppendAllLines("d:\\Msg.txt", new[] { "Message received: " + message });
|
||||
//File.AppendAllLines("d:\\Msg.txt", new[] { "Message received: " + message });
|
||||
|
||||
HandleMessage(message);
|
||||
|
||||
@@ -69,7 +69,14 @@ namespace ColorControl.Forms
|
||||
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
Program.HandleStartupParams(startUpParams, null);
|
||||
try
|
||||
{
|
||||
Program.HandleStartupParams(startUpParams, null);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckMutexAsync()
|
||||
|
||||
Generated
+155
-33
@@ -231,6 +231,13 @@
|
||||
this.edtDelayDisplaySettings = new System.Windows.Forms.NumericUpDown();
|
||||
this.label6 = new System.Windows.Forms.Label();
|
||||
this.grpGeneralOptions = new System.Windows.Forms.GroupBox();
|
||||
this.btnStartStopService = new System.Windows.Forms.Button();
|
||||
this.btnElevationInfo = new System.Windows.Forms.Button();
|
||||
this.rbElevationService = new System.Windows.Forms.RadioButton();
|
||||
this.rbElevationProcess = new System.Windows.Forms.RadioButton();
|
||||
this.rbElevationAdmin = new System.Windows.Forms.RadioButton();
|
||||
this.label8 = new System.Windows.Forms.Label();
|
||||
this.rbElevationNone = new System.Windows.Forms.RadioButton();
|
||||
this.chkGdiScaling = new System.Windows.Forms.CheckBox();
|
||||
this.chkCheckForUpdates = new System.Windows.Forms.CheckBox();
|
||||
this.chkMinimizeToSystemTray = new System.Windows.Forms.CheckBox();
|
||||
@@ -238,6 +245,8 @@
|
||||
this.chkStartMinimized = new System.Windows.Forms.CheckBox();
|
||||
this.chkStartAfterLogin = new System.Windows.Forms.CheckBox();
|
||||
this.tabLog = new System.Windows.Forms.TabPage();
|
||||
this.lblShowLog = new System.Windows.Forms.Label();
|
||||
this.cbxLogType = new System.Windows.Forms.ComboBox();
|
||||
this.btnClearLog = new System.Windows.Forms.Button();
|
||||
this.edtLog = new System.Windows.Forms.TextBox();
|
||||
this.tabInfo = new System.Windows.Forms.TabPage();
|
||||
@@ -251,7 +260,6 @@
|
||||
this.mnuNvSettings = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.miNvProfileInspector = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.miNvSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.chkOptionsDedicatedElevatedProcess = new System.Windows.Forms.CheckBox();
|
||||
this.tcMain.SuspendLayout();
|
||||
this.tabNVIDIA.SuspendLayout();
|
||||
this.mnuNvPresets.SuspendLayout();
|
||||
@@ -2237,11 +2245,11 @@
|
||||
this.grpNvidiaOptions.Controls.Add(this.cbxDitheringBitDepth);
|
||||
this.grpNvidiaOptions.Controls.Add(this.chkDitheringEnabled);
|
||||
this.grpNvidiaOptions.Controls.Add(this.pbGradient);
|
||||
this.grpNvidiaOptions.Location = new System.Drawing.Point(481, 7);
|
||||
this.grpNvidiaOptions.Location = new System.Drawing.Point(537, 7);
|
||||
this.grpNvidiaOptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpNvidiaOptions.Name = "grpNvidiaOptions";
|
||||
this.grpNvidiaOptions.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpNvidiaOptions.Size = new System.Drawing.Size(625, 351);
|
||||
this.grpNvidiaOptions.Size = new System.Drawing.Size(569, 351);
|
||||
this.grpNvidiaOptions.TabIndex = 6;
|
||||
this.grpNvidiaOptions.TabStop = false;
|
||||
this.grpNvidiaOptions.Text = "NVIDIA options - test dithering";
|
||||
@@ -2312,7 +2320,7 @@
|
||||
this.pbGradient.Location = new System.Drawing.Point(7, 106);
|
||||
this.pbGradient.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.pbGradient.Name = "pbGradient";
|
||||
this.pbGradient.Size = new System.Drawing.Size(611, 236);
|
||||
this.pbGradient.Size = new System.Drawing.Size(555, 236);
|
||||
this.pbGradient.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.pbGradient.TabIndex = 0;
|
||||
this.pbGradient.TabStop = false;
|
||||
@@ -2324,11 +2332,11 @@
|
||||
this.grpMiscellaneousOptions.Controls.Add(this.edtBlankScreenSaverShortcut);
|
||||
this.grpMiscellaneousOptions.Controls.Add(this.lblFixChromeFontsDescription);
|
||||
this.grpMiscellaneousOptions.Controls.Add(this.chkFixChromeFonts);
|
||||
this.grpMiscellaneousOptions.Location = new System.Drawing.Point(7, 332);
|
||||
this.grpMiscellaneousOptions.Location = new System.Drawing.Point(7, 365);
|
||||
this.grpMiscellaneousOptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpMiscellaneousOptions.Name = "grpMiscellaneousOptions";
|
||||
this.grpMiscellaneousOptions.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpMiscellaneousOptions.Size = new System.Drawing.Size(467, 150);
|
||||
this.grpMiscellaneousOptions.Size = new System.Drawing.Size(522, 150);
|
||||
this.grpMiscellaneousOptions.TabIndex = 5;
|
||||
this.grpMiscellaneousOptions.TabStop = false;
|
||||
this.grpMiscellaneousOptions.Text = "Miscellaneous";
|
||||
@@ -2399,11 +2407,11 @@
|
||||
this.grpLGOptions.Controls.Add(this.lblLgMaxPowerOnRetriesDescription);
|
||||
this.grpLGOptions.Controls.Add(this.edtLgMaxPowerOnRetries);
|
||||
this.grpLGOptions.Controls.Add(this.lblLgMaxPowerOnRetries);
|
||||
this.grpLGOptions.Location = new System.Drawing.Point(7, 136);
|
||||
this.grpLGOptions.Location = new System.Drawing.Point(7, 169);
|
||||
this.grpLGOptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpLGOptions.Name = "grpLGOptions";
|
||||
this.grpLGOptions.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpLGOptions.Size = new System.Drawing.Size(470, 190);
|
||||
this.grpLGOptions.Size = new System.Drawing.Size(522, 190);
|
||||
this.grpLGOptions.TabIndex = 4;
|
||||
this.grpLGOptions.TabStop = false;
|
||||
this.grpLGOptions.Text = "LG controller";
|
||||
@@ -2411,7 +2419,7 @@
|
||||
// lblGameBarShortcut
|
||||
//
|
||||
this.lblGameBarShortcut.AutoSize = true;
|
||||
this.lblGameBarShortcut.Location = new System.Drawing.Point(201, 127);
|
||||
this.lblGameBarShortcut.Location = new System.Drawing.Point(266, 127);
|
||||
this.lblGameBarShortcut.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblGameBarShortcut.Name = "lblGameBarShortcut";
|
||||
this.lblGameBarShortcut.Size = new System.Drawing.Size(108, 15);
|
||||
@@ -2420,7 +2428,7 @@
|
||||
//
|
||||
// edtLgGameBarShortcut
|
||||
//
|
||||
this.edtLgGameBarShortcut.Location = new System.Drawing.Point(307, 121);
|
||||
this.edtLgGameBarShortcut.Location = new System.Drawing.Point(386, 121);
|
||||
this.edtLgGameBarShortcut.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgGameBarShortcut.Name = "edtLgGameBarShortcut";
|
||||
this.edtLgGameBarShortcut.ReadOnly = true;
|
||||
@@ -2447,7 +2455,7 @@
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.edtLgOptionShutdownDelay.Location = new System.Drawing.Point(349, 68);
|
||||
this.edtLgOptionShutdownDelay.Location = new System.Drawing.Point(428, 68);
|
||||
this.edtLgOptionShutdownDelay.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgOptionShutdownDelay.Maximum = new decimal(new int[] {
|
||||
5000,
|
||||
@@ -2507,7 +2515,7 @@
|
||||
//
|
||||
// edtLgMaxPowerOnRetries
|
||||
//
|
||||
this.edtLgMaxPowerOnRetries.Location = new System.Drawing.Point(349, 20);
|
||||
this.edtLgMaxPowerOnRetries.Location = new System.Drawing.Point(428, 20);
|
||||
this.edtLgMaxPowerOnRetries.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.edtLgMaxPowerOnRetries.Maximum = new decimal(new int[] {
|
||||
25,
|
||||
@@ -2535,11 +2543,11 @@
|
||||
//
|
||||
this.grpHDROptions.Controls.Add(this.edtDelayDisplaySettings);
|
||||
this.grpHDROptions.Controls.Add(this.label6);
|
||||
this.grpHDROptions.Location = new System.Drawing.Point(481, 365);
|
||||
this.grpHDROptions.Location = new System.Drawing.Point(537, 365);
|
||||
this.grpHDROptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpHDROptions.Name = "grpHDROptions";
|
||||
this.grpHDROptions.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpHDROptions.Size = new System.Drawing.Size(467, 83);
|
||||
this.grpHDROptions.Size = new System.Drawing.Size(569, 83);
|
||||
this.grpHDROptions.TabIndex = 3;
|
||||
this.grpHDROptions.TabStop = false;
|
||||
this.grpHDROptions.Text = "HDR";
|
||||
@@ -2578,7 +2586,13 @@
|
||||
//
|
||||
// grpGeneralOptions
|
||||
//
|
||||
this.grpGeneralOptions.Controls.Add(this.chkOptionsDedicatedElevatedProcess);
|
||||
this.grpGeneralOptions.Controls.Add(this.btnStartStopService);
|
||||
this.grpGeneralOptions.Controls.Add(this.btnElevationInfo);
|
||||
this.grpGeneralOptions.Controls.Add(this.rbElevationService);
|
||||
this.grpGeneralOptions.Controls.Add(this.rbElevationProcess);
|
||||
this.grpGeneralOptions.Controls.Add(this.rbElevationAdmin);
|
||||
this.grpGeneralOptions.Controls.Add(this.label8);
|
||||
this.grpGeneralOptions.Controls.Add(this.rbElevationNone);
|
||||
this.grpGeneralOptions.Controls.Add(this.chkGdiScaling);
|
||||
this.grpGeneralOptions.Controls.Add(this.chkCheckForUpdates);
|
||||
this.grpGeneralOptions.Controls.Add(this.chkMinimizeToSystemTray);
|
||||
@@ -2589,15 +2603,101 @@
|
||||
this.grpGeneralOptions.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpGeneralOptions.Name = "grpGeneralOptions";
|
||||
this.grpGeneralOptions.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.grpGeneralOptions.Size = new System.Drawing.Size(467, 122);
|
||||
this.grpGeneralOptions.Size = new System.Drawing.Size(522, 156);
|
||||
this.grpGeneralOptions.TabIndex = 2;
|
||||
this.grpGeneralOptions.TabStop = false;
|
||||
this.grpGeneralOptions.Text = "General";
|
||||
//
|
||||
// btnStartStopService
|
||||
//
|
||||
this.btnStartStopService.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnStartStopService.Location = new System.Drawing.Point(474, 103);
|
||||
this.btnStartStopService.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnStartStopService.Name = "btnStartStopService";
|
||||
this.btnStartStopService.Size = new System.Drawing.Size(40, 27);
|
||||
this.btnStartStopService.TabIndex = 65;
|
||||
this.btnStartStopService.Text = "Start";
|
||||
this.btnStartStopService.UseVisualStyleBackColor = true;
|
||||
this.btnStartStopService.Click += new System.EventHandler(this.btnStartStopService_Click);
|
||||
//
|
||||
// btnElevationInfo
|
||||
//
|
||||
this.btnElevationInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnElevationInfo.Location = new System.Drawing.Point(329, 41);
|
||||
this.btnElevationInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnElevationInfo.Name = "btnElevationInfo";
|
||||
this.btnElevationInfo.Size = new System.Drawing.Size(22, 27);
|
||||
this.btnElevationInfo.TabIndex = 64;
|
||||
this.btnElevationInfo.Text = "?";
|
||||
this.btnElevationInfo.UseVisualStyleBackColor = true;
|
||||
this.btnElevationInfo.Click += new System.EventHandler(this.btnElevationInfo_Click);
|
||||
//
|
||||
// rbElevationService
|
||||
//
|
||||
this.rbElevationService.AutoSize = true;
|
||||
this.rbElevationService.Location = new System.Drawing.Point(216, 107);
|
||||
this.rbElevationService.Name = "rbElevationService";
|
||||
this.rbElevationService.Size = new System.Drawing.Size(136, 19);
|
||||
this.rbElevationService.TabIndex = 63;
|
||||
this.rbElevationService.TabStop = true;
|
||||
this.rbElevationService.Tag = "2";
|
||||
this.rbElevationService.Text = "Use Windows Service";
|
||||
this.rbElevationService.UseVisualStyleBackColor = true;
|
||||
this.rbElevationService.CheckedChanged += new System.EventHandler(this.rbElevationNone_CheckedChanged);
|
||||
//
|
||||
// rbElevationProcess
|
||||
//
|
||||
this.rbElevationProcess.AutoSize = true;
|
||||
this.rbElevationProcess.Location = new System.Drawing.Point(216, 128);
|
||||
this.rbElevationProcess.Name = "rbElevationProcess";
|
||||
this.rbElevationProcess.Size = new System.Drawing.Size(189, 19);
|
||||
this.rbElevationProcess.TabIndex = 62;
|
||||
this.rbElevationProcess.TabStop = true;
|
||||
this.rbElevationProcess.Tag = "3";
|
||||
this.rbElevationProcess.Text = "Use dedicated elevated process";
|
||||
this.rbElevationProcess.UseVisualStyleBackColor = true;
|
||||
this.rbElevationProcess.CheckedChanged += new System.EventHandler(this.rbElevationNone_CheckedChanged);
|
||||
//
|
||||
// rbElevationAdmin
|
||||
//
|
||||
this.rbElevationAdmin.AutoSize = true;
|
||||
this.rbElevationAdmin.Location = new System.Drawing.Point(216, 86);
|
||||
this.rbElevationAdmin.Name = "rbElevationAdmin";
|
||||
this.rbElevationAdmin.Size = new System.Drawing.Size(97, 19);
|
||||
this.rbElevationAdmin.TabIndex = 61;
|
||||
this.rbElevationAdmin.TabStop = true;
|
||||
this.rbElevationAdmin.Tag = "1";
|
||||
this.rbElevationAdmin.Text = "Run as admin";
|
||||
this.rbElevationAdmin.UseVisualStyleBackColor = true;
|
||||
this.rbElevationAdmin.CheckedChanged += new System.EventHandler(this.rbElevationNone_CheckedChanged);
|
||||
//
|
||||
// label8
|
||||
//
|
||||
this.label8.AutoSize = true;
|
||||
this.label8.Location = new System.Drawing.Point(216, 47);
|
||||
this.label8.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.label8.Name = "label8";
|
||||
this.label8.Size = new System.Drawing.Size(105, 15);
|
||||
this.label8.TabIndex = 60;
|
||||
this.label8.Text = "Elevation-method:";
|
||||
//
|
||||
// rbElevationNone
|
||||
//
|
||||
this.rbElevationNone.AutoSize = true;
|
||||
this.rbElevationNone.Location = new System.Drawing.Point(216, 65);
|
||||
this.rbElevationNone.Name = "rbElevationNone";
|
||||
this.rbElevationNone.Size = new System.Drawing.Size(54, 19);
|
||||
this.rbElevationNone.TabIndex = 10;
|
||||
this.rbElevationNone.TabStop = true;
|
||||
this.rbElevationNone.Tag = "0";
|
||||
this.rbElevationNone.Text = "None";
|
||||
this.rbElevationNone.UseVisualStyleBackColor = true;
|
||||
this.rbElevationNone.CheckedChanged += new System.EventHandler(this.rbElevationNone_CheckedChanged);
|
||||
//
|
||||
// chkGdiScaling
|
||||
//
|
||||
this.chkGdiScaling.AutoSize = true;
|
||||
this.chkGdiScaling.Location = new System.Drawing.Point(238, 72);
|
||||
this.chkGdiScaling.Location = new System.Drawing.Point(216, 22);
|
||||
this.chkGdiScaling.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.chkGdiScaling.Name = "chkGdiScaling";
|
||||
this.chkGdiScaling.Size = new System.Drawing.Size(197, 19);
|
||||
@@ -2609,7 +2709,7 @@
|
||||
// chkCheckForUpdates
|
||||
//
|
||||
this.chkCheckForUpdates.AutoSize = true;
|
||||
this.chkCheckForUpdates.Location = new System.Drawing.Point(238, 47);
|
||||
this.chkCheckForUpdates.Location = new System.Drawing.Point(7, 122);
|
||||
this.chkCheckForUpdates.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.chkCheckForUpdates.Name = "chkCheckForUpdates";
|
||||
this.chkCheckForUpdates.Size = new System.Drawing.Size(197, 19);
|
||||
@@ -2621,7 +2721,7 @@
|
||||
// chkMinimizeToSystemTray
|
||||
//
|
||||
this.chkMinimizeToSystemTray.AutoSize = true;
|
||||
this.chkMinimizeToSystemTray.Location = new System.Drawing.Point(238, 22);
|
||||
this.chkMinimizeToSystemTray.Location = new System.Drawing.Point(7, 97);
|
||||
this.chkMinimizeToSystemTray.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.chkMinimizeToSystemTray.Name = "chkMinimizeToSystemTray";
|
||||
this.chkMinimizeToSystemTray.Size = new System.Drawing.Size(152, 19);
|
||||
@@ -2667,6 +2767,8 @@
|
||||
//
|
||||
// tabLog
|
||||
//
|
||||
this.tabLog.Controls.Add(this.lblShowLog);
|
||||
this.tabLog.Controls.Add(this.cbxLogType);
|
||||
this.tabLog.Controls.Add(this.btnClearLog);
|
||||
this.tabLog.Controls.Add(this.edtLog);
|
||||
this.tabLog.Location = new System.Drawing.Point(4, 24);
|
||||
@@ -2678,9 +2780,33 @@
|
||||
this.tabLog.Text = "Log";
|
||||
this.tabLog.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// lblShowLog
|
||||
//
|
||||
this.lblShowLog.AutoSize = true;
|
||||
this.lblShowLog.Location = new System.Drawing.Point(8, 14);
|
||||
this.lblShowLog.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0);
|
||||
this.lblShowLog.Name = "lblShowLog";
|
||||
this.lblShowLog.Size = new System.Drawing.Size(88, 15);
|
||||
this.lblShowLog.TabIndex = 33;
|
||||
this.lblShowLog.Text = "Show log from:";
|
||||
//
|
||||
// cbxLogType
|
||||
//
|
||||
this.cbxLogType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cbxLogType.FormattingEnabled = true;
|
||||
this.cbxLogType.Items.AddRange(new object[] {
|
||||
"Main application",
|
||||
"Service"});
|
||||
this.cbxLogType.Location = new System.Drawing.Point(102, 9);
|
||||
this.cbxLogType.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.cbxLogType.Name = "cbxLogType";
|
||||
this.cbxLogType.Size = new System.Drawing.Size(189, 23);
|
||||
this.cbxLogType.TabIndex = 32;
|
||||
this.cbxLogType.SelectedIndexChanged += new System.EventHandler(this.cbxLogType_SelectedIndexChanged);
|
||||
//
|
||||
// btnClearLog
|
||||
//
|
||||
this.btnClearLog.Location = new System.Drawing.Point(7, 7);
|
||||
this.btnClearLog.Location = new System.Drawing.Point(299, 6);
|
||||
this.btnClearLog.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.btnClearLog.Name = "btnClearLog";
|
||||
this.btnClearLog.Size = new System.Drawing.Size(88, 27);
|
||||
@@ -2824,18 +2950,6 @@
|
||||
this.miNvSettings.Text = "Settings";
|
||||
this.miNvSettings.Click += new System.EventHandler(this.miNvSettings_Click);
|
||||
//
|
||||
// chkOptionsDedicatedElevatedProcess
|
||||
//
|
||||
this.chkOptionsDedicatedElevatedProcess.AutoSize = true;
|
||||
this.chkOptionsDedicatedElevatedProcess.Location = new System.Drawing.Point(7, 97);
|
||||
this.chkOptionsDedicatedElevatedProcess.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
this.chkOptionsDedicatedElevatedProcess.Name = "chkOptionsDedicatedElevatedProcess";
|
||||
this.chkOptionsDedicatedElevatedProcess.Size = new System.Drawing.Size(190, 19);
|
||||
this.chkOptionsDedicatedElevatedProcess.TabIndex = 8;
|
||||
this.chkOptionsDedicatedElevatedProcess.Text = "Use dedicated elevated process";
|
||||
this.chkOptionsDedicatedElevatedProcess.UseVisualStyleBackColor = true;
|
||||
this.chkOptionsDedicatedElevatedProcess.CheckedChanged += new System.EventHandler(this.chkOptionsDedicatedElevatedProcess_CheckedChanged);
|
||||
//
|
||||
// MainForm
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
@@ -3124,7 +3238,15 @@
|
||||
private System.Windows.Forms.ContextMenuStrip mnuGameOptions;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameProcessorAffinity;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameProcessPriority;
|
||||
private System.Windows.Forms.CheckBox chkOptionsDedicatedElevatedProcess;
|
||||
private System.Windows.Forms.RadioButton rbElevationService;
|
||||
private System.Windows.Forms.RadioButton rbElevationProcess;
|
||||
private System.Windows.Forms.RadioButton rbElevationAdmin;
|
||||
private System.Windows.Forms.Label label8;
|
||||
private System.Windows.Forms.RadioButton rbElevationNone;
|
||||
private System.Windows.Forms.Button btnElevationInfo;
|
||||
private System.Windows.Forms.Button btnStartStopService;
|
||||
private System.Windows.Forms.Label lblShowLog;
|
||||
private System.Windows.Forms.ComboBox cbxLogType;
|
||||
}
|
||||
}
|
||||
|
||||
+293
-47
@@ -7,8 +7,8 @@ using ColorControl.Services.Common;
|
||||
using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Svc;
|
||||
using LgTv;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using nspector;
|
||||
using nspector.Common;
|
||||
@@ -28,7 +28,6 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@@ -77,7 +76,6 @@ namespace ColorControl
|
||||
private bool _updatingDitherSettings;
|
||||
|
||||
private LgGameBar _gameBarForm;
|
||||
private QuickAccessForm<GamePreset> _gameQuickAccessForm;
|
||||
|
||||
private GameService _gameService;
|
||||
|
||||
@@ -125,7 +123,7 @@ namespace ColorControl
|
||||
_trayIcon.ContextMenuStrip.Opened += trayIconContextMenu_Popup;
|
||||
_trayIcon.BalloonTipClicked += trayIconBalloonTip_Clicked;
|
||||
|
||||
chkStartAfterLogin.Checked = Utils.TaskExists(Program.TS_TASKNAME, true);
|
||||
chkStartAfterLogin.Checked = Utils.TaskExists(Program.TS_TASKNAME);
|
||||
|
||||
chkFixChromeFonts.Enabled = Utils.IsChromeInstalled();
|
||||
if (chkFixChromeFonts.Enabled)
|
||||
@@ -140,12 +138,15 @@ namespace ColorControl
|
||||
|
||||
_shortcuts.Add(SHORTCUTID_SCREENSAVER, StartScreenSaver);
|
||||
|
||||
//Utils.StartService();
|
||||
|
||||
InitLgService();
|
||||
InitNvService();
|
||||
InitAmdService();
|
||||
InitGameService();
|
||||
|
||||
InitInfo();
|
||||
UpdateServiceInfo();
|
||||
|
||||
UserSessionInfo.Install();
|
||||
_screenStateNotify = WinApi.RegisterPowerSettingNotification(Handle, ref Utils.GUID_CONSOLE_DISPLAY_STATE, 0);
|
||||
@@ -154,9 +155,36 @@ namespace ColorControl
|
||||
|
||||
_initialized = true;
|
||||
|
||||
//Task.Run(() => Utils.StartPipeAsync());
|
||||
|
||||
AfterInitialized();
|
||||
}
|
||||
|
||||
private void UpdateServiceInfo()
|
||||
{
|
||||
var text = "Use Windows Service";
|
||||
btnStartStopService.Enabled = true;
|
||||
|
||||
if (Utils.IsServiceRunning())
|
||||
{
|
||||
text += " (running)";
|
||||
btnStartStopService.Text = "Stop";
|
||||
}
|
||||
else if (Utils.IsServiceInstalled())
|
||||
{
|
||||
text += " (installed, not running)";
|
||||
btnStartStopService.Text = "Start";
|
||||
}
|
||||
else
|
||||
{
|
||||
text += " (not installed)";
|
||||
btnStartStopService.Text = "Start";
|
||||
btnStartStopService.Enabled = false;
|
||||
}
|
||||
|
||||
rbElevationService.Text = text;
|
||||
}
|
||||
|
||||
private void InitNvService()
|
||||
{
|
||||
try
|
||||
@@ -361,6 +389,11 @@ namespace ColorControl
|
||||
Text = Application.ProductName + " " + Application.ProductVersion;
|
||||
//}
|
||||
|
||||
if (Utils.IsAdministrator())
|
||||
{
|
||||
Text += " (administrator)";
|
||||
}
|
||||
|
||||
lblInfo.Text = Text + " - " + _currentVersionInfo.LegalCopyright;
|
||||
|
||||
lbPlugins.Items.Add("lgtv.net by gr4b4z");
|
||||
@@ -817,7 +850,13 @@ namespace ColorControl
|
||||
return;
|
||||
}
|
||||
var enabled = chkStartAfterLogin.Checked;
|
||||
Utils.RegisterTask(Program.TS_TASKNAME, enabled);
|
||||
RegisterScheduledTask(enabled);
|
||||
|
||||
rbElevationAdmin.Enabled = enabled;
|
||||
if (!enabled && rbElevationAdmin.Checked)
|
||||
{
|
||||
rbElevationNone.Checked = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadConfig()
|
||||
@@ -829,7 +868,6 @@ namespace ColorControl
|
||||
edtDelayDisplaySettings.Value = _config.DisplaySettingsDelay;
|
||||
edtBlankScreenSaverShortcut.Text = _config.ScreenSaverShortcut;
|
||||
chkGdiScaling.Checked = _config.UseGdiScaling;
|
||||
chkOptionsDedicatedElevatedProcess.Checked = _config.UseDedicatedElevatedProcess;
|
||||
|
||||
if (!string.IsNullOrEmpty(_config.ScreenSaverShortcut))
|
||||
{
|
||||
@@ -857,15 +895,7 @@ namespace ColorControl
|
||||
_config.FormHeight = Height;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var data = JsonConvert.SerializeObject(_config);
|
||||
File.WriteAllText(Program.ConfigFilename, data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
Utils.WriteObject(Program.ConfigFilename, _config);
|
||||
}
|
||||
|
||||
private void ShowControls(Control parent, bool show = true, Control exclude = null)
|
||||
@@ -907,6 +937,44 @@ namespace ColorControl
|
||||
|
||||
InitSelectedTab();
|
||||
CheckForUpdates();
|
||||
|
||||
CheckElevationMethod();
|
||||
}
|
||||
|
||||
private void CheckElevationMethod()
|
||||
{
|
||||
if (Utils.IsAdministrator())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_config.ElevationMethodAsked)
|
||||
{
|
||||
if (_config.ElevationMethod == ElevationMethod.UseService && !Utils.IsServiceInstalled() &&
|
||||
(MessageForms.QuestionYesNo("The elevation method is set to Windows Service but it is not installed. Do you want to install it now?") == DialogResult.Yes))
|
||||
{
|
||||
Utils.InstallService();
|
||||
}
|
||||
else if (_config.ElevationMethod == ElevationMethod.UseService && !Utils.IsServiceRunning() &&
|
||||
(MessageForms.QuestionYesNo("The elevation method is set to Windows Service but it is not running. Do you want to start it now?") == DialogResult.Yes))
|
||||
{
|
||||
Utils.StartService();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var result = MessageForms.QuestionYesNo(Utils.ELEVATION_MSG + @"
|
||||
|
||||
Do you want to install and start the Windows Service now? You can always change this on the Options-tab page.
|
||||
|
||||
NOTE: installing the service may cause a User Account Control popup.");
|
||||
if (result == DialogResult.Yes)
|
||||
{
|
||||
SetElevationMethod(ElevationMethod.UseService);
|
||||
}
|
||||
|
||||
_config.ElevationMethodAsked = true;
|
||||
}
|
||||
|
||||
protected override void SetVisibleCore(bool value)
|
||||
@@ -1692,6 +1760,24 @@ namespace ColorControl
|
||||
|
||||
UpdateDitherSettings();
|
||||
}
|
||||
|
||||
_initialized = false;
|
||||
try
|
||||
{
|
||||
var _ = _config.ElevationMethod switch
|
||||
{
|
||||
ElevationMethod.None => rbElevationNone.Checked = true,
|
||||
ElevationMethod.RunAsAdmin => rbElevationAdmin.Checked = true,
|
||||
ElevationMethod.UseService => rbElevationService.Checked = true,
|
||||
ElevationMethod.UseElevatedProcess => rbElevationProcess.Checked = true
|
||||
};
|
||||
}
|
||||
finally
|
||||
{
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
UpdateServiceInfo();
|
||||
}
|
||||
|
||||
private void UpdateDitherSettings()
|
||||
@@ -2059,36 +2145,44 @@ namespace ColorControl
|
||||
|
||||
private void LoadLog()
|
||||
{
|
||||
var filename = Path.Combine(_dataDir, "LogFile.txt");
|
||||
var logType = cbxLogType.SelectedIndex;
|
||||
|
||||
var lines = new List<string> { "No log file found" };
|
||||
|
||||
try
|
||||
if (logType == -1)
|
||||
{
|
||||
if (File.Exists(filename))
|
||||
cbxLogType.SelectedIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
string text;
|
||||
|
||||
if (logType == 0)
|
||||
{
|
||||
var filename = Path.Combine(_dataDir, "LogFile.txt");
|
||||
|
||||
text = Utils.ReadText(filename);
|
||||
|
||||
text ??= "No log file found";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Utils.IsServiceRunning())
|
||||
{
|
||||
using var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
var message = new SvcMessage { MessageType = SvcMessageType.GetLog };
|
||||
|
||||
using var reader = new StreamReader(fs);
|
||||
var result = PipeUtils.SendMessage(message);
|
||||
|
||||
String line;
|
||||
|
||||
while ((line = reader.ReadLine()) != null)
|
||||
{
|
||||
lines.Add(line);
|
||||
}
|
||||
|
||||
//lines = File.ReadAllLines(filename);
|
||||
text = result?.Data ?? "Cannot get log from service";
|
||||
}
|
||||
else
|
||||
{
|
||||
text = "The service is not installed or not running";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lines = new List<string> { $"Cannot load log file: {ex.Message}" };
|
||||
}
|
||||
var reversedLines = lines.ToList();
|
||||
var builder = new StringBuilder();
|
||||
reversedLines.ForEach(line => builder.AppendLine(line));
|
||||
edtLog.Text = builder.ToString();
|
||||
|
||||
edtLog.Text = text;
|
||||
|
||||
edtLog.SelectionStart = text.Length;
|
||||
edtLog.ScrollToCaret();
|
||||
}
|
||||
|
||||
private void LoadInfo()
|
||||
@@ -2401,12 +2495,26 @@ Do you want to continue?";
|
||||
|
||||
private void btnClearLog_Click(object sender, EventArgs e)
|
||||
{
|
||||
var filename = Path.Combine(_dataDir, "LogFile.txt");
|
||||
if (File.Exists(filename))
|
||||
var logType = cbxLogType.SelectedIndex;
|
||||
|
||||
if (logType == -1)
|
||||
{
|
||||
File.Delete(filename);
|
||||
edtLog.Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (logType == 0)
|
||||
{
|
||||
var filename = Program.LogFilename;
|
||||
if (File.Exists(filename))
|
||||
{
|
||||
File.Delete(filename);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PipeUtils.SendMessage(SvcMessageType.ClearLog);
|
||||
}
|
||||
edtLog.Clear();
|
||||
}
|
||||
|
||||
private void edtLgDeviceFilter_TextChanged(object sender, EventArgs e)
|
||||
@@ -3652,7 +3760,8 @@ The InStart and Software Update items are now visible under the Expert-button."
|
||||
|
||||
var fileName = Path.GetFileNameWithoutExtension(preset.Path);
|
||||
|
||||
preset.name = versionInfo.FileDescription ?? versionInfo.ProductName ?? fileName;
|
||||
preset.name = !string.IsNullOrEmpty(versionInfo.FileDescription) ? versionInfo.FileDescription :
|
||||
!string.IsNullOrEmpty(versionInfo.ProductName) ? versionInfo.ProductName : fileName;
|
||||
}
|
||||
|
||||
AddOrUpdateItemGame(preset);
|
||||
@@ -4066,13 +4175,150 @@ The InStart and Software Update items are now visible under the Expert-button."
|
||||
var enumValue = Enum.Parse(typeof(GamePriorityClass), value);
|
||||
|
||||
preset.ProcessPriorityClass = (uint)(int)enumValue;
|
||||
|
||||
}
|
||||
|
||||
private void chkOptionsDedicatedElevatedProcess_CheckedChanged(object sender, EventArgs e)
|
||||
private void rbElevationNone_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
_config.UseDedicatedElevatedProcess = chkOptionsDedicatedElevatedProcess.Checked;
|
||||
Utils.UseDedicatedElevatedProcess = _config.UseDedicatedElevatedProcess;
|
||||
if (!_initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (sender is not RadioButton button || !button.Checked)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SetElevationMethod((ElevationMethod)Utils.ParseInt((string)button.Tag));
|
||||
}
|
||||
|
||||
private void SetElevationMethod(ElevationMethod elevationMethod)
|
||||
{
|
||||
_config.ElevationMethod = elevationMethod;
|
||||
|
||||
Utils.UseDedicatedElevatedProcess = _config.ElevationMethod == ElevationMethod.UseElevatedProcess;
|
||||
|
||||
var _ = _config.ElevationMethod switch
|
||||
{
|
||||
ElevationMethod.None => SetElevationMethodNone(),
|
||||
ElevationMethod.RunAsAdmin => SetElevationMethodRunAsAdmin(),
|
||||
ElevationMethod.UseService => SetElevationMethodUseService(),
|
||||
ElevationMethod.UseElevatedProcess => SetElevationMethodUseElevatedProcess(),
|
||||
_ => true
|
||||
};
|
||||
|
||||
UpdateServiceInfo();
|
||||
}
|
||||
|
||||
private bool SetElevationMethodNone()
|
||||
{
|
||||
if (chkStartAfterLogin.Enabled)
|
||||
{
|
||||
RegisterScheduledTask();
|
||||
}
|
||||
|
||||
Utils.UninstallService();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SetElevationMethodRunAsAdmin()
|
||||
{
|
||||
if (chkStartAfterLogin.Enabled)
|
||||
{
|
||||
RegisterScheduledTask(false);
|
||||
RegisterScheduledTask();
|
||||
}
|
||||
|
||||
Utils.UninstallService();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SetElevationMethodUseService()
|
||||
{
|
||||
Utils.InstallService();
|
||||
|
||||
if (Utils.IsServiceInstalled())
|
||||
{
|
||||
MessageForms.InfoOk("Service installed successfully.");
|
||||
return true;
|
||||
}
|
||||
|
||||
MessageForms.ErrorOk("Service could not be installed. Check the logs.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool SetElevationMethodUseElevatedProcess()
|
||||
{
|
||||
if (chkStartAfterLogin.Enabled)
|
||||
{
|
||||
RegisterScheduledTask();
|
||||
}
|
||||
|
||||
Utils.UninstallService();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void RegisterScheduledTask(bool enabled = true)
|
||||
{
|
||||
Utils.RegisterTask(Program.TS_TASKNAME, enabled, _config.ElevationMethod == ElevationMethod.RunAsAdmin ? Microsoft.Win32.TaskScheduler.TaskRunLevel.Highest : Microsoft.Win32.TaskScheduler.TaskRunLevel.LUA);
|
||||
}
|
||||
|
||||
private void btnElevationInfo_Click(object sender, EventArgs e)
|
||||
{
|
||||
MessageForms.InfoOk(Utils.ELEVATION_MSG + @$"
|
||||
|
||||
NOTE: if ColorControl itself already runs as administrator this is indicated in the title: ColorControl {Application.ProductVersion} (administrator).
|
||||
|
||||
Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as administrator.
|
||||
");
|
||||
}
|
||||
|
||||
private void btnStartStopService_Click(object sender, EventArgs e)
|
||||
{
|
||||
btnStartStopService.Enabled = false;
|
||||
try
|
||||
{
|
||||
var start = btnStartStopService.Text == "Start";
|
||||
|
||||
if (start)
|
||||
{
|
||||
Utils.StartService();
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.StopService();
|
||||
}
|
||||
|
||||
var wait = 1000;
|
||||
|
||||
while (wait > 0)
|
||||
{
|
||||
Utils.WaitForTask(Task.Delay(100));
|
||||
|
||||
if (start == Utils.IsServiceRunning())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
wait -= 100;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
btnStartStopService.Enabled = true;
|
||||
}
|
||||
|
||||
UpdateServiceInfo();
|
||||
}
|
||||
|
||||
private void cbxLogType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
LoadLog();
|
||||
}
|
||||
}
|
||||
}
|
||||
+79
-6
@@ -3,13 +3,18 @@ using ColorControl.Forms;
|
||||
using ColorControl.Services.AMD;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Svc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl
|
||||
@@ -19,6 +24,7 @@ namespace ColorControl
|
||||
public const string TS_TASKNAME = "ColorControl";
|
||||
public static string DataDir { get; private set; }
|
||||
public static string ConfigFilename { get; private set; }
|
||||
public static string LogFilename { get; private set; }
|
||||
public static Config Config { get; private set; }
|
||||
public static AppContext AppContext { get; private set; }
|
||||
|
||||
@@ -32,6 +38,20 @@ namespace ColorControl
|
||||
[STAThread]
|
||||
static void Main(string[] args)
|
||||
{
|
||||
DataDir = Utils.GetDataPath();
|
||||
|
||||
var runAsService = args.Contains("--service") || Process.GetCurrentProcess().Parent()?.ProcessName?.Equals("services", StringComparison.InvariantCultureIgnoreCase) == true;
|
||||
|
||||
InitLogger(runAsService);
|
||||
|
||||
Logger.Debug("Parent process: " + Process.GetCurrentProcess().Parent()?.ProcessName);
|
||||
|
||||
if (runAsService)
|
||||
{
|
||||
Utils.WaitForTask(RunService(args));
|
||||
return;
|
||||
}
|
||||
|
||||
MutexId = $"Global\\{typeof(MainForm).GUID}";
|
||||
|
||||
var currentDomain = AppDomain.CurrentDomain;
|
||||
@@ -40,9 +60,6 @@ namespace ColorControl
|
||||
// Handler for exceptions in threads behind forms.
|
||||
Application.ThreadException += GlobalThreadExceptionHandler;
|
||||
|
||||
DataDir = Utils.GetDataPath();
|
||||
InitLogger();
|
||||
|
||||
LoadConfig();
|
||||
|
||||
if (Config.UseGdiScaling)
|
||||
@@ -88,10 +105,19 @@ namespace ColorControl
|
||||
mutex.WaitOne();
|
||||
try
|
||||
{
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Utils.StartService();
|
||||
}
|
||||
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new MainForm(AppContext));
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
Utils.StopService();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -108,12 +134,17 @@ namespace ColorControl
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitLogger()
|
||||
private static void InitLogger(bool runAsService)
|
||||
{
|
||||
var config = new NLog.Config.LoggingConfiguration();
|
||||
|
||||
// Targets where to log to: File and Console
|
||||
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = Path.Combine(DataDir, "LogFile.txt") };
|
||||
var logFileAppendix = runAsService ? "_svc" : "";
|
||||
|
||||
LogFilename = Path.Combine(DataDir, $"LogFile{logFileAppendix}.txt");
|
||||
|
||||
var logfile = new NLog.Targets.FileTarget("logfile") { FileName = LogFilename };
|
||||
|
||||
//var logconsole = new NLog.Targets.ConsoleTarget("logconsole");
|
||||
|
||||
// Rules for mapping loggers to targets
|
||||
@@ -154,7 +185,7 @@ namespace ColorControl
|
||||
}
|
||||
if (startUpParams.EnableAutoStart || startUpParams.DisableAutoStart)
|
||||
{
|
||||
Utils.RegisterTask(TS_TASKNAME, startUpParams.EnableAutoStart);
|
||||
Utils.RegisterTask(TS_TASKNAME, startUpParams.EnableAutoStart, startUpParams.AutoStartRunLevel);
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.SetProcessAffinity)
|
||||
@@ -172,6 +203,30 @@ namespace ColorControl
|
||||
StartElevated();
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.SendWol)
|
||||
{
|
||||
return WOL.WakeFunction(startUpParams.WolMacAddress, startUpParams.WolIpAddress);
|
||||
}
|
||||
if (startUpParams.InstallService)
|
||||
{
|
||||
Utils.InstallService();
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.UninstallService)
|
||||
{
|
||||
Utils.UninstallService();
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.StartService)
|
||||
{
|
||||
Utils.StartService();
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.StopService)
|
||||
{
|
||||
Utils.StopService();
|
||||
return true;
|
||||
}
|
||||
|
||||
var useConsole = startUpParams.NoGui || existingProcess != null;
|
||||
|
||||
@@ -263,6 +318,24 @@ namespace ColorControl
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task RunService(string[] args)
|
||||
{
|
||||
Logger.Debug("RUNNING SERVICE");
|
||||
|
||||
using IHost host = Host.CreateDefaultBuilder(args)
|
||||
.UseWindowsService(options =>
|
||||
{
|
||||
options.ServiceName = "ColorControl Service";
|
||||
})
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services.AddHostedService<ColorControlBackgroundService>();
|
||||
})
|
||||
.Build();
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
public static int EnumThreadWindows(IntPtr handle, IntPtr param)
|
||||
{
|
||||
NativeMethods.SendMessageW(handle, Utils.WM_BRINGTOFRONT, UIntPtr.Zero, IntPtr.Zero);
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using ATI.ADL;
|
||||
using ColorControl.Common;
|
||||
using ColorControl.Services.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
|
||||
@@ -52,15 +50,7 @@ namespace ColorControl.Services.AMD
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_presets);
|
||||
File.WriteAllText(_presetsFilename, json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
public void GlobalSave()
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using ColorControl.Common;
|
||||
using ColorControl.Services.Common;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
@@ -51,15 +49,7 @@ namespace ColorControl.Services.GameLauncher
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_presets);
|
||||
File.WriteAllText(_presetsFilename, json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
public void GlobalSave()
|
||||
|
||||
@@ -759,7 +759,7 @@ namespace ColorControl.Services.LG
|
||||
|
||||
if (MacAddress != null)
|
||||
{
|
||||
result = WOL.WakeFunction(MacAddress);
|
||||
result = WOL.WakeFunctionCheckAdmin(MacAddress, IpAddress);
|
||||
_justWokeUp = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using ColorControl.Common;
|
||||
using ColorControl.Forms;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Svc;
|
||||
using LgTv;
|
||||
using Microsoft.Win32;
|
||||
using Newtonsoft.Json;
|
||||
@@ -127,6 +128,8 @@ namespace ColorControl.Services.LG
|
||||
SaveConfig();
|
||||
SavePresets();
|
||||
SaveRemoteControlButtons();
|
||||
|
||||
SendConfigToService();
|
||||
}
|
||||
|
||||
protected override List<LgPreset> GetDefaultPresets()
|
||||
@@ -257,29 +260,19 @@ namespace ColorControl.Services.LG
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_presets);
|
||||
File.WriteAllText(_presetsFilename, json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
Config.PowerOnAfterStartup = Devices?.Any(d => d.PowerOnAfterStartup) ?? false;
|
||||
|
||||
var json = JsonConvert.SerializeObject(Config);
|
||||
File.WriteAllText(_configFilename, json);
|
||||
Utils.WriteObject(_configFilename, Config);
|
||||
}
|
||||
|
||||
private void SaveRemoteControlButtons()
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_remoteControlButtons);
|
||||
File.WriteAllText(_rcButtonsFilename, json);
|
||||
Utils.WriteObject(_rcButtonsFilename, _remoteControlButtons);
|
||||
}
|
||||
|
||||
public async Task RefreshDevices(bool connect = true, bool afterStartUp = false)
|
||||
@@ -937,5 +930,23 @@ namespace ColorControl.Services.LG
|
||||
Utils.StartProcess(resumeScript, hidden: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendConfigToService()
|
||||
{
|
||||
if (!Utils.IsServiceRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(Config);
|
||||
|
||||
var message = new SvcMessage
|
||||
{
|
||||
MessageType = SvcMessageType.SetLgConfig,
|
||||
Data = json
|
||||
};
|
||||
|
||||
PipeUtils.SendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
using ColorControl.Common;
|
||||
using ColorControl.Services.Common;
|
||||
using Newtonsoft.Json;
|
||||
using nspector.Common;
|
||||
using nspector.Common.Meta;
|
||||
using NvAPIWrapper.Display;
|
||||
@@ -10,7 +9,6 @@ using NWin32.NativeTypes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
@@ -187,15 +185,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
private void SavePresets()
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(_presets);
|
||||
File.WriteAllText(_presetsFilename, json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error(e.ToLogString());
|
||||
}
|
||||
Utils.WriteObject(_presetsFilename, _presets);
|
||||
}
|
||||
|
||||
private void SetCurrentDisplay(NvPreset preset)
|
||||
@@ -509,11 +499,11 @@ namespace ColorControl.Services.NVIDIA
|
||||
return false;
|
||||
}
|
||||
|
||||
var timing = display.DisplayDevice.CurrentTiming;
|
||||
var desktopRect = display.DisplayDevice.ScanOutInformation.SourceDesktopRectangle;
|
||||
|
||||
if (refreshRate == 0)
|
||||
{
|
||||
var timing = display.DisplayDevice.CurrentTiming;
|
||||
refreshRate = (uint)timing.Extra.RefreshRate;
|
||||
}
|
||||
|
||||
@@ -523,11 +513,6 @@ namespace ColorControl.Services.NVIDIA
|
||||
resolutionHeight = (uint)desktopRect.Height;
|
||||
}
|
||||
|
||||
if (timing.Extra.RefreshRate == refreshRate && desktopRect.Width == resolutionWidth && desktopRect.Height == resolutionHeight)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var portrait = new[] { Rotate.Degree90, Rotate.Degree270 }.Contains(display.DisplayDevice.ScanOutInformation.SourceToTargetRotation);
|
||||
|
||||
return SetRefreshRateInternal(display.Name, (int)refreshRate, portrait, (int)resolutionWidth, (int)resolutionHeight, updateRegistry);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
using ColorControl.Common;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace ColorControl
|
||||
{
|
||||
@@ -17,6 +19,11 @@ namespace ColorControl
|
||||
public const string SetProcessAffinityParam = "--set-process-affinity";
|
||||
public const string SetProcessPriorityParam = "--set-process-priority";
|
||||
public const string StartElevatedParam = "--elevated";
|
||||
public const string SendWakeOnLanParam = "--send-wol";
|
||||
public const string InstallServiceParam = "--install-service";
|
||||
public const string UninstallServiceParam = "--uninstall-service";
|
||||
public const string StartServiceParam = "--start-service";
|
||||
public const string StopServiceParam = "--stop-service";
|
||||
|
||||
public bool RunningFromScheduledTask { get; private set; }
|
||||
public bool ActivateChromeFontFix { get; private set; }
|
||||
@@ -30,6 +37,7 @@ namespace ColorControl
|
||||
public string LgPresetName { get; private set; }
|
||||
public bool NoGui { get; set; }
|
||||
public bool EnableAutoStart { get; private set; }
|
||||
public TaskRunLevel AutoStartRunLevel { get; private set; } = TaskRunLevel.LUA;
|
||||
public bool DisableAutoStart { get; private set; }
|
||||
public bool SetProcessAffinity { get; private set; }
|
||||
public int ProcessId { get; private set; }
|
||||
@@ -37,6 +45,13 @@ namespace ColorControl
|
||||
public bool SetProcessPriority { get; private set; }
|
||||
public uint PriorityClass { get; private set; }
|
||||
public bool StartElevated { get; private set; }
|
||||
public bool SendWol { get; private set; }
|
||||
public string WolMacAddress { get; private set; }
|
||||
public string WolIpAddress { get; private set; }
|
||||
public bool InstallService { get; private set; }
|
||||
public bool UninstallService { get; private set; }
|
||||
public bool StartService { get; private set; }
|
||||
public bool StopService { get; private set; }
|
||||
|
||||
public static StartUpParams Parse(IEnumerable<string> args)
|
||||
{
|
||||
@@ -85,6 +100,22 @@ namespace ColorControl
|
||||
settings.PriorityClass = uint.Parse(arg);
|
||||
break;
|
||||
}
|
||||
case SendWakeOnLanParam:
|
||||
{
|
||||
if (settings.WolMacAddress == null)
|
||||
{
|
||||
settings.WolMacAddress = arg;
|
||||
continue;
|
||||
}
|
||||
|
||||
settings.WolIpAddress = arg;
|
||||
break;
|
||||
}
|
||||
case EnableAutoStartParam:
|
||||
{
|
||||
settings.AutoStartRunLevel = (TaskRunLevel)Utils.ParseInt(arg, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parseNameParam = string.Empty;
|
||||
@@ -140,6 +171,7 @@ namespace ColorControl
|
||||
case EnableAutoStartParam:
|
||||
{
|
||||
settings.EnableAutoStart = true;
|
||||
parseNameParam = EnableAutoStartParam;
|
||||
break;
|
||||
}
|
||||
case DisableAutoStartParam:
|
||||
@@ -164,6 +196,32 @@ namespace ColorControl
|
||||
settings.StartElevated = true;
|
||||
break;
|
||||
}
|
||||
case SendWakeOnLanParam:
|
||||
{
|
||||
settings.SendWol = true;
|
||||
parseNameParam = SendWakeOnLanParam;
|
||||
break;
|
||||
}
|
||||
case InstallServiceParam:
|
||||
{
|
||||
settings.InstallService = true;
|
||||
break;
|
||||
}
|
||||
case UninstallServiceParam:
|
||||
{
|
||||
settings.UninstallService = true;
|
||||
break;
|
||||
}
|
||||
case StartServiceParam:
|
||||
{
|
||||
settings.StartService = true;
|
||||
break;
|
||||
}
|
||||
case StopServiceParam:
|
||||
{
|
||||
settings.StopService = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return settings;
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
using ColorControl.Common;
|
||||
using ColorControl.Services.LG;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Svc
|
||||
{
|
||||
public sealed class ColorControlBackgroundService : BackgroundService
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private static string LgConfigFile = "LgConfig.json";
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
LgConfigFile = Path.Combine(Program.DataDir, LgConfigFile);
|
||||
|
||||
//var lgService = new LgService(Program.DataDir, true);
|
||||
//lgService.InstallEventHandlers(true);
|
||||
|
||||
await WakeDevicesAsync();
|
||||
|
||||
var securityIdentifier = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
|
||||
|
||||
var ps = new PipeSecurity();
|
||||
ps.AddAccessRule(new PipeAccessRule(securityIdentifier, PipeAccessRights.ReadWrite, AccessControlType.Allow));
|
||||
|
||||
Logger.Debug("EXECUTING BACKGROUND");
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
Logger.Debug("WAITING FOR MESSAGE...");
|
||||
|
||||
var pipeServer = NamedPipeServerStreamAcl.Create("testpipe", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 1024, 1024, ps);
|
||||
|
||||
await pipeServer.WaitForConnectionAsync(stoppingToken);
|
||||
|
||||
var ss = new StreamString(pipeServer);
|
||||
|
||||
var message = ss.ReadString();
|
||||
|
||||
//Logger.Debug("MESSAGE RECEIVED: " + message);
|
||||
|
||||
try
|
||||
{
|
||||
var result = HandleMessage(message);
|
||||
|
||||
var resultJson = JsonConvert.SerializeObject(result);
|
||||
|
||||
//Logger.Debug("SENDING RESULT: " + resultJson);
|
||||
|
||||
ss.WriteString(resultJson);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"While handling message: {message}");
|
||||
|
||||
var result = SvcResultMessage.FromResult(false, ex.Message);
|
||||
var resultJson = JsonConvert.SerializeObject(result);
|
||||
ss.WriteString(resultJson);
|
||||
}
|
||||
|
||||
pipeServer.Close();
|
||||
//pipeServer.Disconnect();
|
||||
}
|
||||
Logger.Debug("STOPPING...");
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
Logger.Debug("Service stopping");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex, "{Message}", ex.Message);
|
||||
|
||||
// Terminates this process and returns an exit code to the operating system.
|
||||
// This is required to avoid the 'BackgroundServiceExceptionBehavior', which
|
||||
// performs one of two scenarios:
|
||||
// 1. When set to "Ignore": will do nothing at all, errors cause zombie services.
|
||||
// 2. When set to "StopHost": will cleanly stop the host, and log errors.
|
||||
//
|
||||
// In order for the Windows Service Management system to leverage configured
|
||||
// recovery options, we need to terminate the process with a non-zero exit code.
|
||||
//Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleMessage(string json)
|
||||
{
|
||||
var message = JsonConvert.DeserializeObject<SvcMessage>(json);
|
||||
|
||||
var result = message.MessageType switch
|
||||
{
|
||||
SvcMessageType.SetLgConfig => HandleSetLgConfigMessage(message),
|
||||
SvcMessageType.GetLog => HandleGetLogMessage(message),
|
||||
SvcMessageType.ClearLog => HandleClearLogMessage(message),
|
||||
SvcMessageType.ExecuteRpc => HandleExecuteRpcCommand(message)
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleExecuteRpcCommand(SvcMessage message)
|
||||
{
|
||||
var args = message.Data.Split(' ');
|
||||
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
return SvcResultMessage.FromResult(Program.HandleStartupParams(startUpParams, null));
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleSetLgConfigMessage(SvcMessage message)
|
||||
{
|
||||
var data = message.Data;
|
||||
|
||||
Utils.WriteText(LgConfigFile, data);
|
||||
|
||||
return SvcResultMessage.FromResult(true);
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleGetLogMessage(SvcMessage _)
|
||||
{
|
||||
var logFile = Program.LogFilename;
|
||||
|
||||
var data = Utils.ReadText(logFile);
|
||||
|
||||
return SvcResultMessage.FromResult(data);
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleClearLogMessage(SvcMessage _)
|
||||
{
|
||||
var logFile = Program.LogFilename;
|
||||
|
||||
if (File.Exists(logFile))
|
||||
{
|
||||
File.Delete(logFile);
|
||||
}
|
||||
|
||||
return SvcResultMessage.FromResult(true);
|
||||
}
|
||||
|
||||
private async Task WakeDevicesAsync()
|
||||
{
|
||||
if (!UserSessionInfo.UserLocalSession)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!File.Exists(LgConfigFile))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var config = Utils.DeserializeJson<LgServiceConfig>(LgConfigFile);
|
||||
|
||||
if (config == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var wakeDevices = config.Devices.Where(d => d.PowerOnAfterStartup).ToList();
|
||||
|
||||
foreach (var wakeDevice in wakeDevices)
|
||||
{
|
||||
for (var i = 0; i < config.PowerOnRetries; i++)
|
||||
{
|
||||
WOL.WakeFunction(wakeDevice.MacAddress, wakeDevice.IpAddress);
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
var result = Utils.PingHost(wakeDevice.IpAddress);
|
||||
|
||||
if (result)
|
||||
{
|
||||
Logger.Debug($"Device {wakeDevice.Name} is pingable, stopping WOL");
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace ColorControl.Svc
|
||||
{
|
||||
public enum SvcMessageType
|
||||
{
|
||||
SetLgConfig = 1,
|
||||
GetLog = 2,
|
||||
ClearLog = 3,
|
||||
ExecuteRpc = 10,
|
||||
}
|
||||
|
||||
public class SvcMessage
|
||||
{
|
||||
public SvcMessageType MessageType { get; set; }
|
||||
|
||||
public string Data { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace ColorControl.Svc
|
||||
{
|
||||
public class SvcResultMessage
|
||||
{
|
||||
public bool Result { get; set; }
|
||||
|
||||
public string Data { get; set; }
|
||||
|
||||
public string ErrorMessage { get; set; }
|
||||
|
||||
|
||||
public static SvcResultMessage FromResult(bool result, string errorMessage = null) => new SvcResultMessage { Result = result, ErrorMessage = errorMessage };
|
||||
public static SvcResultMessage FromResult(string data) => new SvcResultMessage { Result = true, Data = data };
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user