mirror of
https://github.com/Maassoft/ColorControl.git
synced 2026-10-21 16:12:18 -05:00
fix Novideo, add Game launcher auto-apply, add some LG actions, move winapi/admin functions to designated services
This commit is contained in:
1 parent
6eae7db459
commit
9fd8e8f9bb
63 files changed
+3297
-2344
No files matched your search
@@ -18,8 +18,8 @@
|
||||
<PublisherName>Maassoft</PublisherName>
|
||||
<Company>Maassoft</Company>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>9.6.4.0</ApplicationVersion>
|
||||
<Version>9.6.4.0</Version>
|
||||
<ApplicationVersion>9.7.0.0</ApplicationVersion>
|
||||
<Version>9.7.0.0</Version>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<PublishWizardCompleted>true</PublishWizardCompleted>
|
||||
<BootstrapperEnabled>false</BootstrapperEnabled>
|
||||
@@ -63,6 +63,9 @@
|
||||
<Compile Update="services\lg\RemoteControlPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Services\NVIDIA\NvInfoPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Services\NVIDIA\NvPanel.cs" />
|
||||
<Compile Update="Services\Samsung\SamsungPanel.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
|
||||
@@ -5,6 +5,7 @@ using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
@@ -16,55 +17,11 @@ namespace ColorControl
|
||||
{
|
||||
public static async Task<bool> HandleStartupParams(StartUpParams startUpParams, Process existingProcess)
|
||||
{
|
||||
if (startUpParams.ActivateChromeFontFix || startUpParams.DeactivateChromeFontFix)
|
||||
{
|
||||
Utils.InstallChromeFix(startUpParams.ActivateChromeFontFix, startUpParams.ChromeFontFixApplicationDataFolder);
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.EnableAutoStart || startUpParams.DisableAutoStart)
|
||||
{
|
||||
Utils.RegisterTask(Program.TS_TASKNAME, startUpParams.EnableAutoStart, startUpParams.AutoStartRunLevel);
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.SetProcessAffinity)
|
||||
{
|
||||
Utils.SetProcessAffinity(startUpParams.ProcessId, startUpParams.AffinityMask);
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.SetProcessPriority)
|
||||
{
|
||||
Utils.SetProcessPriority(startUpParams.ProcessId, startUpParams.PriorityClass);
|
||||
return true;
|
||||
}
|
||||
if (startUpParams.StartElevated)
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -152,7 +109,9 @@ Options:
|
||||
{
|
||||
try
|
||||
{
|
||||
Application.Run(new ElevatedForm());
|
||||
var elevatedForm = Program.ServiceProvider.GetRequiredService<ElevatedForm>();
|
||||
|
||||
Application.Run(elevatedForm);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -1,85 +1,53 @@
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Native;
|
||||
using NWin32;
|
||||
using ColorControl.Svc;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Forms
|
||||
namespace ColorControl.Forms;
|
||||
|
||||
public partial class ElevatedForm : Form
|
||||
{
|
||||
public partial class ElevatedForm : Form
|
||||
private ColorControlBackgroundService _backgroundService;
|
||||
|
||||
public ElevatedForm(ColorControlBackgroundService backgroundService)
|
||||
{
|
||||
public ElevatedForm()
|
||||
InitializeComponent();
|
||||
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
ShowInTaskbar = false;
|
||||
Load += ElevatedForm_Load;
|
||||
Shown += ElevatedForm_Shown;
|
||||
|
||||
Task.Run(CheckMutexAsync);
|
||||
|
||||
_backgroundService = backgroundService;
|
||||
_backgroundService.PipeName = "elevatedpipe";
|
||||
|
||||
Task.Run(async () => await _backgroundService.StartAsync(CancellationToken.None));
|
||||
}
|
||||
|
||||
private void ElevatedForm_Shown(object sender, EventArgs e)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
protected void ElevatedForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Size = new Size(0, 0);
|
||||
}
|
||||
|
||||
private void CheckMutexAsync()
|
||||
{
|
||||
var mutex = new Mutex(false, Shared.Common.GlobalContext.CurrentContext.MutexId, out var created);
|
||||
try
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
FormBorderStyle = FormBorderStyle.None;
|
||||
ShowInTaskbar = false;
|
||||
Load += ElevatedForm_Load;
|
||||
Shown += ElevatedForm_Shown;
|
||||
|
||||
var filterStatus = new WinApi.CHANGEFILTERSTRUCT();
|
||||
filterStatus.size = (uint)Marshal.SizeOf(filterStatus);
|
||||
filterStatus.info = 0;
|
||||
|
||||
WinApi.ChangeWindowMessageFilterEx(Handle, NativeConstants.WM_COPYDATA, WinApi.ChangeWindowMessageFilterExAction.Allow, ref filterStatus);
|
||||
|
||||
Task.Run(CheckMutexAsync);
|
||||
mutex.WaitOne();
|
||||
}
|
||||
|
||||
private void ElevatedForm_Shown(object sender, EventArgs e)
|
||||
catch (AbandonedMutexException)
|
||||
{
|
||||
Hide();
|
||||
}
|
||||
|
||||
protected void ElevatedForm_Load(object sender, EventArgs e)
|
||||
{
|
||||
Size = new Size(0, 0);
|
||||
}
|
||||
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (m.Msg == NativeConstants.WM_COPYDATA)
|
||||
{
|
||||
var container = (WinApi.COPYDATASTRUCT)m.GetLParam(typeof(WinApi.COPYDATASTRUCT));
|
||||
var message = Marshal.PtrToStringAnsi(container.lpData);
|
||||
|
||||
HandleMessage(message);
|
||||
}
|
||||
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
|
||||
private void HandleMessage(string message)
|
||||
{
|
||||
var args = message.Split(' ');
|
||||
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
try
|
||||
{
|
||||
var _ = CommandLineHandler.HandleStartupParams(startUpParams, null);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckMutexAsync()
|
||||
{
|
||||
var mutex = new Mutex(false, Shared.Common.AppContext.CurrentContext.MutexId, out var created);
|
||||
try
|
||||
{
|
||||
mutex.WaitOne();
|
||||
}
|
||||
catch (AbandonedMutexException)
|
||||
{
|
||||
}
|
||||
BeginInvoke(Application.Exit);
|
||||
}
|
||||
BeginInvoke(Application.Exit);
|
||||
}
|
||||
}
|
||||
Generated
-44
@@ -59,9 +59,6 @@
|
||||
chkStartMinimized = new System.Windows.Forms.CheckBox();
|
||||
chkStartAfterLogin = new System.Windows.Forms.CheckBox();
|
||||
tabInfo = new System.Windows.Forms.TabPage();
|
||||
grpNVIDIAInfo = new System.Windows.Forms.GroupBox();
|
||||
btnRefreshNVIDIAInfo = new System.Windows.Forms.Button();
|
||||
tvNVIDIAInfo = new System.Windows.Forms.TreeView();
|
||||
groupBox3 = new System.Windows.Forms.GroupBox();
|
||||
lbPlugins = new System.Windows.Forms.ListBox();
|
||||
label7 = new System.Windows.Forms.Label();
|
||||
@@ -73,7 +70,6 @@
|
||||
grpMiscellaneousOptions.SuspendLayout();
|
||||
grpGeneralOptions.SuspendLayout();
|
||||
tabInfo.SuspendLayout();
|
||||
grpNVIDIAInfo.SuspendLayout();
|
||||
groupBox3.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
@@ -441,7 +437,6 @@
|
||||
//
|
||||
// tabInfo
|
||||
//
|
||||
tabInfo.Controls.Add(grpNVIDIAInfo);
|
||||
tabInfo.Controls.Add(groupBox3);
|
||||
tabInfo.Location = new System.Drawing.Point(4, 24);
|
||||
tabInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
@@ -452,41 +447,6 @@
|
||||
tabInfo.Text = "Info";
|
||||
tabInfo.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// grpNVIDIAInfo
|
||||
//
|
||||
grpNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
grpNVIDIAInfo.Controls.Add(btnRefreshNVIDIAInfo);
|
||||
grpNVIDIAInfo.Controls.Add(tvNVIDIAInfo);
|
||||
grpNVIDIAInfo.Location = new System.Drawing.Point(463, 7);
|
||||
grpNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
grpNVIDIAInfo.Name = "grpNVIDIAInfo";
|
||||
grpNVIDIAInfo.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
grpNVIDIAInfo.Size = new System.Drawing.Size(643, 511);
|
||||
grpNVIDIAInfo.TabIndex = 4;
|
||||
grpNVIDIAInfo.TabStop = false;
|
||||
grpNVIDIAInfo.Text = "NVIDIA info";
|
||||
//
|
||||
// btnRefreshNVIDIAInfo
|
||||
//
|
||||
btnRefreshNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnRefreshNVIDIAInfo.Location = new System.Drawing.Point(7, 478);
|
||||
btnRefreshNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnRefreshNVIDIAInfo.Name = "btnRefreshNVIDIAInfo";
|
||||
btnRefreshNVIDIAInfo.Size = new System.Drawing.Size(88, 27);
|
||||
btnRefreshNVIDIAInfo.TabIndex = 1;
|
||||
btnRefreshNVIDIAInfo.Text = "Refresh";
|
||||
btnRefreshNVIDIAInfo.UseVisualStyleBackColor = true;
|
||||
btnRefreshNVIDIAInfo.Click += btnRefreshNVIDIAInfo_Click;
|
||||
//
|
||||
// tvNVIDIAInfo
|
||||
//
|
||||
tvNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
tvNVIDIAInfo.Location = new System.Drawing.Point(7, 22);
|
||||
tvNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
tvNVIDIAInfo.Name = "tvNVIDIAInfo";
|
||||
tvNVIDIAInfo.Size = new System.Drawing.Size(628, 448);
|
||||
tvNVIDIAInfo.TabIndex = 0;
|
||||
//
|
||||
// groupBox3
|
||||
//
|
||||
groupBox3.Controls.Add(lbPlugins);
|
||||
@@ -579,7 +539,6 @@
|
||||
grpGeneralOptions.ResumeLayout(false);
|
||||
grpGeneralOptions.PerformLayout();
|
||||
tabInfo.ResumeLayout(false);
|
||||
grpNVIDIAInfo.ResumeLayout(false);
|
||||
groupBox3.ResumeLayout(false);
|
||||
groupBox3.PerformLayout();
|
||||
ResumeLayout(false);
|
||||
@@ -597,9 +556,6 @@
|
||||
private System.Windows.Forms.ListBox lbPlugins;
|
||||
private System.Windows.Forms.Label label7;
|
||||
private System.Windows.Forms.Label lblInfo;
|
||||
private System.Windows.Forms.GroupBox grpNVIDIAInfo;
|
||||
private System.Windows.Forms.TreeView tvNVIDIAInfo;
|
||||
private System.Windows.Forms.Button btnRefreshNVIDIAInfo;
|
||||
private System.Windows.Forms.GroupBox grpMiscellaneousOptions;
|
||||
private System.Windows.Forms.CheckBox chkFixChromeFonts;
|
||||
private System.Windows.Forms.Label lblFixChromeFontsDescription;
|
||||
|
||||
+41
-77
@@ -15,7 +15,6 @@ using Linearstar.Windows.RawInput;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NLog;
|
||||
using novideo_srgb;
|
||||
using NvAPIWrapper.Display;
|
||||
using NWin32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -39,10 +38,12 @@ namespace ColorControl
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly PowerEventDispatcher _powerEventDispatcher;
|
||||
private readonly ServiceManager _serviceManager;
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private readonly WinApiService _winApiService;
|
||||
private string _dataDir;
|
||||
|
||||
private NvPanel _nvPanel;
|
||||
private NvDitherPanel _nvDitherPanel;
|
||||
|
||||
private NotifyIcon _trayIcon;
|
||||
private bool _initialized = false;
|
||||
@@ -76,7 +77,8 @@ namespace ColorControl
|
||||
private Dictionary<int, Action> _shortcuts = new();
|
||||
private Dictionary<string, Func<UserControl>> _modules = new();
|
||||
|
||||
public MainForm(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, ServiceManager serviceManager)
|
||||
public MainForm(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, ServiceManager serviceManager,
|
||||
IServiceProvider serviceProvider, WinApiAdminService winApiAdminService, WinApiService winApiService)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -87,6 +89,9 @@ namespace ColorControl
|
||||
|
||||
_powerEventDispatcher = powerEventDispatcher;
|
||||
_serviceManager = serviceManager;
|
||||
_serviceProvider = serviceProvider;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
_winApiService = winApiService;
|
||||
_dataDir = Program.DataDir;
|
||||
_config = Program.Config;
|
||||
|
||||
@@ -130,17 +135,17 @@ namespace ColorControl
|
||||
_trayIcon.ContextMenuStrip.Opened += trayIconContextMenu_Popup;
|
||||
_trayIcon.BalloonTipClicked += trayIconBalloonTip_Clicked;
|
||||
|
||||
chkStartAfterLogin.Checked = Utils.TaskExists(Program.TS_TASKNAME);
|
||||
chkStartAfterLogin.Checked = _winApiService.TaskExists(Program.TS_TASKNAME);
|
||||
|
||||
chkFixChromeFonts.Enabled = Utils.IsChromeInstalled();
|
||||
chkFixChromeFonts.Enabled = _winApiService.IsChromeInstalled();
|
||||
if (chkFixChromeFonts.Enabled)
|
||||
{
|
||||
var fixInstalled = Utils.IsChromeFixInstalled();
|
||||
var fixInstalled = _winApiService.IsChromeFixInstalled();
|
||||
if (_config.FixChromeFonts && !fixInstalled)
|
||||
{
|
||||
Utils.ExecuteElevated(StartUpParams.ActivateChromeFontFixParam);
|
||||
_winApiAdminService.InstallChromeFix(true, Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
|
||||
}
|
||||
chkFixChromeFonts.Checked = Utils.IsChromeFixInstalled();
|
||||
chkFixChromeFonts.Checked = _winApiService.IsChromeFixInstalled();
|
||||
}
|
||||
|
||||
InitShortcut(SHORTCUTID_SCREENSAVER, _config.ScreenSaverShortcut, StartScreenSaver);
|
||||
@@ -230,12 +235,12 @@ namespace ColorControl
|
||||
var text = "Use Windows Service";
|
||||
btnStartStopService.Enabled = true;
|
||||
|
||||
if (Utils.IsServiceRunning())
|
||||
if (_winApiService.IsServiceRunning())
|
||||
{
|
||||
text += " (running)";
|
||||
btnStartStopService.Text = "Stop";
|
||||
}
|
||||
else if (Utils.IsServiceInstalled())
|
||||
else if (_winApiService.IsServiceInstalled())
|
||||
{
|
||||
text += " (installed, not running)";
|
||||
btnStartStopService.Text = "Start";
|
||||
@@ -256,11 +261,11 @@ namespace ColorControl
|
||||
{
|
||||
//throw new Exception("bla");
|
||||
Logger.Debug("Initializing NVIDIA...");
|
||||
var appContextProvider = Program.ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
_serviceManager.NvService = new NvService(appContextProvider);
|
||||
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
|
||||
_serviceManager.NvService = _serviceProvider.GetRequiredService<NvService>();
|
||||
Logger.Debug("Initializing NVIDIA...Done.");
|
||||
|
||||
var rpcService = Program.ServiceProvider.GetRequiredService<RpcService>();
|
||||
var rpcService = _serviceProvider.GetRequiredService<RpcClientService>();
|
||||
|
||||
_nvPanel = new NvPanel(_serviceManager.NvService, _trayIcon, Handle, appContextProvider, rpcService);
|
||||
_nvPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||
@@ -282,7 +287,7 @@ namespace ColorControl
|
||||
{
|
||||
try
|
||||
{
|
||||
var appContextProvider = Program.ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
var appContextProvider = _serviceProvider.GetRequiredService<AppContextProvider>();
|
||||
_serviceManager.AmdService = new AmdService(appContextProvider);
|
||||
|
||||
_amdPanel = new AmdPanel(_serviceManager.AmdService, _trayIcon, Handle);
|
||||
@@ -305,7 +310,7 @@ namespace ColorControl
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceManager.GameService = Program.ServiceProvider.GetRequiredService<GameService>();
|
||||
_serviceManager.GameService = _serviceProvider.GetRequiredService<GameService>();
|
||||
|
||||
_gamePanel = new GamePanel(_serviceManager.GameService, _serviceManager.NvService, _serviceManager.AmdService, _serviceManager.LgService, _serviceManager.SamsungService, _trayIcon, Handle);
|
||||
_gamePanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||
@@ -336,7 +341,7 @@ namespace ColorControl
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceManager.LgService = Program.ServiceProvider.GetRequiredService<LgService>();
|
||||
_serviceManager.LgService = _serviceProvider.GetRequiredService<LgService>();
|
||||
|
||||
_lgPanel = new LgPanel(_serviceManager.LgService, _serviceManager.NvService, _serviceManager.AmdService, _trayIcon, Handle);
|
||||
_lgPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||
@@ -360,7 +365,7 @@ namespace ColorControl
|
||||
{
|
||||
try
|
||||
{
|
||||
_serviceManager.SamsungService = Program.ServiceProvider.GetRequiredService<SamsungService>();
|
||||
_serviceManager.SamsungService = _serviceProvider.GetRequiredService<SamsungService>();
|
||||
|
||||
//_serviceManager.SamsungService.Init();
|
||||
|
||||
@@ -387,7 +392,7 @@ namespace ColorControl
|
||||
|
||||
Text = Application.ProductName + " " + Application.ProductVersion;
|
||||
|
||||
if (Utils.IsAdministrator())
|
||||
if (_winApiService.IsAdministrator())
|
||||
{
|
||||
Text += " (administrator)";
|
||||
}
|
||||
@@ -435,7 +440,7 @@ namespace ColorControl
|
||||
{
|
||||
if (_updateHtmlUrl != null)
|
||||
{
|
||||
Utils.StartProcess(_updateHtmlUrl);
|
||||
_winApiAdminService.StartProcess(_updateHtmlUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,7 +696,7 @@ namespace ColorControl
|
||||
|
||||
private void CheckElevationMethod()
|
||||
{
|
||||
if (Utils.IsAdministrator())
|
||||
if (_winApiService.IsAdministrator())
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -703,15 +708,15 @@ namespace ColorControl
|
||||
return;
|
||||
}
|
||||
|
||||
if (_config.ElevationMethod == ElevationMethod.UseService && !Utils.IsServiceInstalled() &&
|
||||
if (_config.ElevationMethod == ElevationMethod.UseService && !_winApiService.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();
|
||||
_winApiAdminService.InstallService();
|
||||
}
|
||||
else if (_config.ElevationMethod == ElevationMethod.UseService && !Utils.IsServiceRunning() &&
|
||||
else if (_config.ElevationMethod == ElevationMethod.UseService && !_winApiService.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();
|
||||
_winApiAdminService.StartService();
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -764,7 +769,6 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
{
|
||||
if (tcMain.SelectedTab == tabInfo)
|
||||
{
|
||||
LoadInfo();
|
||||
}
|
||||
else if (tcMain.SelectedTab == tabOptions)
|
||||
{
|
||||
@@ -786,26 +790,6 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
}
|
||||
}
|
||||
|
||||
if (_serviceManager.NvService != null)
|
||||
{
|
||||
if (_nvDitherPanel == null)
|
||||
{
|
||||
_nvDitherPanel = new NvDitherPanel(_serviceManager.NvService);
|
||||
|
||||
tabOptions.Controls.Add(_nvDitherPanel);
|
||||
|
||||
_nvDitherPanel.Top = grpGeneralOptions.Top;
|
||||
_nvDitherPanel.Left = grpGeneralOptions.Left + grpGeneralOptions.Width + 4;
|
||||
_nvDitherPanel.Width = tabOptions.Width - _nvDitherPanel.Left - 4;
|
||||
|
||||
_nvDitherPanel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
}
|
||||
else
|
||||
{
|
||||
_nvDitherPanel.UpdateInfo();
|
||||
}
|
||||
}
|
||||
|
||||
_initialized = false;
|
||||
try
|
||||
{
|
||||
@@ -944,24 +928,8 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
await _samsungPanel?.ApplyPreset(preset);
|
||||
}
|
||||
|
||||
private void LoadInfo()
|
||||
{
|
||||
grpNVIDIAInfo.Visible = _serviceManager.NvService != null;
|
||||
}
|
||||
|
||||
private void btnRefreshNVIDIAInfo_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (_serviceManager.NvService != null)
|
||||
{
|
||||
tvNVIDIAInfo.Nodes.Clear();
|
||||
var displays = Display.GetDisplays();
|
||||
for (var i = 0; i < displays.Length; i++)
|
||||
{
|
||||
var display = displays[i];
|
||||
var node = TreeNodeBuilder.CreateTree(display, $"Display[{i}]");
|
||||
tvNVIDIAInfo.Nodes.Add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnSetShortcutScreenSaver_Click(object sender, EventArgs e)
|
||||
@@ -1063,7 +1031,7 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
{
|
||||
_updateHtmlUrl = latest.html_url.Value;
|
||||
|
||||
if (latest.assets != null && Utils.IsServiceRunning())
|
||||
if (latest.assets != null && _winApiService.IsServiceRunning())
|
||||
{
|
||||
var asset = latest.assets[0];
|
||||
_downloadUrl = asset.browser_download_url.Value;
|
||||
@@ -1196,8 +1164,6 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
{
|
||||
_config.ElevationMethod = elevationMethod;
|
||||
|
||||
Utils.UseDedicatedElevatedProcess = _config.ElevationMethod == ElevationMethod.UseElevatedProcess;
|
||||
|
||||
var _ = _config.ElevationMethod switch
|
||||
{
|
||||
ElevationMethod.None => SetElevationMethodNone(),
|
||||
@@ -1217,7 +1183,7 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
RegisterScheduledTask();
|
||||
}
|
||||
|
||||
Utils.UninstallService();
|
||||
_winApiAdminService.UninstallService();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1230,16 +1196,16 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
RegisterScheduledTask();
|
||||
}
|
||||
|
||||
Utils.UninstallService();
|
||||
_winApiAdminService.UninstallService();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool SetElevationMethodUseService()
|
||||
{
|
||||
Utils.InstallService();
|
||||
_winApiAdminService.InstallService();
|
||||
|
||||
if (Utils.IsServiceInstalled())
|
||||
if (_winApiService.IsServiceInstalled())
|
||||
{
|
||||
MessageForms.InfoOk("Service installed successfully.");
|
||||
return true;
|
||||
@@ -1257,14 +1223,14 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
RegisterScheduledTask();
|
||||
}
|
||||
|
||||
Utils.UninstallService();
|
||||
_winApiAdminService.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);
|
||||
_winApiAdminService.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)
|
||||
@@ -1273,7 +1239,7 @@ NOTE: installing the service may cause a User Account Control popup.");
|
||||
|
||||
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.
|
||||
Currently ColorControl is {(_winApiService.IsAdministrator() ? "" : "not ")}running as administrator.
|
||||
");
|
||||
}
|
||||
|
||||
@@ -1286,11 +1252,11 @@ Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as ad
|
||||
|
||||
if (start)
|
||||
{
|
||||
Utils.StartService();
|
||||
_winApiAdminService.StartService();
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.StopService();
|
||||
_winApiAdminService.StopService();
|
||||
}
|
||||
|
||||
var wait = 1500;
|
||||
@@ -1299,7 +1265,7 @@ Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as ad
|
||||
{
|
||||
await Task.Delay(100);
|
||||
|
||||
if (start == Utils.IsServiceRunning())
|
||||
if (start == _winApiService.IsServiceRunning())
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1376,11 +1342,9 @@ Currently ColorControl is {(Utils.IsAdministrator() ? "" : "not ")}running as ad
|
||||
{
|
||||
_config.FixChromeFonts = chkFixChromeFonts.Checked;
|
||||
|
||||
var param = chkFixChromeFonts.Checked ? StartUpParams.ActivateChromeFontFixParam : StartUpParams.DeactivateChromeFontFixParam;
|
||||
|
||||
var folder = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
|
||||
|
||||
Utils.ExecuteElevated($"{param} {folder}");
|
||||
_winApiAdminService.InstallChromeFix(chkFixChromeFonts.Checked, folder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+53
-24
@@ -1,13 +1,16 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Forms;
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using ColorControl.Svc;
|
||||
using ColorControl.XForms;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
@@ -31,7 +34,7 @@ namespace ColorControl
|
||||
public static string ConfigFilename { get; private set; }
|
||||
public static string LogFilename { get; private set; }
|
||||
public static Config Config { get; private set; }
|
||||
public static Shared.Common.AppContext AppContext { get; private set; }
|
||||
public static GlobalContext AppContext { get; private set; }
|
||||
|
||||
public static bool IsRestarting { get; private set; }
|
||||
public static bool UserExit = false;
|
||||
@@ -59,27 +62,23 @@ namespace ColorControl
|
||||
//Utils.UpdateFiles(@"H:\temp\ColorControl\ColorControl", @"C:\Users\vinni\source\repos\ColorControl\ColorControl\bin\Debug\net6.0-windows10.0.20348.0");
|
||||
//Utils.UnZipFile(@"H:\temp\ColorControl\ColorControl.zip", @"H:\temp\ColorControl\temp");
|
||||
|
||||
var runAsService = args.Contains("--service") || Utils.IsAdministrator() && Process.GetCurrentProcess().Parent()?.ProcessName?.Equals("services", StringComparison.InvariantCultureIgnoreCase) == true;
|
||||
var runAsService = args.Contains("--service") || WinApiService.IsAdministratorStatic() && Process.GetCurrentProcess().Parent()?.ProcessName?.Equals("services", StringComparison.InvariantCultureIgnoreCase) == true;
|
||||
var runElevated = args.Contains("--elevated");
|
||||
|
||||
InitLogger(runAsService);
|
||||
InitLogger(runAsService, runElevated);
|
||||
|
||||
Logger.Debug($"Using data path: {DataDir}");
|
||||
//Logger.Debug("Parent process: " + Process.GetCurrentProcess().Parent()?.ProcessName);
|
||||
|
||||
var host = CreateHostBuilder().Build();
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
|
||||
if (runAsService)
|
||||
{
|
||||
AppContext = new Shared.Common.AppContext(null, new StartUpParams(), DataDir, _loggingRule);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
await RunService(args);
|
||||
return;
|
||||
}
|
||||
|
||||
var host = CreateHostBuilder().Build();
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var mutexId = $"Global\\{typeof(MainForm).GUID}";
|
||||
|
||||
var currentDomain = AppDomain.CurrentDomain;
|
||||
@@ -90,16 +89,17 @@ namespace ColorControl
|
||||
|
||||
LoadConfig();
|
||||
|
||||
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
AppContext = new GlobalContext(Config, startUpParams, DataDir, _loggingRule, mutexId);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
if (Config.UseGdiScaling)
|
||||
{
|
||||
Application.SetHighDpiMode(HighDpiMode.DpiUnawareGdiScaled);
|
||||
}
|
||||
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
|
||||
AppContext = new Shared.Common.AppContext(Config, startUpParams, DataDir, _loggingRule, mutexId);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
var existingProcess = Utils.GetProcessByName("ColorControl");
|
||||
|
||||
try
|
||||
@@ -145,12 +145,26 @@ namespace ColorControl
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
var winApiService = ServiceProvider.GetRequiredService<WinApiService>();
|
||||
|
||||
if (winApiService.IsAdministrator())
|
||||
{
|
||||
var backgroundService = ServiceProvider.GetRequiredService<ColorControlBackgroundService>();
|
||||
backgroundService.PipeName = PipeUtils.ElevatedPipe;
|
||||
|
||||
Task.Run(async () => await backgroundService.StartAsync(CancellationToken.None));
|
||||
}
|
||||
}
|
||||
|
||||
_mainForm = ServiceProvider.GetRequiredService<MainForm>();
|
||||
Application.Run(_mainForm);
|
||||
|
||||
if (Debugger.IsAttached && !IsRestarting)
|
||||
{
|
||||
Utils.StopService();
|
||||
var winApiAdminService = ServiceProvider.GetRequiredService<WinApiAdminService>();
|
||||
winApiAdminService.StopService();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -181,12 +195,12 @@ namespace ColorControl
|
||||
Environment.Exit(0);
|
||||
}
|
||||
|
||||
private static void InitLogger(bool runAsService)
|
||||
private static void InitLogger(bool runAsService, bool runElevated)
|
||||
{
|
||||
var config = new LoggingConfiguration();
|
||||
|
||||
// Targets where to log to: File and Console
|
||||
var logFileAppendix = runAsService ? "_svc" : "";
|
||||
var logFileAppendix = runAsService ? "_svc" : runElevated ? "_elevated" : "";
|
||||
|
||||
LogFilename = Path.Combine(DataDir, $"LogFile{logFileAppendix}.txt");
|
||||
|
||||
@@ -220,8 +234,6 @@ namespace ColorControl
|
||||
}
|
||||
Config ??= new Config();
|
||||
|
||||
Utils.UseDedicatedElevatedProcess = Config.UseDedicatedElevatedProcess;
|
||||
|
||||
var minLogLevel = LogLevel.FromString(Config.LogLevel);
|
||||
|
||||
if (minLogLevel != LogLevel.Trace)
|
||||
@@ -245,9 +257,9 @@ namespace ColorControl
|
||||
services.AddSingleton<PowerEventDispatcher>();
|
||||
services.AddSingleton<ProcessEventDispatcher>();
|
||||
services.AddSingleton<MainForm>();
|
||||
services.AddSingleton<ServiceManager>();
|
||||
services.AddSingleton<ElevatedForm>();
|
||||
services.AddSingleton<LogWindow>();
|
||||
services.AddSingleton<RestartDetector>();
|
||||
services.AddTransient<RpcService>();
|
||||
});
|
||||
}
|
||||
private static async Task RunService(string[] args)
|
||||
@@ -266,6 +278,12 @@ namespace ColorControl
|
||||
})
|
||||
.Build();
|
||||
|
||||
ServiceProvider = host.Services;
|
||||
|
||||
var appContextProvider = ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
AppContext = new GlobalContext(null, new StartUpParams(), DataDir, _loggingRule);
|
||||
appContextProvider.SetAppContext(AppContext);
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
@@ -273,6 +291,17 @@ namespace ColorControl
|
||||
{
|
||||
services.AddSingleton<AppContextProvider>();
|
||||
services.AddSingleton<SessionSwitchDispatcher>();
|
||||
services.AddSingleton<WinApiAdminService>();
|
||||
services.AddSingleton<WinApiService>();
|
||||
services.AddSingleton<WinElevatedProcessManager>();
|
||||
services.AddTransient<RpcClientService>();
|
||||
services.AddTransient<RpcServerService>();
|
||||
services.AddSingleton<NvService>();
|
||||
services.AddSingleton<WolService>();
|
||||
services.AddSingleton<ColorControlBackgroundService>();
|
||||
services.AddSingleton<ServiceManager>();
|
||||
|
||||
RpcServerService.ServiceTypes.Add(typeof(NvService));
|
||||
}
|
||||
|
||||
public static int EnumThreadWindows(IntPtr handle, IntPtr param)
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ColorControl.Services.AMD
|
||||
_trayIcon = trayIcon;
|
||||
_mainHandle = handle;
|
||||
|
||||
_config = Shared.Common.AppContext.CurrentContext.Config;
|
||||
_config = Shared.Common.GlobalContext.CurrentContext.Config;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
@@ -127,7 +127,7 @@ namespace ColorControl.Services.AMD
|
||||
|
||||
private async Task ApplyAmdPresetOnStartup(int attempts = 5)
|
||||
{
|
||||
var startUpParams = Shared.Common.AppContext.CurrentContext.StartUpParams;
|
||||
var startUpParams = Shared.Common.GlobalContext.CurrentContext.StartUpParams;
|
||||
var presetIdOrName = !string.IsNullOrEmpty(startUpParams.AmdPresetIdOrName) ? startUpParams.AmdPresetIdOrName : _config.AmdPresetId_ApplyOnStartup.ToString();
|
||||
|
||||
if (!string.IsNullOrEmpty(presetIdOrName))
|
||||
|
||||
@@ -3,70 +3,76 @@ using ColorControl.Services.GameLauncher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Services.Samsung;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Services;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.Common
|
||||
namespace ColorControl.Services.Common;
|
||||
|
||||
public class ServiceManager
|
||||
{
|
||||
public class ServiceManager
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
|
||||
internal NvService NvService { get; set; }
|
||||
internal LgService LgService { get; set; }
|
||||
internal AmdService AmdService { get; set; }
|
||||
internal GameService GameService { get; set; }
|
||||
internal SamsungService SamsungService { get; set; }
|
||||
|
||||
public ServiceManager(WinApiAdminService winApiAdminService)
|
||||
{
|
||||
internal NvService NvService { get; set; }
|
||||
internal LgService LgService { get; set; }
|
||||
internal AmdService AmdService { get; set; }
|
||||
internal GameService GameService { get; set; }
|
||||
internal SamsungService SamsungService { get; set; }
|
||||
_winApiAdminService = winApiAdminService;
|
||||
}
|
||||
|
||||
public async Task<bool> HandleExternalServiceAsync(string serviceName, string[] parameters)
|
||||
public async Task<bool> HandleExternalServiceAsync(string serviceName, string[] parameters)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serviceName) || parameters.Length == 0)
|
||||
{
|
||||
if (string.IsNullOrEmpty(serviceName) || parameters.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NvService != null && serviceName.Equals("NvPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return await NvService.ApplyPreset(parameters[0]);
|
||||
}
|
||||
if (NvService != null && serviceName.Equals("GsyncEnabled", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return NvService.IsGsyncEnabled();
|
||||
}
|
||||
if (AmdService != null && serviceName.Equals("AmdPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return await AmdService.ApplyPreset(parameters[0]);
|
||||
}
|
||||
if (LgService != null && serviceName.Equals("LgPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await LgService.ApplyPreset(parameters[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (SamsungService != null && serviceName.Equals("SamsungPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SamsungService.ApplyPreset(parameters[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (serviceName.Equals("StartProgram", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
Utils.StartProcess(parameters[0], parameters.Length > 1 ? string.Join(" ", parameters.Skip(1)) : null, setWorkingDir: true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
if (NvService != null && serviceName.Equals("NvPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
NvService?.GlobalSave();
|
||||
AmdService?.GlobalSave();
|
||||
LgService?.GlobalSave();
|
||||
GameService?.GlobalSave();
|
||||
SamsungService?.GlobalSave();
|
||||
return await NvService.ApplyPreset(parameters[0]);
|
||||
}
|
||||
if (NvService != null && serviceName.Equals("GsyncEnabled", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return NvService.IsGsyncEnabled();
|
||||
}
|
||||
if (AmdService != null && serviceName.Equals("AmdPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return await AmdService.ApplyPreset(parameters[0]);
|
||||
}
|
||||
if (LgService != null && serviceName.Equals("LgPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await LgService.ApplyPreset(parameters[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (SamsungService != null && serviceName.Equals("SamsungPreset", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
await SamsungService.ApplyPreset(parameters[0]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (serviceName.Equals("StartProgram", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_winApiAdminService.StartProcess(parameters[0], parameters.Length > 1 ? string.Join(" ", parameters.Skip(1)) : null, setWorkingDir: true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
NvService?.GlobalSave();
|
||||
AmdService?.GlobalSave();
|
||||
LgService?.GlobalSave();
|
||||
GameService?.GlobalSave();
|
||||
SamsungService?.GlobalSave();
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,10 @@ public class EventDispatcher<T> where T : EventArgs
|
||||
{
|
||||
eventHandlers.Add(eventName, eventHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
eventHandlers[eventName] += eventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
public void RegisterAsyncEventHandler(string eventName, AsyncEventHandler<T> eventHandler)
|
||||
@@ -24,6 +28,10 @@ public class EventDispatcher<T> where T : EventArgs
|
||||
{
|
||||
asyncEventHandlers.Add(eventName, eventHandler);
|
||||
}
|
||||
else
|
||||
{
|
||||
asyncEventHandlers[eventName] += eventHandler;
|
||||
}
|
||||
}
|
||||
|
||||
public void UnregisterEventHandler(string eventName)
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
public const string Event_ProcessChanged = "ProcessChanged";
|
||||
public bool IsRunning { get; set; }
|
||||
public ProcessChangedEventArgs MonitorContext { get; private set; }
|
||||
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private ProcessChangedEventArgs MonitorContext { get; set; }
|
||||
private AppContextProvider _appContextProvider { get; }
|
||||
|
||||
public ProcessEventDispatcher(AppContextProvider appContextProvider)
|
||||
@@ -88,6 +88,8 @@ namespace ColorControl.Services.EventDispatcher
|
||||
{
|
||||
var processes = Process.GetProcesses();
|
||||
|
||||
context.StartedProcesses = processes.Where(p => context.RunningProcesses?.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.StoppedProcesses = context.RunningProcesses?.Where(p => processes.Any(rp => rp.Id == p.Id) == false).ToList();
|
||||
context.RunningProcesses = processes;
|
||||
|
||||
context.IsNotificationDisabled = FormUtils.IsNotificationDisabled();
|
||||
|
||||
+37
-18
@@ -34,6 +34,7 @@
|
||||
mnuGameOptions = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
miGameProcessorAffinity = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miGameProcessPriority = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miPresetNVIDIAProfileInspector = new System.Windows.Forms.ToolStripMenuItem();
|
||||
chkGameQuickAccess = new System.Windows.Forms.CheckBox();
|
||||
btnGameSettings = new System.Windows.Forms.Button();
|
||||
mnuGameActions = new System.Windows.Forms.ContextMenuStrip(components);
|
||||
@@ -51,6 +52,7 @@
|
||||
mnuGameNvidiaPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameAmdPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameLgPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameSamsungPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameStartProgram = new System.Windows.Forms.ToolStripMenuItem();
|
||||
label4 = new System.Windows.Forms.Label();
|
||||
edtGameName = new System.Windows.Forms.TextBox();
|
||||
@@ -60,7 +62,7 @@
|
||||
btnGameAdd = new System.Windows.Forms.Button();
|
||||
btnGameLaunch = new System.Windows.Forms.Button();
|
||||
lvGamePresets = new System.Windows.Forms.ListView();
|
||||
mnuGameSamsungPresets = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miGameOptionsAutoApplySettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuGameOptions.SuspendLayout();
|
||||
mnuGameActions.SuspendLayout();
|
||||
mnuGameAddStep.SuspendLayout();
|
||||
@@ -96,24 +98,31 @@
|
||||
// mnuGameOptions
|
||||
//
|
||||
mnuGameOptions.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuGameOptions.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miGameProcessorAffinity, miGameProcessPriority });
|
||||
mnuGameOptions.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miGameProcessorAffinity, miGameProcessPriority, miPresetNVIDIAProfileInspector, miGameOptionsAutoApplySettings });
|
||||
mnuGameOptions.Name = "mnuLgButtons";
|
||||
mnuGameOptions.Size = new System.Drawing.Size(166, 48);
|
||||
mnuGameOptions.Size = new System.Drawing.Size(202, 114);
|
||||
//
|
||||
// miGameProcessorAffinity
|
||||
//
|
||||
miGameProcessorAffinity.Name = "miGameProcessorAffinity";
|
||||
miGameProcessorAffinity.Size = new System.Drawing.Size(165, 22);
|
||||
miGameProcessorAffinity.Size = new System.Drawing.Size(201, 22);
|
||||
miGameProcessorAffinity.Text = "Processor affinity";
|
||||
miGameProcessorAffinity.Click += btnGameProcessAffinity_Click;
|
||||
//
|
||||
// miGameProcessPriority
|
||||
//
|
||||
miGameProcessPriority.Name = "miGameProcessPriority";
|
||||
miGameProcessPriority.Size = new System.Drawing.Size(165, 22);
|
||||
miGameProcessPriority.Size = new System.Drawing.Size(201, 22);
|
||||
miGameProcessPriority.Text = "Process priority";
|
||||
miGameProcessPriority.Click += miGameProcessPriority_Click;
|
||||
//
|
||||
// miPresetNVIDIAProfileInspector
|
||||
//
|
||||
miPresetNVIDIAProfileInspector.Name = "miPresetNVIDIAProfileInspector";
|
||||
miPresetNVIDIAProfileInspector.Size = new System.Drawing.Size(201, 22);
|
||||
miPresetNVIDIAProfileInspector.Text = "NVIDIA Profile Inspector";
|
||||
miPresetNVIDIAProfileInspector.Click += miPresetNVIDIAProfileInspector_Click;
|
||||
//
|
||||
// chkGameQuickAccess
|
||||
//
|
||||
chkGameQuickAccess.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
@@ -145,21 +154,21 @@
|
||||
mnuGameActions.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuGameActions.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuGameNvInspector, miGameSetQuickAccessShortcut });
|
||||
mnuGameActions.Name = "mnuLgButtons";
|
||||
mnuGameActions.Size = new System.Drawing.Size(212, 48);
|
||||
mnuGameActions.Size = new System.Drawing.Size(202, 48);
|
||||
mnuGameActions.Opening += mnuGameActions_Opening;
|
||||
//
|
||||
// mnuGameNvInspector
|
||||
//
|
||||
mnuGameNvInspector.Name = "mnuGameNvInspector";
|
||||
mnuGameNvInspector.Size = new System.Drawing.Size(211, 22);
|
||||
mnuGameNvInspector.Size = new System.Drawing.Size(201, 22);
|
||||
mnuGameNvInspector.Text = "NVIDIA Profile Inspector";
|
||||
mnuGameNvInspector.Click += mnuGameNvInspector_Click;
|
||||
//
|
||||
// miGameSetQuickAccessShortcut
|
||||
//
|
||||
miGameSetQuickAccessShortcut.Name = "miGameSetQuickAccessShortcut";
|
||||
miGameSetQuickAccessShortcut.Size = new System.Drawing.Size(211, 22);
|
||||
miGameSetQuickAccessShortcut.Text = "Set Quick Access Shortcut";
|
||||
miGameSetQuickAccessShortcut.Size = new System.Drawing.Size(201, 22);
|
||||
miGameSetQuickAccessShortcut.Text = "Settings...";
|
||||
miGameSetQuickAccessShortcut.Click += miGameSetQuickAccessShortcut_Click;
|
||||
//
|
||||
// chkGameRunAsAdmin
|
||||
@@ -261,31 +270,37 @@
|
||||
mnuGameAddStep.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuGameAddStep.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { mnuGameNvidiaPresets, mnuGameAmdPresets, mnuGameLgPresets, mnuGameSamsungPresets, mnuGameStartProgram });
|
||||
mnuGameAddStep.Name = "mnuLgButtons";
|
||||
mnuGameAddStep.Size = new System.Drawing.Size(181, 136);
|
||||
mnuGameAddStep.Size = new System.Drawing.Size(164, 114);
|
||||
mnuGameAddStep.Opening += mnuGameAddStep_Opening;
|
||||
//
|
||||
// mnuGameNvidiaPresets
|
||||
//
|
||||
mnuGameNvidiaPresets.Name = "mnuGameNvidiaPresets";
|
||||
mnuGameNvidiaPresets.Size = new System.Drawing.Size(180, 22);
|
||||
mnuGameNvidiaPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameNvidiaPresets.Text = "NVIDIA presets";
|
||||
//
|
||||
// mnuGameAmdPresets
|
||||
//
|
||||
mnuGameAmdPresets.Name = "mnuGameAmdPresets";
|
||||
mnuGameAmdPresets.Size = new System.Drawing.Size(180, 22);
|
||||
mnuGameAmdPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameAmdPresets.Text = "AMD presets";
|
||||
//
|
||||
// mnuGameLgPresets
|
||||
//
|
||||
mnuGameLgPresets.Name = "mnuGameLgPresets";
|
||||
mnuGameLgPresets.Size = new System.Drawing.Size(180, 22);
|
||||
mnuGameLgPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameLgPresets.Text = "LG presets";
|
||||
//
|
||||
// mnuGameSamsungPresets
|
||||
//
|
||||
mnuGameSamsungPresets.Name = "mnuGameSamsungPresets";
|
||||
mnuGameSamsungPresets.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameSamsungPresets.Text = "Samsung presets";
|
||||
//
|
||||
// mnuGameStartProgram
|
||||
//
|
||||
mnuGameStartProgram.Name = "mnuGameStartProgram";
|
||||
mnuGameStartProgram.Size = new System.Drawing.Size(180, 22);
|
||||
mnuGameStartProgram.Size = new System.Drawing.Size(163, 22);
|
||||
mnuGameStartProgram.Text = "Start Program";
|
||||
mnuGameStartProgram.Click += mnuGameStartProgram_Click;
|
||||
//
|
||||
@@ -379,6 +394,7 @@
|
||||
lvGamePresets.AllowDrop = true;
|
||||
lvGamePresets.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
lvGamePresets.CheckBoxes = true;
|
||||
lvGamePresets.ContextMenuStrip = mnuGameOptions;
|
||||
lvGamePresets.FullRowSelect = true;
|
||||
lvGamePresets.Location = new System.Drawing.Point(8, 8);
|
||||
lvGamePresets.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
@@ -396,11 +412,12 @@
|
||||
lvGamePresets.DragEnter += lvGamePresets_DragEnter;
|
||||
lvGamePresets.DoubleClick += lvGamePresets_DoubleClick;
|
||||
//
|
||||
// mnuGameSamsungPresets
|
||||
// miGameOptionsAutoApplySettings
|
||||
//
|
||||
mnuGameSamsungPresets.Name = "mnuGameSamsungPresets";
|
||||
mnuGameSamsungPresets.Size = new System.Drawing.Size(180, 22);
|
||||
mnuGameSamsungPresets.Text = "Samsung presets";
|
||||
miGameOptionsAutoApplySettings.Name = "miGameOptionsAutoApplySettings";
|
||||
miGameOptionsAutoApplySettings.Size = new System.Drawing.Size(201, 22);
|
||||
miGameOptionsAutoApplySettings.Text = "Auto apply settings...";
|
||||
miGameOptionsAutoApplySettings.Click += miGameOptionsAutoApplySettings_Click;
|
||||
//
|
||||
// GamePanel
|
||||
//
|
||||
@@ -470,5 +487,7 @@
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameProcessPriority;
|
||||
private System.Windows.Forms.ComboBox cbxGameStepType;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuGameSamsungPresets;
|
||||
private System.Windows.Forms.ToolStripMenuItem miPresetNVIDIAProfileInspector;
|
||||
private System.Windows.Forms.ToolStripMenuItem miGameOptionsAutoApplySettings;
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ namespace ColorControl.Services.GameLauncher
|
||||
_amdService = amdService;
|
||||
_lgService = lgService;
|
||||
_samsungService = samsungService;
|
||||
_config = Shared.Common.AppContext.CurrentContext.Config;
|
||||
_config = Shared.Common.GlobalContext.CurrentContext.Config;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ColorControl.Services.GameLauncher
|
||||
var preset = GetSelectedGamePreset();
|
||||
var enabled = preset != null;
|
||||
|
||||
FormUtils.EnableControls(this, enabled, new List<Control> { lvGamePresets, btnGameAdd });
|
||||
FormUtils.EnableControls(this, enabled, new List<Control> { lvGamePresets, btnGameAdd, btnGameSettings });
|
||||
|
||||
if (preset != null)
|
||||
{
|
||||
@@ -361,16 +361,44 @@ namespace ColorControl.Services.GameLauncher
|
||||
|
||||
private void miGameSetQuickAccessShortcut_Click(object sender, EventArgs e)
|
||||
{
|
||||
var shortcut = FormUtils.EditShortcut(_config.GameQuickAccessShortcut);
|
||||
EditGameSettings();
|
||||
}
|
||||
|
||||
if (shortcut == null)
|
||||
private void EditGameSettings()
|
||||
{
|
||||
var quickAccessField = new FieldDefinition
|
||||
{
|
||||
Label = "Quick Access shortcut",
|
||||
FieldType = FieldType.Shortcut,
|
||||
Value = _config.GameQuickAccessShortcut
|
||||
};
|
||||
|
||||
var applyExternallyLaunched = new FieldDefinition
|
||||
{
|
||||
Label = "Apply presets when launching games externally",
|
||||
SubLabel = "This will monitor processes and automatically apply the preset whenever a known game is launched",
|
||||
FieldType = FieldType.CheckBox,
|
||||
Value = _gameService.Config.ApplyExternallyLaunched
|
||||
};
|
||||
|
||||
var values = MessageForms.ShowDialog("Game launcher settings", new[] {
|
||||
quickAccessField,
|
||||
applyExternallyLaunched
|
||||
});
|
||||
if (!values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var shortcut = (string)quickAccessField.Value;
|
||||
|
||||
_config.GameQuickAccessShortcut = shortcut;
|
||||
|
||||
KeyboardShortcutManager.RegisterShortcut(SHORTCUTID_GAMEQA, _config.GameQuickAccessShortcut);
|
||||
|
||||
_gameService.Config.ApplyExternallyLaunched = applyExternallyLaunched.ValueAsBool;
|
||||
|
||||
UpdateInfo();
|
||||
}
|
||||
|
||||
private void mnuGameActions_Opening(object sender, CancelEventArgs e)
|
||||
@@ -490,5 +518,52 @@ namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
FormUtils.ListViewSort(sender, e);
|
||||
}
|
||||
|
||||
private void miPresetNVIDIAProfileInspector_Click(object sender, EventArgs e)
|
||||
{
|
||||
var form = new frmDrvSettings();
|
||||
form.Show();
|
||||
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
var executable = Path.GetFileName(preset.Path);
|
||||
|
||||
form.SetProfileByExecutable(executable);
|
||||
}
|
||||
|
||||
private void miGameOptionsAutoApplySettings_Click(object sender, EventArgs e)
|
||||
{
|
||||
var preset = GetSelectedGamePreset();
|
||||
|
||||
var allowAutoApplyField = new FieldDefinition
|
||||
{
|
||||
Label = "Allow this preset to be automatically executed when the process starts",
|
||||
FieldType = FieldType.CheckBox,
|
||||
Value = preset.AutoSettings.AllowAutoApply
|
||||
};
|
||||
|
||||
var processActions = new[] { ProcessAutoAction.None, ProcessAutoAction.Suspend }.Select(t => Utils.GetDescription(t));
|
||||
|
||||
var processActionField = new FieldDefinition
|
||||
{
|
||||
Label = "Optional action to perform directly after the process starts",
|
||||
SubLabel = "Temporarily suspending the process may help when enabling/disabling HDR or other settings",
|
||||
FieldType = FieldType.DropDown,
|
||||
Values = processActions,
|
||||
Value = preset.AutoSettings.ProcessAutoAction
|
||||
};
|
||||
|
||||
var values = MessageForms.ShowDialog("Auto apply settings", new[] {
|
||||
allowAutoApplyField,
|
||||
processActionField
|
||||
});
|
||||
if (!values.Any())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
preset.AutoSettings.AllowAutoApply = allowAutoApplyField.ValueAsBool;
|
||||
preset.AutoSettings.ProcessAutoAction = processActionField.ValueAsEnum<ProcessAutoAction>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
|
||||
@@ -26,6 +26,19 @@ namespace ColorControl.Services.GameLauncher
|
||||
RealTime = NativeConstants.REALTIME_PRIORITY_CLASS
|
||||
}
|
||||
|
||||
public enum ProcessAutoAction
|
||||
{
|
||||
None = 0,
|
||||
Suspend = 1,
|
||||
Restart = 2
|
||||
}
|
||||
|
||||
class AutoSettings
|
||||
{
|
||||
public bool AllowAutoApply { get; set; }
|
||||
public ProcessAutoAction ProcessAutoAction { get; set; }
|
||||
}
|
||||
|
||||
class GamePreset : PresetBase
|
||||
{
|
||||
public string Path { get; set; }
|
||||
@@ -36,12 +49,14 @@ namespace ColorControl.Services.GameLauncher
|
||||
public List<string> FinalizeSteps { get; set; }
|
||||
public uint ProcessAffinityMask { get; set; }
|
||||
public uint ProcessPriorityClass { get; set; }
|
||||
public AutoSettings AutoSettings { get; set; }
|
||||
|
||||
public GamePreset() : base()
|
||||
{
|
||||
PreLaunchSteps = new List<string>();
|
||||
PostLaunchSteps = new List<string>();
|
||||
FinalizeSteps = new List<string>();
|
||||
AutoSettings = new AutoSettings();
|
||||
}
|
||||
|
||||
public GamePreset(GamePreset preset) : this()
|
||||
@@ -73,15 +88,16 @@ namespace ColorControl.Services.GameLauncher
|
||||
|
||||
public override List<string> GetDisplayValues(Config config = null)
|
||||
{
|
||||
var values = new List<string>();
|
||||
var values = new List<string>
|
||||
{
|
||||
name,
|
||||
Path,
|
||||
Parameters,
|
||||
|
||||
values.Add(name);
|
||||
values.Add(Path);
|
||||
values.Add(Parameters);
|
||||
|
||||
values.Add(string.Join(", ", PreLaunchSteps));
|
||||
values.Add(string.Join(", ", PostLaunchSteps));
|
||||
values.Add(string.Join(", ", FinalizeSteps));
|
||||
string.Join(", ", PreLaunchSteps),
|
||||
string.Join(", ", PostLaunchSteps),
|
||||
string.Join(", ", FinalizeSteps)
|
||||
};
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@@ -1,27 +1,120 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Services;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
class GameService : ServiceBase<GamePreset>
|
||||
{
|
||||
//private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public override string ServiceName => "Game";
|
||||
|
||||
protected override string PresetsBaseFilename => "GamePresets.json";
|
||||
|
||||
private ProcessEventDispatcher _processEventDispatcher;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private readonly WinApiService _winApiService;
|
||||
private ServiceManager _serviceManager;
|
||||
private int _lastStartedProcessId;
|
||||
private System.DateTime _lastStartedPresetDateTime = System.DateTime.MinValue;
|
||||
private string _lastStartedProcessPath;
|
||||
private string _configFilename;
|
||||
|
||||
public GameService(AppContextProvider appContextProvider, ServiceManager serviceManager) : base(appContextProvider)
|
||||
public GameServiceConfig Config { get; private set; }
|
||||
|
||||
public GameService(AppContextProvider appContextProvider, ServiceManager serviceManager, ProcessEventDispatcher processEventDispatcher, WinApiAdminService winApiAdminService, WinApiService winApiService) : base(appContextProvider)
|
||||
{
|
||||
LoadConfig();
|
||||
LoadPresets();
|
||||
_serviceManager = serviceManager;
|
||||
_processEventDispatcher = processEventDispatcher;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
_winApiService = winApiService;
|
||||
_processEventDispatcher.RegisterAsyncEventHandler(ProcessEventDispatcher.Event_ProcessChanged, ProcessChanged);
|
||||
}
|
||||
|
||||
private async Task ProcessChanged(object sender, ProcessChangedEventArgs e, CancellationToken token)
|
||||
{
|
||||
if (e.StartedProcesses?.Any() != true || !Config.ApplyExternallyLaunched)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastStartedPresetDateTime > System.DateTime.Now.AddSeconds(-5))
|
||||
{
|
||||
return;
|
||||
}
|
||||
_lastStartedProcessId = 0;
|
||||
|
||||
var startedProcesses = e.StartedProcesses;
|
||||
|
||||
foreach (var startedProcess in startedProcesses)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (await HandleStartedProcess(startedProcess))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (System.Exception) { }
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> HandleStartedProcess(Process process)
|
||||
{
|
||||
GamePreset preset;
|
||||
|
||||
if (_winApiService.IsAdministrator())
|
||||
{
|
||||
var fileName = process.MainModule.FileName;
|
||||
|
||||
preset = _presets.FirstOrDefault(p => fileName.Contains(Path.GetDirectoryName(p.Path), System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
else
|
||||
{
|
||||
var name = process.ProcessName.Replace("-Win64-Shipping", "");
|
||||
preset = _presets.FirstOrDefault(p => Path.GetFileName(p.Path).Contains(name, System.StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
if (preset == null || !preset.AutoSettings.AllowAutoApply)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_lastStartedProcessId != process.Id)
|
||||
{
|
||||
Logger.Debug($"Auto-starting preset {preset.name} for process {process.ProcessName}");
|
||||
|
||||
var mainThreadId = 0;
|
||||
var suspended = false;
|
||||
if (preset.AutoSettings.ProcessAutoAction == ProcessAutoAction.Suspend)
|
||||
{
|
||||
mainThreadId = _winApiAdminService.SuspendMainThread(process.Id);
|
||||
suspended = true;
|
||||
}
|
||||
else if (preset.AutoSettings.ProcessAutoAction == ProcessAutoAction.Restart)
|
||||
{
|
||||
_winApiAdminService.StopProcess(process.Id);
|
||||
process = null;
|
||||
}
|
||||
|
||||
var _ = ExecutePreset(preset, process, suspended ? mainThreadId : 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override List<GamePreset> GetDefaultPresets()
|
||||
@@ -37,6 +130,7 @@ namespace ColorControl.Services.GameLauncher
|
||||
public void GlobalSave()
|
||||
{
|
||||
SavePresets();
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(string idOrName)
|
||||
@@ -57,17 +151,34 @@ namespace ColorControl.Services.GameLauncher
|
||||
return await ApplyPreset(preset, Program.AppContext);
|
||||
}
|
||||
|
||||
public async Task<bool> ApplyPreset(GamePreset preset, AppContext appContext)
|
||||
public async Task<bool> ApplyPreset(GamePreset preset, GlobalContext _)
|
||||
{
|
||||
var result = await ExecutePreset(preset);
|
||||
|
||||
_lastAppliedPreset = preset;
|
||||
|
||||
PresetApplied();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<bool> ExecutePreset(GamePreset preset, Process process = null, int resumeThreadId = default)
|
||||
{
|
||||
var result = true;
|
||||
|
||||
await ExecuteSteps(preset.PreLaunchSteps);
|
||||
|
||||
Process process = null;
|
||||
|
||||
if (!string.IsNullOrEmpty(preset.Path))
|
||||
if (process == null && !string.IsNullOrEmpty(preset.Path))
|
||||
{
|
||||
process = Utils.StartProcess(preset.Path, preset.Parameters, setWorkingDir: true, elevate: preset.RunAsAdministrator, affinityMask: preset.ProcessAffinityMask, priorityClass: preset.ProcessPriorityClass);
|
||||
process = _winApiAdminService.StartProcess(preset.Path, preset.Parameters, setWorkingDir: true, elevate: preset.RunAsAdministrator, affinityMask: preset.ProcessAffinityMask, priorityClass: preset.ProcessPriorityClass);
|
||||
|
||||
_lastStartedPresetDateTime = System.DateTime.Now;
|
||||
_lastStartedProcessId = process.Id;
|
||||
_lastStartedProcessPath = Path.GetDirectoryName(preset.Path);
|
||||
}
|
||||
else if (resumeThreadId != default)
|
||||
{
|
||||
_winApiAdminService.ResumeThread((uint)resumeThreadId);
|
||||
}
|
||||
|
||||
await ExecuteSteps(preset.PostLaunchSteps);
|
||||
@@ -77,16 +188,27 @@ namespace ColorControl.Services.GameLauncher
|
||||
await ExecuteFinalizationStepsAsync(process, preset.FinalizeSteps);
|
||||
}
|
||||
|
||||
_lastAppliedPreset = preset;
|
||||
|
||||
PresetApplied();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task ExecuteFinalizationStepsAsync(Process process, List<string> finalizeSteps)
|
||||
{
|
||||
await process.WaitForExitAsync();
|
||||
await Task.Delay(1000);
|
||||
|
||||
try
|
||||
{
|
||||
if (process.HasExited)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await process.WaitForExitAsync();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex);
|
||||
return;
|
||||
}
|
||||
|
||||
await ExecuteSteps(finalizeSteps);
|
||||
}
|
||||
@@ -140,5 +262,27 @@ namespace ColorControl.Services.GameLauncher
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadConfig()
|
||||
{
|
||||
_configFilename = Path.Combine(_dataPath, "GameConfig.json");
|
||||
try
|
||||
{
|
||||
if (File.Exists(_configFilename))
|
||||
{
|
||||
Config = JsonConvert.DeserializeObject<GameServiceConfig>(File.ReadAllText(_configFilename));
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Logger.Error($"LoadConfig: {ex.Message}");
|
||||
}
|
||||
Config ??= new GameServiceConfig();
|
||||
}
|
||||
|
||||
private void SaveConfig()
|
||||
{
|
||||
Utils.WriteObject(_configFilename, Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace ColorControl.Services.GameLauncher
|
||||
{
|
||||
class GameServiceConfig
|
||||
{
|
||||
public bool ApplyExternallyLaunched { get; set; }
|
||||
|
||||
public GameServiceConfig()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Services;
|
||||
using LgTv;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
@@ -262,8 +263,10 @@ namespace ColorControl.Services.LG
|
||||
AddSetDeviceConfigAction("HDMI_4_icon", typeof(HdmiIcon), "HDMI 4 icon");
|
||||
|
||||
AddGenericPictureAction("soundMode", typeof(SoundMode), category: "sound", title: "Sound Mode");
|
||||
AddGenericPictureAction("smartSoundMode", typeof(OffToOn), category: "sound", title: "Adaptive Sound Control");
|
||||
AddGenericPictureAction("soundOutput", typeof(SoundOutput), category: "sound", title: "Sound Output");
|
||||
AddGenericPictureAction("autoVolume", typeof(OffToOn), category: "sound", title: "Auto Volume");
|
||||
AddGenericPictureAction("virtualSurround", typeof(OffToOn), category: "sound", title: "Virtual Surround");
|
||||
|
||||
//AddGenericPictureAction("enableToastPopup", typeof(OffToOn), category: "option", title: "enableToastPopup");
|
||||
AddSetConfigAction("tv.conti.supportUsedTime", typeof(BoolFalseToTrue), title: "Total Power On Time");
|
||||
@@ -917,7 +920,9 @@ namespace ColorControl.Services.LG
|
||||
|
||||
if (MacAddress != null)
|
||||
{
|
||||
result = WOL.WakeFunctionCheckAdmin(MacAddress, IpAddress);
|
||||
var wolService = Program.ServiceProvider.GetRequiredService<WolService>();
|
||||
|
||||
result = wolService.SendWol(MacAddress, IpAddress);
|
||||
_justWokeUp = true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace ColorControl.Services.LG
|
||||
private void UpdateInfo()
|
||||
{
|
||||
lblTvName.Text = $"Device: {_lgDevice?.Name ?? "No tv selected"}";
|
||||
lblProcessName.Text = $"Current process: {_lgService.MonitorContext?.ForegroundProcess?.ProcessName ?? _lgService.MonitorContext?.LastFullScreenProcessName ?? "No full screen process"}";
|
||||
lblProcessName.Text = $"Current process: {_lgService.CurrentProcessEvent?.ForegroundProcess?.ProcessName ?? _lgService.CurrentProcessEvent?.LastFullScreenProcessName ?? "No full screen process"}";
|
||||
|
||||
UpdateValues();
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ColorControl.Services.LG
|
||||
_trayIcon = trayIcon;
|
||||
_mainHandle = handle;
|
||||
|
||||
_config = Shared.Common.AppContext.CurrentContext.Config;
|
||||
_config = Shared.Common.GlobalContext.CurrentContext.Config;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace ColorControl.Services.LG
|
||||
{
|
||||
FillLgDevices();
|
||||
|
||||
var startUpParams = Shared.Common.AppContext.CurrentContext.StartUpParams;
|
||||
var startUpParams = Shared.Common.GlobalContext.CurrentContext.StartUpParams;
|
||||
|
||||
if (startUpParams.ExecuteLgPreset)
|
||||
{
|
||||
|
||||
@@ -22,19 +22,6 @@ namespace ColorControl.Services.LG
|
||||
{
|
||||
class LgService : ServiceBase<LgPreset>
|
||||
{
|
||||
internal class ProcessMonitorContext
|
||||
{
|
||||
public List<LgDevice> Devices { get; set; }
|
||||
public bool WasFullScreen { get; set; }
|
||||
public Process[] StartedProcesses { get; set; }
|
||||
public Process[] StoppedProcesses { get; set; }
|
||||
public Process[] RunningProcesses { get; set; }
|
||||
public bool IsNotificationDisabled { get; set; }
|
||||
public Process ForegroundProcess { get; set; }
|
||||
public bool ForegroundProcessIsFullScreen { get; set; }
|
||||
public string LastFullScreenProcessName = string.Empty;
|
||||
}
|
||||
|
||||
protected static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public static string LgListAppsJson = "listApps.json";
|
||||
@@ -56,7 +43,6 @@ namespace ColorControl.Services.LG
|
||||
public event EventHandler SelectedDeviceChangedEvent;
|
||||
|
||||
public LgServiceConfig Config { get; private set; }
|
||||
public ProcessMonitorContext MonitorContext { get; private set; }
|
||||
|
||||
protected override string PresetsBaseFilename => "LgPresets.json";
|
||||
|
||||
@@ -75,9 +61,13 @@ namespace ColorControl.Services.LG
|
||||
private int _poweredOffByScreenSaverProcessId;
|
||||
private LgPreset _lastTriggeredPreset;
|
||||
private RestartDetector _restartDetector;
|
||||
private readonly WinApiService _winApiService;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private SynchronizationContext _syncContext;
|
||||
|
||||
public LgService(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, SessionSwitchDispatcher sessionSwitchDispatcher, ProcessEventDispatcher processEventDispatcher, ServiceManager serviceManager, RestartDetector restartDetector) : base(appContextProvider)
|
||||
public ProcessChangedEventArgs CurrentProcessEvent => _processEventDispatcher?.MonitorContext;
|
||||
|
||||
public LgService(AppContextProvider appContextProvider, PowerEventDispatcher powerEventDispatcher, SessionSwitchDispatcher sessionSwitchDispatcher, ProcessEventDispatcher processEventDispatcher, ServiceManager serviceManager, RestartDetector restartDetector, WinApiService winApiService, WinApiAdminService winApiAdminService) : base(appContextProvider)
|
||||
{
|
||||
_allowPowerOn = appContextProvider.GetAppContext().StartUpParams.RunningFromScheduledTask;
|
||||
_powerEventDispatcher = powerEventDispatcher;
|
||||
@@ -87,6 +77,8 @@ namespace ColorControl.Services.LG
|
||||
LgPreset.LgApps = _lgApps;
|
||||
|
||||
_restartDetector = restartDetector;
|
||||
_winApiService = winApiService;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
_syncContext = appContextProvider.GetAppContext().SynchronizationContext;
|
||||
LgTvApiCore.SyncContext = _syncContext;
|
||||
|
||||
@@ -851,7 +843,7 @@ namespace ColorControl.Services.LG
|
||||
var standByScript = Path.Combine(Program.DataDir, "StandByScript.bat");
|
||||
if (File.Exists(standByScript))
|
||||
{
|
||||
Utils.StartProcess(standByScript, hidden: true, wait: true);
|
||||
_winApiAdminService.StartProcess(standByScript, hidden: true, wait: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -911,13 +903,13 @@ namespace ColorControl.Services.LG
|
||||
|
||||
if (File.Exists(resumeScript))
|
||||
{
|
||||
Utils.StartProcess(resumeScript, hidden: true);
|
||||
_winApiAdminService.StartProcess(resumeScript, hidden: true);
|
||||
}
|
||||
}
|
||||
|
||||
private void SendConfigToService()
|
||||
{
|
||||
if (!Utils.IsServiceRunning())
|
||||
if (!_winApiService.IsServiceRunning())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
partial class NvInfoPanel
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
grpNVIDIAInfo = new System.Windows.Forms.GroupBox();
|
||||
btnRefreshNVIDIAInfo = new System.Windows.Forms.Button();
|
||||
tvNVIDIAInfo = new System.Windows.Forms.TreeView();
|
||||
grpNVIDIAInfo.SuspendLayout();
|
||||
SuspendLayout();
|
||||
//
|
||||
// grpNVIDIAInfo
|
||||
//
|
||||
grpNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
grpNVIDIAInfo.Controls.Add(btnRefreshNVIDIAInfo);
|
||||
grpNVIDIAInfo.Controls.Add(tvNVIDIAInfo);
|
||||
grpNVIDIAInfo.Location = new System.Drawing.Point(4, 3);
|
||||
grpNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
grpNVIDIAInfo.Name = "grpNVIDIAInfo";
|
||||
grpNVIDIAInfo.Padding = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
grpNVIDIAInfo.Size = new System.Drawing.Size(643, 547);
|
||||
grpNVIDIAInfo.TabIndex = 5;
|
||||
grpNVIDIAInfo.TabStop = false;
|
||||
grpNVIDIAInfo.Text = "NVIDIA info";
|
||||
//
|
||||
// btnRefreshNVIDIAInfo
|
||||
//
|
||||
btnRefreshNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left;
|
||||
btnRefreshNVIDIAInfo.Location = new System.Drawing.Point(8, 514);
|
||||
btnRefreshNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
btnRefreshNVIDIAInfo.Name = "btnRefreshNVIDIAInfo";
|
||||
btnRefreshNVIDIAInfo.Size = new System.Drawing.Size(88, 27);
|
||||
btnRefreshNVIDIAInfo.TabIndex = 1;
|
||||
btnRefreshNVIDIAInfo.Text = "Refresh";
|
||||
btnRefreshNVIDIAInfo.UseVisualStyleBackColor = true;
|
||||
btnRefreshNVIDIAInfo.Click += btnRefreshNVIDIAInfo_Click;
|
||||
//
|
||||
// tvNVIDIAInfo
|
||||
//
|
||||
tvNVIDIAInfo.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
|
||||
tvNVIDIAInfo.Location = new System.Drawing.Point(8, 22);
|
||||
tvNVIDIAInfo.Margin = new System.Windows.Forms.Padding(4, 3, 4, 3);
|
||||
tvNVIDIAInfo.Name = "tvNVIDIAInfo";
|
||||
tvNVIDIAInfo.Size = new System.Drawing.Size(627, 486);
|
||||
tvNVIDIAInfo.TabIndex = 0;
|
||||
//
|
||||
// NvInfoPanel
|
||||
//
|
||||
AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
|
||||
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
Controls.Add(grpNVIDIAInfo);
|
||||
Name = "NvInfoPanel";
|
||||
Size = new System.Drawing.Size(654, 556);
|
||||
grpNVIDIAInfo.ResumeLayout(false);
|
||||
ResumeLayout(false);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.GroupBox grpNVIDIAInfo;
|
||||
private System.Windows.Forms.Button btnRefreshNVIDIAInfo;
|
||||
private System.Windows.Forms.TreeView tvNVIDIAInfo;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using ColorControl.Shared.Forms;
|
||||
using NvAPIWrapper.Display;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
public partial class NvInfoPanel : UserControl, IModulePanel
|
||||
{
|
||||
private NvService _nvService;
|
||||
|
||||
internal NvInfoPanel(NvService nvService)
|
||||
{
|
||||
_nvService = nvService;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
if (DarkModeUtils.UseDarkMode)
|
||||
{
|
||||
grpNVIDIAInfo.ForeColor = FormUtils.CurrentForeColor;
|
||||
}
|
||||
|
||||
RefreshInfo();
|
||||
}
|
||||
|
||||
public void UpdateInfo()
|
||||
{
|
||||
RefreshInfo();
|
||||
}
|
||||
|
||||
private void btnRefreshNVIDIAInfo_Click(object sender, System.EventArgs e)
|
||||
{
|
||||
}
|
||||
|
||||
private void RefreshInfo()
|
||||
{
|
||||
tvNVIDIAInfo.Nodes.Clear();
|
||||
var displays = Display.GetDisplays();
|
||||
for (var i = 0; i < displays.Length; i++)
|
||||
{
|
||||
var display = displays[i];
|
||||
var node = TreeNodeBuilder.CreateTree(display, $"Display[{i}]");
|
||||
tvNVIDIAInfo.Nodes.Add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing"">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
+36
-18
@@ -82,6 +82,8 @@ namespace ColorControl.Services.NVIDIA
|
||||
miNvDriverSettingsIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvOtherSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvOtherIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvHdmiSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvHdmiIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvOverclocking = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvOverclockingIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvCopyId = new System.Windows.Forms.ToolStripMenuItem();
|
||||
@@ -91,9 +93,9 @@ namespace ColorControl.Services.NVIDIA
|
||||
miNvProfileInspector = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvNovideo = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvTestDithering = new System.Windows.Forms.ToolStripMenuItem();
|
||||
lvNvPresetsToolTip = new System.Windows.Forms.ToolTip(components);
|
||||
mnuNvHdmiSettings = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNvHdmiIncluded = new System.Windows.Forms.ToolStripMenuItem();
|
||||
miNVIDIAInfo = new System.Windows.Forms.ToolStripMenuItem();
|
||||
mnuNvPresets.SuspendLayout();
|
||||
mnuNvSettings.SuspendLayout();
|
||||
SuspendLayout();
|
||||
@@ -326,7 +328,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
mnuNvPresets.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuNvPresets.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvApply, miNvPresetApplyOnStartup, tssNvPresetMenu, mnuNvDisplay, mnuNvPresetsColorSettings, mnuRefreshRate, mnuNvResolution, miNvPresetDithering, miNvHDR, mnuNvDriverSettings, mnuNvOtherSettings, mnuNvHdmiSettings, mnuNvOverclocking, miNvCopyId });
|
||||
mnuNvPresets.Name = "mnuNvPresets";
|
||||
mnuNvPresets.Size = new System.Drawing.Size(185, 318);
|
||||
mnuNvPresets.Size = new System.Drawing.Size(185, 296);
|
||||
mnuNvPresets.Opening += mnuNvPresets_Opening;
|
||||
//
|
||||
// miNvApply
|
||||
@@ -543,7 +545,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
// miNvDriverSettingsIncluded
|
||||
//
|
||||
miNvDriverSettingsIncluded.Name = "miNvDriverSettingsIncluded";
|
||||
miNvDriverSettingsIncluded.Size = new System.Drawing.Size(180, 22);
|
||||
miNvDriverSettingsIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvDriverSettingsIncluded.Text = "Included";
|
||||
miNvDriverSettingsIncluded.Click += miNvDriverSettingsIncluded_Click;
|
||||
//
|
||||
@@ -557,10 +559,24 @@ namespace ColorControl.Services.NVIDIA
|
||||
// miNvOtherIncluded
|
||||
//
|
||||
miNvOtherIncluded.Name = "miNvOtherIncluded";
|
||||
miNvOtherIncluded.Size = new System.Drawing.Size(180, 22);
|
||||
miNvOtherIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvOtherIncluded.Text = "Included";
|
||||
miNvOtherIncluded.Click += miNvOtherIncluded_Click;
|
||||
//
|
||||
// mnuNvHdmiSettings
|
||||
//
|
||||
mnuNvHdmiSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvHdmiIncluded });
|
||||
mnuNvHdmiSettings.Name = "mnuNvHdmiSettings";
|
||||
mnuNvHdmiSettings.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvHdmiSettings.Text = "HDMI Settings";
|
||||
//
|
||||
// miNvHdmiIncluded
|
||||
//
|
||||
miNvHdmiIncluded.Name = "miNvHdmiIncluded";
|
||||
miNvHdmiIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvHdmiIncluded.Text = "Included";
|
||||
miNvHdmiIncluded.Click += miNvHdmiIncluded_Click;
|
||||
//
|
||||
// mnuNvOverclocking
|
||||
//
|
||||
mnuNvOverclocking.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvOverclockingIncluded });
|
||||
@@ -571,7 +587,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
// miNvOverclockingIncluded
|
||||
//
|
||||
miNvOverclockingIncluded.Name = "miNvOverclockingIncluded";
|
||||
miNvOverclockingIncluded.Size = new System.Drawing.Size(180, 22);
|
||||
miNvOverclockingIncluded.Size = new System.Drawing.Size(120, 22);
|
||||
miNvOverclockingIncluded.Text = "Included";
|
||||
miNvOverclockingIncluded.Click += miNvOverclockingIncluded_Click;
|
||||
//
|
||||
@@ -620,9 +636,9 @@ namespace ColorControl.Services.NVIDIA
|
||||
// mnuNvSettings
|
||||
//
|
||||
mnuNvSettings.ImageScalingSize = new System.Drawing.Size(20, 20);
|
||||
mnuNvSettings.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvProfileInspector, miNvNovideo, miNvSettings });
|
||||
mnuNvSettings.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvProfileInspector, miNvNovideo, miNvSettings, miNvTestDithering, miNVIDIAInfo });
|
||||
mnuNvSettings.Name = "mnuLgButtons";
|
||||
mnuNvSettings.Size = new System.Drawing.Size(202, 70);
|
||||
mnuNvSettings.Size = new System.Drawing.Size(202, 136);
|
||||
//
|
||||
// miNvProfileInspector
|
||||
//
|
||||
@@ -645,19 +661,19 @@ namespace ColorControl.Services.NVIDIA
|
||||
miNvSettings.Text = "Settings";
|
||||
miNvSettings.Click += miNvSettings_Click;
|
||||
//
|
||||
// mnuNvHdmiSettings
|
||||
// miNvTestDithering
|
||||
//
|
||||
mnuNvHdmiSettings.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { miNvHdmiIncluded });
|
||||
mnuNvHdmiSettings.Name = "mnuNvHdmiSettings";
|
||||
mnuNvHdmiSettings.Size = new System.Drawing.Size(184, 22);
|
||||
mnuNvHdmiSettings.Text = "HDMI Settings";
|
||||
miNvTestDithering.Name = "miNvTestDithering";
|
||||
miNvTestDithering.Size = new System.Drawing.Size(201, 22);
|
||||
miNvTestDithering.Text = "Test dithering";
|
||||
miNvTestDithering.Click += miNvTestDithering_Click;
|
||||
//
|
||||
// miNvHdmiIncluded
|
||||
// miNVIDIAInfo
|
||||
//
|
||||
miNvHdmiIncluded.Name = "miNvHdmiIncluded";
|
||||
miNvHdmiIncluded.Size = new System.Drawing.Size(180, 22);
|
||||
miNvHdmiIncluded.Text = "Included";
|
||||
miNvHdmiIncluded.Click += miNvHdmiIncluded_Click;
|
||||
miNVIDIAInfo.Name = "miNVIDIAInfo";
|
||||
miNVIDIAInfo.Size = new System.Drawing.Size(201, 22);
|
||||
miNVIDIAInfo.Text = "NVIDIA Info";
|
||||
miNVIDIAInfo.Click += miNVIDIAInfo_Click;
|
||||
//
|
||||
// NvPanel
|
||||
//
|
||||
@@ -760,5 +776,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvOtherIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuNvHdmiSettings;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvHdmiIncluded;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNvTestDithering;
|
||||
private System.Windows.Forms.ToolStripMenuItem miNVIDIAInfo;
|
||||
}
|
||||
}
|
||||
@@ -37,9 +37,9 @@ namespace ColorControl.Services.NVIDIA
|
||||
private readonly AppContextProvider _appContextProvider;
|
||||
private string _lastDisplayRefreshRates = string.Empty;
|
||||
private NotifyIcon _trayIcon;
|
||||
private RpcService _rpcService;
|
||||
private RpcClientService _rpcService;
|
||||
|
||||
public NvPanel(NvService nvService, NotifyIcon trayIcon, IntPtr handle, AppContextProvider appContextProvider, RpcService rpcService)
|
||||
public NvPanel(NvService nvService, NotifyIcon trayIcon, IntPtr handle, AppContextProvider appContextProvider, RpcClientService rpcService)
|
||||
{
|
||||
_nvService = nvService;
|
||||
_trayIcon = trayIcon;
|
||||
@@ -287,17 +287,20 @@ namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
var preset = GetSelectedNvPreset(true);
|
||||
|
||||
var checkState = miNvPresetDitheringEnabled.CheckState;
|
||||
var newCheckState = checkState == CheckState.Checked ? CheckState.Unchecked : checkState == CheckState.Unchecked ? CheckState.Indeterminate : CheckState.Checked;
|
||||
|
||||
if (preset.IsDisplayPreset)
|
||||
{
|
||||
miNvPresetDitheringEnabled.Checked = !miNvPresetDitheringEnabled.Checked;
|
||||
miNvPresetDitheringEnabled.CheckState = newCheckState;
|
||||
|
||||
_nvService.SetDithering(miNvPresetDitheringEnabled.Checked ? NvDitherState.Enabled : NvDitherState.Disabled);
|
||||
_nvService.SetDithering(newCheckState == CheckState.Indeterminate ? NvDitherState.Auto : newCheckState == CheckState.Checked ? NvDitherState.Enabled : NvDitherState.Disabled);
|
||||
|
||||
UpdateDisplayInfoItems();
|
||||
return;
|
||||
}
|
||||
|
||||
preset.ditheringEnabled = !preset.ditheringEnabled;
|
||||
preset.ditheringEnabled = checkState == CheckState.Indeterminate ? null : checkState == CheckState.Checked;
|
||||
|
||||
AddOrUpdateItem();
|
||||
}
|
||||
@@ -395,7 +398,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
miNvPresetColorSettings.Checked = preset.applyColorData;
|
||||
miNvPresetApplyDithering.Checked = preset.applyDithering;
|
||||
miNvPresetDitheringEnabled.Checked = preset.ditheringEnabled;
|
||||
miNvPresetDitheringEnabled.CheckState = preset.ditheringEnabled == null ? CheckState.Indeterminate : preset.ditheringEnabled == true ? CheckState.Checked : CheckState.Unchecked;
|
||||
|
||||
foreach (var item in mnuNvDitheringBitDepth.DropDownItems.OfType<ToolStripMenuItem>())
|
||||
{
|
||||
@@ -1466,7 +1469,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
return;
|
||||
}
|
||||
|
||||
_nvService.ApplyOverclocking(newSettings);
|
||||
_nvService.ApplyOverclocking(new List<NvGpuOcSettings> { newSettings });
|
||||
|
||||
UpdateNvGpuInfo();
|
||||
}
|
||||
@@ -1687,7 +1690,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
private async Task ApplyNvPresetOnStartup(int attempts = 5)
|
||||
{
|
||||
var startUpParams = Shared.Common.AppContext.CurrentContext.StartUpParams;
|
||||
var startUpParams = Shared.Common.GlobalContext.CurrentContext.StartUpParams;
|
||||
|
||||
var presetIdOrName = !string.IsNullOrEmpty(startUpParams.NvidiaPresetIdOrName) ? startUpParams.NvidiaPresetIdOrName : _config.NvPresetId_ApplyOnStartup.ToString();
|
||||
|
||||
@@ -1728,7 +1731,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
if (preset.IsDisplayPreset)
|
||||
{
|
||||
_nvService.SetDithering(preset.ditheringEnabled ? NvDitherState.Enabled : NvDitherState.Disabled, ditheringBits, preset.ditheringMode);
|
||||
_nvService.SetDithering(preset.DitherState, ditheringBits, preset.ditheringMode);
|
||||
|
||||
UpdateDisplayInfoItems();
|
||||
return;
|
||||
@@ -1749,7 +1752,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
if (preset.IsDisplayPreset)
|
||||
{
|
||||
_nvService.SetDithering(preset.ditheringEnabled ? NvDitherState.Enabled : NvDitherState.Disabled, preset.ditheringBits, ditheringMode);
|
||||
_nvService.SetDithering(preset.DitherState, preset.ditheringBits, ditheringMode);
|
||||
|
||||
UpdateDisplayInfoItems();
|
||||
return;
|
||||
@@ -1797,5 +1800,19 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
AddOrUpdateItem();
|
||||
}
|
||||
|
||||
private void miNvTestDithering_Click(object sender, EventArgs e)
|
||||
{
|
||||
var panel = new NvDitherPanel(_nvService);
|
||||
|
||||
MessageForms.ShowControl(panel, "Test dithering");
|
||||
}
|
||||
|
||||
private void miNVIDIAInfo_Click(object sender, EventArgs e)
|
||||
{
|
||||
var panel = new NvInfoPanel(_nvService);
|
||||
|
||||
MessageForms.ShowControl(panel, "NVIDIA Info");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
public bool HDREnabled { get; set; }
|
||||
public bool toggleHDR { get; set; }
|
||||
public bool applyDithering { get; set; }
|
||||
public bool ditheringEnabled { get; set; }
|
||||
public bool? ditheringEnabled { get; set; }
|
||||
public bool applyRefreshRate { get; set; }
|
||||
public uint refreshRate { get; set; }
|
||||
public bool applyResolution { get; set; }
|
||||
@@ -49,6 +49,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
public Display Display { get; set; }
|
||||
[JsonIgnore]
|
||||
public string InfoLine { get; set; }
|
||||
public NvDitherState DitherState => ditheringEnabled.HasValue ? ditheringEnabled == true ? NvDitherState.Enabled : NvDitherState.Disabled : NvDitherState.Auto;
|
||||
|
||||
public NvPreset() : base()
|
||||
{
|
||||
@@ -224,14 +225,19 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
public string GetDitheringDescription(string disabledText = "Disabled")
|
||||
{
|
||||
var dithering = ditheringEnabled ? string.Empty : disabledText;
|
||||
if (ditheringEnabled)
|
||||
if (ditheringEnabled == null && ditheringBits == 0 && ditheringMode == 0)
|
||||
{
|
||||
return "Auto: Disabled";
|
||||
}
|
||||
|
||||
if (ditheringEnabled is null or true)
|
||||
{
|
||||
var ditherBitsDescription = ((NvDitherBits)ditheringBits).GetDescription();
|
||||
var ditherModeDescription = ((NvDitherMode)ditheringMode).GetDescription();
|
||||
dithering = string.Format("{0} {1}", ditherBitsDescription, ditherModeDescription);
|
||||
return string.Format("{0}{1} {2}", ditheringEnabled == null ? "Auto: " : "", ditherBitsDescription, ditherModeDescription);
|
||||
}
|
||||
return dithering;
|
||||
|
||||
return disabledText;
|
||||
}
|
||||
|
||||
public string GetHdmiSettingsDescription()
|
||||
|
||||
@@ -7,6 +7,7 @@ using ColorControl.Shared.Native;
|
||||
using ColorControl.Shared.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using novideo_srgb;
|
||||
using nspector.Common;
|
||||
using nspector.Common.Meta;
|
||||
using NvAPIWrapper.Display;
|
||||
@@ -143,11 +144,15 @@ namespace ColorControl.Services.NVIDIA
|
||||
DRS_RBAR_OPTIONS,
|
||||
DRS_RBAR_SIZE_LIMIT
|
||||
};
|
||||
|
||||
private readonly WinApiService _winApiService;
|
||||
private readonly RpcClientService _rpcClientService;
|
||||
private static NvService ServiceInstance;
|
||||
|
||||
public NvService(AppContextProvider appContextProvider) : base(appContextProvider)
|
||||
public NvService(AppContextProvider appContextProvider, WinApiService winApiService, RpcClientService rpcClientService) : base(appContextProvider)
|
||||
{
|
||||
_winApiService = winApiService;
|
||||
_rpcClientService = rpcClientService;
|
||||
_rpcClientService.Name = nameof(NvService);
|
||||
NvPreset.NvService = this;
|
||||
|
||||
AddJsonConverter(new ColorDataConverter());
|
||||
@@ -159,9 +164,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
{
|
||||
try
|
||||
{
|
||||
var appContextProvider = Program.ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
|
||||
var nvService = new NvService(appContextProvider);
|
||||
var nvService = Program.ServiceProvider.GetRequiredService<NvService>();
|
||||
|
||||
var result = await nvService.ApplyPreset(idOrName);
|
||||
|
||||
@@ -315,6 +318,11 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
if (applyHdr)
|
||||
{
|
||||
if (newHdrEnabled && !hdrEnabled)
|
||||
{
|
||||
MainWindow.BeforeDisplaySettingsChange();
|
||||
}
|
||||
|
||||
SetHDRState(display, newHdrEnabled);
|
||||
}
|
||||
|
||||
@@ -341,7 +349,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
if (preset.applyDithering)
|
||||
{
|
||||
if (!SetDithering(preset.ditheringEnabled ? NvDitherState.Enabled : NvDitherState.Disabled, preset: preset))
|
||||
if (!SetDithering(preset.DitherState, preset: preset))
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
@@ -364,19 +372,17 @@ namespace ColorControl.Services.NVIDIA
|
||||
return Task.FromResult(result);
|
||||
}
|
||||
|
||||
public bool ApplyOverclocking(NvGpuOcSettings setting)
|
||||
{
|
||||
return ApplyOverclocking(new List<NvGpuOcSettings> { setting });
|
||||
}
|
||||
|
||||
public bool ApplyOverclocking(List<NvGpuOcSettings> settings)
|
||||
{
|
||||
if (!Utils.IsAdministrator())
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
var result = PipeUtils.SendMessage(new SvcNvOverclockingMessage
|
||||
var message = new SvcRpcSetNvOverclockingMessage
|
||||
{
|
||||
MethodName = nameof(ApplyOverclocking),
|
||||
OverclockingSettings = settings
|
||||
});
|
||||
};
|
||||
|
||||
var result = _rpcClientService.Call<object>(message);
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
@@ -418,42 +424,26 @@ namespace ColorControl.Services.NVIDIA
|
||||
}
|
||||
}
|
||||
|
||||
public static void ApplyDriverSettings(string profileName, List<KeyValuePair<uint, string>> settings)
|
||||
public void ApplyDriverSettings(string profileName, List<KeyValuePair<uint, string>> settings)
|
||||
{
|
||||
CheckServiceInstance();
|
||||
RefreshProfileSettings();
|
||||
|
||||
ServiceInstance._drs.StoreSettingsToProfile(profileName, settings);
|
||||
_drs.StoreSettingsToProfile(profileName, settings);
|
||||
}
|
||||
|
||||
public static bool RestoreDriverSettings(string profileName, List<KeyValuePair<uint, string>> settings)
|
||||
public bool RestoreDriverSettings(string profileName, List<KeyValuePair<uint, string>> settings)
|
||||
{
|
||||
CheckServiceInstance();
|
||||
|
||||
var result = false;
|
||||
|
||||
foreach (var keyValuePair in settings)
|
||||
{
|
||||
var settingId = keyValuePair.Key;
|
||||
ServiceInstance._drs.ResetValue(profileName, settingId, out result);
|
||||
_drs.ResetValue(profileName, settingId, out result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static NvService CheckServiceInstance()
|
||||
{
|
||||
if (ServiceInstance == null)
|
||||
{
|
||||
var appContextProvider = Program.ServiceProvider.GetRequiredService<AppContextProvider>();
|
||||
|
||||
ServiceInstance = new NvService(appContextProvider);
|
||||
ServiceInstance.Initialize();
|
||||
ServiceInstance.RefreshProfileSettings();
|
||||
}
|
||||
|
||||
return ServiceInstance;
|
||||
}
|
||||
|
||||
private void SetDriverSettings(Dictionary<uint, uint> settings)
|
||||
{
|
||||
var convertedSettings = new List<KeyValuePair<uint, string>>();
|
||||
@@ -853,6 +843,22 @@ namespace ColorControl.Services.NVIDIA
|
||||
//var display = GetCurrentDisplay();
|
||||
//var displayDevice = display.DisplayDevice;
|
||||
|
||||
//var config = DisplayApi.GetDisplayConfig();
|
||||
|
||||
//var config1 = config[0];
|
||||
|
||||
//var pathInfo1 = config1.TargetsInfo.First();
|
||||
|
||||
//var details = pathInfo1.Details.Value;
|
||||
|
||||
//var newDetails = new PathAdvancedTargetInfo(details.Rotation, Scaling.GPUScanOutToNative);
|
||||
|
||||
//var newPathTargetInfo = new PathTargetInfoV2(pathInfo1.DisplayId, newDetails);
|
||||
|
||||
//var newPathInfo = new PathInfoV2(new[] { newPathTargetInfo }, config1.SourceModeInfo);
|
||||
|
||||
//DisplayApi.SetDisplayConfig(new IPathInfo[] { newPathInfo }, DisplayConfigFlags.SaveToPersistence);
|
||||
|
||||
//var info = DisplayApi.GetScanOutConfiguration(displayDevice.DisplayId);
|
||||
|
||||
//var vertices = new float[] {
|
||||
@@ -1023,7 +1029,7 @@ namespace ColorControl.Services.NVIDIA
|
||||
}
|
||||
else
|
||||
{
|
||||
preset.ditheringEnabled = ditherInfo.state != (int)NvDitherState.Disabled;
|
||||
preset.ditheringEnabled = ditherInfo.state == 0 ? null : ditherInfo.state != (int)NvDitherState.Disabled;
|
||||
preset.ditheringBits = (uint)ditherInfo.bits;
|
||||
preset.ditheringMode = (uint)ditherInfo.mode;
|
||||
}
|
||||
@@ -1123,11 +1129,11 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
_drs.GetProfileNames(ref _baseProfileName, false);
|
||||
|
||||
if (!Utils.IsAdministrator())
|
||||
{
|
||||
_drs.ApplySettings += HandleDrsApplySettings;
|
||||
_drs.RestoreSetting += HandleDrsRestoreSetting;
|
||||
}
|
||||
//if (!WinApiService.IsAdministratorStatic())
|
||||
//{
|
||||
_drs.ApplySettings += HandleDrsApplySettings;
|
||||
_drs.RestoreSetting += HandleDrsRestoreSetting;
|
||||
//}
|
||||
|
||||
//SetGpuClocks();
|
||||
|
||||
@@ -1169,10 +1175,9 @@ namespace ColorControl.Services.NVIDIA
|
||||
|
||||
private bool HasPrivilegesForUnexposedApis()
|
||||
{
|
||||
return Utils.IsAdministrator() || _appContextProvider.GetAppContext()?.Config.ElevationMethod != ElevationMethod.UseService || _appContextProvider.GetAppContext()?.IsServiceRunning() != true;
|
||||
return _winApiService.IsAdministrator() || !_winApiService.IsServiceRunning();
|
||||
}
|
||||
|
||||
|
||||
private void HandleDrsApplySettings(object sender, DrsEvent drsEvent)
|
||||
{
|
||||
if (HasPrivilegesForUnexposedApis())
|
||||
@@ -1180,7 +1185,14 @@ namespace ColorControl.Services.NVIDIA
|
||||
return;
|
||||
}
|
||||
|
||||
PipeUtils.SendMessage(new SvcNvDriverSettingsMessage { ProfileName = drsEvent.ProfileName, DriverSettings = drsEvent.Settings });
|
||||
var message = new SvcRpcSetNvDriverSettingsMessage
|
||||
{
|
||||
MethodName = nameof(ApplyDriverSettings),
|
||||
ProfileName = drsEvent.ProfileName,
|
||||
DriverSettings = drsEvent.Settings
|
||||
};
|
||||
|
||||
_rpcClientService.Call<object>(message);
|
||||
|
||||
drsEvent.Handled = true;
|
||||
}
|
||||
@@ -1192,7 +1204,14 @@ namespace ColorControl.Services.NVIDIA
|
||||
return;
|
||||
}
|
||||
|
||||
PipeUtils.SendMessage(new SvcNvDriverSettingsMessage(SvcMessageType.RestoreNvidiaDriverSetting) { ProfileName = drsEvent.ProfileName, DriverSettings = drsEvent.Settings });
|
||||
var message = new SvcRpcSetNvDriverSettingsMessage
|
||||
{
|
||||
MethodName = nameof(RestoreDriverSettings),
|
||||
ProfileName = drsEvent.ProfileName,
|
||||
DriverSettings = drsEvent.Settings
|
||||
};
|
||||
|
||||
_rpcClientService.Call<object>(message);
|
||||
|
||||
drsEvent.Handled = true;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using ColorControl.Services.Common;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Services;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -114,7 +115,7 @@ namespace ColorControl.Services.Samsung
|
||||
|
||||
AddInvokableAction("WOL", WakeAction);
|
||||
AddInvokableAction("ServiceMenu", ServiceMenuAction, true);
|
||||
AddInternalPresetAction(new SamsungPreset("PictureOff", null, new[] { "KEY_AD:1200", "KEY_DOWN:300", "KEY_DOWN:300", "KEY_ENTER" }));
|
||||
AddInternalPresetAction(new SamsungPreset("PictureOff", null, new[] { "KEY_AD:1400", "KEY_DOWN:200", "KEY_DOWN:200", "KEY_ENTER" }));
|
||||
AddInternalPresetAction(new SamsungPreset("PictureOn", null, new[] { "KEY_RETURN:1000", "KEY_RETURN", "KEY_RETURN" }));
|
||||
|
||||
_serviceManager = Program.ServiceProvider.GetRequiredService<ServiceManager>();
|
||||
@@ -328,7 +329,9 @@ namespace ColorControl.Services.Samsung
|
||||
|
||||
if (MacAddress != null)
|
||||
{
|
||||
result = WOL.WakeFunctionCheckAdmin(MacAddress, IpAddress);
|
||||
var wolService = Program.ServiceProvider.GetRequiredService<WolService>();
|
||||
|
||||
result = wolService.SendWol(MacAddress, IpAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -385,7 +388,7 @@ namespace ColorControl.Services.Samsung
|
||||
return $"{(IsDummy ? string.Empty : (IsCustom ? "Custom: " : "Auto detect: "))}{Name}{(!string.IsNullOrEmpty(IpAddress) ? ", " + IpAddress : string.Empty)}";
|
||||
}
|
||||
|
||||
internal async Task<bool> ExecutePresetAsync(SamsungPreset preset, Shared.Common.AppContext appContext = null, SamsungServiceConfig config = null)
|
||||
internal async Task<bool> ExecutePresetAsync(SamsungPreset preset, Shared.Common.GlobalContext appContext = null, SamsungServiceConfig config = null)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
@@ -463,7 +466,7 @@ namespace ColorControl.Services.Samsung
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task ExecuteStepsAsync(SamsungPreset preset, Shared.Common.AppContext appContext, SamsungServiceConfig config)
|
||||
private async Task ExecuteStepsAsync(SamsungPreset preset, Shared.Common.GlobalContext appContext, SamsungServiceConfig config)
|
||||
{
|
||||
foreach (var step in preset.Steps)
|
||||
{
|
||||
@@ -521,7 +524,7 @@ namespace ColorControl.Services.Samsung
|
||||
}
|
||||
}
|
||||
|
||||
public async Task ExecuteActionAsync(InvokableAction action, string[] parameters, Shared.Common.AppContext appContext, SamsungServiceConfig config)
|
||||
public async Task ExecuteActionAsync(InvokableAction action, string[] parameters, Shared.Common.GlobalContext appContext, SamsungServiceConfig config)
|
||||
{
|
||||
if (action.Preset != null)
|
||||
{
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace ColorControl.Services.Samsung
|
||||
_amdService = amdService;
|
||||
_mainHandle = handle;
|
||||
|
||||
_config = Shared.Common.AppContext.CurrentContext.Config;
|
||||
_config = Shared.Common.GlobalContext.CurrentContext.Config;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace ColorControl.Services.Samsung
|
||||
{
|
||||
FillSamsungDevices();
|
||||
|
||||
var startUpParams = Shared.Common.AppContext.CurrentContext.StartUpParams;
|
||||
var startUpParams = Shared.Common.GlobalContext.CurrentContext.StartUpParams;
|
||||
|
||||
if (startUpParams.ExecuteSamsungPreset)
|
||||
{
|
||||
@@ -1114,7 +1114,7 @@ Do you want to continue?";
|
||||
return;
|
||||
}
|
||||
|
||||
await device.ExecuteActionAsync(action, null, Shared.Common.AppContext.CurrentContext, _samsungService.Config);
|
||||
await device.ExecuteActionAsync(action, null, Shared.Common.GlobalContext.CurrentContext, _samsungService.Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,16 +33,17 @@ namespace ColorControl.Services.Samsung
|
||||
private readonly SessionSwitchDispatcher _sessionSwitchDispatcher;
|
||||
private readonly RestartDetector _restartDetector;
|
||||
private readonly ProcessEventDispatcher _processEventDispatcher;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private string _configFilename;
|
||||
private bool _poweredOffByScreenSaver;
|
||||
private int _poweredOffByScreenSaverProcessId;
|
||||
private object _lastTriggeredPreset;
|
||||
private List<SamsungApp> _samsungApps = new List<SamsungApp>();
|
||||
private Shared.Common.AppContext _appContext;
|
||||
private Shared.Common.GlobalContext _appContext;
|
||||
|
||||
public List<SamsungDevice> Devices { get; private set; }
|
||||
|
||||
public SamsungService(AppContextProvider appContextProvider, ServiceManager serviceManager, PowerEventDispatcher powerEventDispatcher, SessionSwitchDispatcher sessionSwitchDispatcher, RestartDetector restartDetector, ProcessEventDispatcher processEventDispatcher) : base(appContextProvider)
|
||||
public SamsungService(AppContextProvider appContextProvider, ServiceManager serviceManager, PowerEventDispatcher powerEventDispatcher, SessionSwitchDispatcher sessionSwitchDispatcher, RestartDetector restartDetector, ProcessEventDispatcher processEventDispatcher, WinApiAdminService winApiAdminService) : base(appContextProvider)
|
||||
{
|
||||
_appContext = appContextProvider.GetAppContext();
|
||||
_allowPowerOn = _appContext.StartUpParams.RunningFromScheduledTask;
|
||||
@@ -51,6 +52,7 @@ namespace ColorControl.Services.Samsung
|
||||
_sessionSwitchDispatcher = sessionSwitchDispatcher;
|
||||
_restartDetector = restartDetector;
|
||||
_processEventDispatcher = processEventDispatcher;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
SamTvConnection.SyncContext = _appContext.SynchronizationContext;
|
||||
|
||||
LoadConfig();
|
||||
@@ -267,7 +269,7 @@ namespace ColorControl.Services.Samsung
|
||||
return await ApplyPreset(preset, _appContext);
|
||||
}
|
||||
|
||||
private async Task<bool> ApplyPreset(SamsungPreset preset, Shared.Common.AppContext appContext)
|
||||
private async Task<bool> ApplyPreset(SamsungPreset preset, Shared.Common.GlobalContext appContext)
|
||||
{
|
||||
var result = true;
|
||||
|
||||
@@ -368,7 +370,7 @@ namespace ColorControl.Services.Samsung
|
||||
var standByScript = Path.Combine(Program.DataDir, "StandByScript.bat");
|
||||
if (File.Exists(standByScript))
|
||||
{
|
||||
Utils.StartProcess(standByScript, hidden: true, wait: true);
|
||||
_winApiAdminService.StartProcess(standByScript, hidden: true, wait: true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +430,7 @@ namespace ColorControl.Services.Samsung
|
||||
|
||||
if (File.Exists(resumeScript))
|
||||
{
|
||||
Utils.StartProcess(resumeScript, hidden: true);
|
||||
_winApiAdminService.StartProcess(resumeScript, hidden: true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
using ColorControl.Services.EventDispatcher;
|
||||
using ColorControl.Services.LG;
|
||||
using ColorControl.Services.NVIDIA;
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Services;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Newtonsoft.Json;
|
||||
using NLog;
|
||||
@@ -21,11 +21,19 @@ namespace ColorControl.Svc
|
||||
{
|
||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||
private readonly SessionSwitchDispatcher _sessionSwitchDispatcher;
|
||||
private readonly RpcServerService _rpcServerService;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
private readonly WolService _wolService;
|
||||
private static string LgConfigFile = "LgConfig.json";
|
||||
|
||||
public ColorControlBackgroundService(SessionSwitchDispatcher sessionSwitchDispatcher)
|
||||
public string PipeName { get; set; } = PipeUtils.ServicePipe;
|
||||
|
||||
public ColorControlBackgroundService(SessionSwitchDispatcher sessionSwitchDispatcher, RpcServerService rpcServerService, WinApiAdminService winApiAdminService, WolService wolService)
|
||||
{
|
||||
_sessionSwitchDispatcher = sessionSwitchDispatcher;
|
||||
_rpcServerService = rpcServerService;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
_wolService = wolService;
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
@@ -37,7 +45,10 @@ namespace ColorControl.Svc
|
||||
//var lgService = new LgService(Program.DataDir, true);
|
||||
//lgService.InstallEventHandlers(true);
|
||||
|
||||
await WakeDevicesAsync();
|
||||
if (PipeName == PipeUtils.ServicePipe)
|
||||
{
|
||||
await WakeDevicesAsync();
|
||||
}
|
||||
|
||||
var securityIdentifier = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);
|
||||
|
||||
@@ -50,7 +61,7 @@ namespace ColorControl.Svc
|
||||
{
|
||||
Logger.Debug("WAITING FOR MESSAGE...");
|
||||
|
||||
var pipeServer = NamedPipeServerStreamAcl.Create("testpipe", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 1024, 1024, ps);
|
||||
var pipeServer = NamedPipeServerStreamAcl.Create(PipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 1024, 1024, ps);
|
||||
|
||||
await pipeServer.WaitForConnectionAsync(stoppingToken);
|
||||
|
||||
@@ -113,39 +124,31 @@ namespace ColorControl.Svc
|
||||
SvcMessageType.SetLgConfig => HandleSetLgConfigMessage(message),
|
||||
SvcMessageType.GetLog => HandleGetLogMessage(message),
|
||||
SvcMessageType.ClearLog => HandleClearLogMessage(message),
|
||||
SvcMessageType.ExecuteRpc => await HandleExecuteRpcCommand(message),
|
||||
SvcMessageType.ExecuteRpcGeneric => await HandleExecuteRpcGenericCommand(JsonConvert.DeserializeObject<SvcRpcMessage>(json)),
|
||||
SvcMessageType.ExecuteRpcGeneric => await _rpcServerService.ExecuteRpcAsync(JsonConvert.DeserializeObject<SvcRpcMessage>(json)),
|
||||
SvcMessageType.ExecuteRpcGenericTyped => await HandleRpcTypedAsync(JsonConvert.DeserializeObject<SvcRpcMessageTyped>(json), json),
|
||||
SvcMessageType.ExecuteUpdate => await HandleExecuteUpdateCommandAsync(JsonConvert.DeserializeObject<SvcInstallUpdateMessage>(json)),
|
||||
SvcMessageType.RestartAfterUpdate => HandleRestartAfterUpdateMessage(),
|
||||
SvcMessageType.ApplyNvidiaDriverSettings => HandleNvDriverSettingsMessage(JsonConvert.DeserializeObject<SvcNvDriverSettingsMessage>(json)),
|
||||
SvcMessageType.RestoreNvidiaDriverSetting => HandleNvRestoreDriverSettingsMessage(JsonConvert.DeserializeObject<SvcNvDriverSettingsMessage>(json)),
|
||||
SvcMessageType.ApplyNvidiaOverclocking => HandleNvOverclockingMessage(JsonConvert.DeserializeObject<SvcNvOverclockingMessage>(json)),
|
||||
_ => SvcResultMessage.FromResult(false, "Unexpected message type")
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<SvcResultMessage> HandleExecuteRpcCommand(SvcMessage message)
|
||||
private async Task<SvcResultMessage> HandleRpcTypedAsync(SvcRpcMessageTyped message, string json)
|
||||
{
|
||||
var args = message.Data.Split(' ');
|
||||
var typeName = message.TypeName;
|
||||
|
||||
var startUpParams = StartUpParams.Parse(args);
|
||||
Logger.Debug($"TypeName: {typeName}");
|
||||
|
||||
return SvcResultMessage.FromResult(await CommandLineHandler.HandleStartupParams(startUpParams, null));
|
||||
}
|
||||
var type = Type.GetType($"ColorControl.Shared.Contracts.{typeName}, Shared");
|
||||
|
||||
private async Task<SvcResultMessage> HandleExecuteRpcGenericCommand(SvcRpcMessage message)
|
||||
{
|
||||
var service = NvService.CheckServiceInstance();
|
||||
Logger.Debug($"Type: {type?.Name}");
|
||||
|
||||
var method = service.GetType().GetMethod(message.MethodName);
|
||||
var typedMessage = JsonConvert.DeserializeObject(json, type) as SvcRpcMessageTyped;
|
||||
|
||||
var result = method.Invoke(service, message.Arguments);
|
||||
Logger.Debug($"Msg: {typedMessage?.MethodName}");
|
||||
|
||||
var data = JsonConvert.SerializeObject(result);
|
||||
|
||||
return SvcResultMessage.FromResult(data);
|
||||
return await _rpcServerService.ExecuteRpcTypedAsync(typedMessage);
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleSetLgConfigMessage(SvcMessage message)
|
||||
@@ -201,28 +204,7 @@ namespace ColorControl.Svc
|
||||
|
||||
private SvcResultMessage HandleRestartAfterUpdateMessage()
|
||||
{
|
||||
Utils.StartProcess("cmd.exe", $@"/C net stop ""{Utils.SERVICE_NAME}"" && net start ""{Utils.SERVICE_NAME}""", true);
|
||||
|
||||
return SvcResultMessage.FromResult(true);
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleNvDriverSettingsMessage(SvcNvDriverSettingsMessage message)
|
||||
{
|
||||
NvService.ApplyDriverSettings(message.ProfileName, message.DriverSettings);
|
||||
|
||||
return SvcResultMessage.FromResult(true);
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleNvRestoreDriverSettingsMessage(SvcNvDriverSettingsMessage message)
|
||||
{
|
||||
var result = NvService.RestoreDriverSettings(message.ProfileName, message.DriverSettings);
|
||||
|
||||
return SvcResultMessage.FromResult(result);
|
||||
}
|
||||
|
||||
private SvcResultMessage HandleNvOverclockingMessage(SvcNvOverclockingMessage message)
|
||||
{
|
||||
NvService.CheckServiceInstance().ApplyOverclocking(message.OverclockingSettings);
|
||||
_winApiAdminService.StartProcess("cmd.exe", $@"/C net stop ""{Utils.SERVICE_NAME}"" && net start ""{Utils.SERVICE_NAME}""", true);
|
||||
|
||||
return SvcResultMessage.FromResult(true);
|
||||
}
|
||||
@@ -252,7 +234,7 @@ namespace ColorControl.Svc
|
||||
{
|
||||
for (var i = 0; i < config.PowerOnRetries; i++)
|
||||
{
|
||||
WOL.WakeFunction(wakeDevice.MacAddress, wakeDevice.IpAddress);
|
||||
_wolService.SendWol(wakeDevice.MacAddress, wakeDevice.IpAddress);
|
||||
|
||||
await Task.Delay(1000);
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Forms;
|
||||
using ColorControl.Shared.Services;
|
||||
using ColorControl.Shared.XForms;
|
||||
using DJ;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NLog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -19,16 +21,18 @@ namespace ColorControl.XForms
|
||||
private static LogWindow _window;
|
||||
|
||||
private int _logLevelIndex;
|
||||
private readonly WinApiAdminService _winApiAdminService;
|
||||
|
||||
public int LogLevelIndex { get => _logLevelIndex; set => _logLevelIndex = value; }
|
||||
|
||||
public LogWindow()
|
||||
public LogWindow(WinApiAdminService winApiAdminService)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
LogLevelIndex = LogLevel.FromString(Shared.Common.AppContext.CurrentContext.Config.LogLevel).Ordinal;
|
||||
LogLevelIndex = LogLevel.FromString(GlobalContext.CurrentContext.Config.LogLevel).Ordinal;
|
||||
|
||||
DataContext = this;
|
||||
_winApiAdminService = winApiAdminService;
|
||||
}
|
||||
|
||||
private void OnRequestNavigate(object sender, RequestNavigateEventArgs e)
|
||||
@@ -47,7 +51,7 @@ namespace ColorControl.XForms
|
||||
new Application();
|
||||
}
|
||||
|
||||
_window ??= new LogWindow();
|
||||
_window ??= Program.ServiceProvider.GetRequiredService<LogWindow>();
|
||||
|
||||
if (show)
|
||||
{
|
||||
@@ -77,7 +81,7 @@ namespace ColorControl.XForms
|
||||
|
||||
private void RawLog_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var context = Shared.Common.AppContext.CurrentContext;
|
||||
var context = Shared.Common.GlobalContext.CurrentContext;
|
||||
|
||||
string logFile;
|
||||
if (tabControl.SelectedIndex == 0)
|
||||
@@ -86,7 +90,9 @@ namespace ColorControl.XForms
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Utils.IsServiceRunning())
|
||||
var winApiService = Program.ServiceProvider.GetRequiredService<WinApiService>();
|
||||
|
||||
if (!winApiService.IsServiceRunning())
|
||||
{
|
||||
MessageForms.WarningOk("Service is not running");
|
||||
return;
|
||||
@@ -109,7 +115,7 @@ namespace ColorControl.XForms
|
||||
return;
|
||||
}
|
||||
|
||||
Utils.StartProcess(logFile);
|
||||
_winApiAdminService.StartProcess(logFile);
|
||||
}
|
||||
|
||||
private void LoadOlder_Click(object sender, RoutedEventArgs e)
|
||||
@@ -128,7 +134,7 @@ namespace ColorControl.XForms
|
||||
|
||||
private void LogLevel_Changed(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||
{
|
||||
var context = Shared.Common.AppContext.CurrentContext;
|
||||
var context = Shared.Common.GlobalContext.CurrentContext;
|
||||
|
||||
var logLevel = LogLevel.FromOrdinal(_logLevelIndex);
|
||||
|
||||
@@ -144,7 +150,7 @@ namespace ColorControl.XForms
|
||||
return;
|
||||
}
|
||||
|
||||
var context = Shared.Common.AppContext.CurrentContext;
|
||||
var context = Shared.Common.GlobalContext.CurrentContext;
|
||||
|
||||
var lines = LoadLog();
|
||||
|
||||
@@ -160,7 +166,9 @@ namespace ColorControl.XForms
|
||||
return Utils.ReadLines(Program.LogFilename);
|
||||
}
|
||||
|
||||
if (Utils.IsServiceRunning())
|
||||
var winApiService = Program.ServiceProvider.GetRequiredService<WinApiService>();
|
||||
|
||||
if (winApiService.IsServiceRunning())
|
||||
{
|
||||
var message = new SvcMessage { MessageType = SvcMessageType.GetLog };
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using nspector.Native.NVAPI2;
|
||||
using System;
|
||||
using nvw = nspector.Native.NVAPI2.NvapiDrsWrapper;
|
||||
|
||||
namespace nspector.Common
|
||||
@@ -38,6 +37,8 @@ namespace nspector.Common
|
||||
if (nvRes != NvAPI_Status.NVAPI_OK)
|
||||
throw new NvapiException("DRS_LoadSettings", nvRes);
|
||||
}
|
||||
|
||||
var dRes = nvw.DRS_DecryptSession(GlobalSession);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -380,13 +380,15 @@ namespace nspector.Common
|
||||
|
||||
public SettingMeta GetSettingMeta(uint settingId, SettingViewMode viewMode = SettingViewMode.Normal)
|
||||
{
|
||||
if (settingMetaCache.ContainsKey(settingId))
|
||||
var settingMeta = settingMetaCache.GetValueOrDefault(settingId);
|
||||
|
||||
if (settingMeta != null)
|
||||
{
|
||||
return PostProcessMeta(settingId, settingMetaCache[settingId], viewMode);
|
||||
return PostProcessMeta(settingId, settingMeta, viewMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
var settingMeta = CreateSettingMeta(settingId);
|
||||
settingMeta = CreateSettingMeta(settingId);
|
||||
settingMetaCache.Add(settingId, settingMeta);
|
||||
return PostProcessMeta(settingId, settingMeta, viewMode);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,29 @@ namespace nspector.Common
|
||||
public event EventHandler<DrsEvent>? RestoreSetting;
|
||||
public bool ExternalApplySettings => ApplySettings != null;
|
||||
|
||||
const uint DRS_NGX_FORCE_DLAA = 0x10E41DF4;
|
||||
const uint DRS_NGX_SCALE_RATIO = 0x10E41DF5;
|
||||
|
||||
private NVDRS_SETTING[] HiddenSettings = new[]
|
||||
{
|
||||
new NVDRS_SETTING {
|
||||
version = nvw.NVDRS_SETTING_VER,
|
||||
settingId = DRS_NGX_FORCE_DLAA,
|
||||
settingType = NVDRS_SETTING_TYPE.NVDRS_DWORD_TYPE,
|
||||
currentValue = new NVDRS_SETTING_UNION {
|
||||
dwordValue = 0u
|
||||
}
|
||||
},
|
||||
new NVDRS_SETTING {
|
||||
version = nvw.NVDRS_SETTING_VER,
|
||||
settingId = DRS_NGX_SCALE_RATIO,
|
||||
settingType = NVDRS_SETTING_TYPE.NVDRS_DWORD_TYPE,
|
||||
currentValue = new NVDRS_SETTING_UNION {
|
||||
dwordValue = 0u
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public DrsSettingsService(DrsSettingsMetaService metaService, DrsDecrypterService decrpterService)
|
||||
: base(metaService, decrpterService)
|
||||
{
|
||||
@@ -180,6 +203,30 @@ namespace nspector.Common
|
||||
return lstResult;
|
||||
}
|
||||
|
||||
public string? GetProfileNameByApps(string appName)
|
||||
{
|
||||
string? name = null;
|
||||
|
||||
DrsSession((hSession) =>
|
||||
{
|
||||
var profileHandles = EnumProfileHandles(hSession);
|
||||
foreach (IntPtr hProfile in profileHandles)
|
||||
{
|
||||
var apps = GetProfileApplications(hSession, hProfile);
|
||||
|
||||
if (apps.Any(a => a.appName.Equals(appName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var profile = GetProfileInfo(hSession, hProfile);
|
||||
name = profile.profileName;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
public void CreateProfile(string profileName, string applicationName = null)
|
||||
{
|
||||
DrsSession((hSession) =>
|
||||
@@ -541,7 +588,7 @@ namespace nspector.Common
|
||||
|
||||
foreach (var settingId in settingIds)
|
||||
{
|
||||
var setting = ReadSetting(hSession, hProfile, settingId);
|
||||
var setting = ReadSetting(hSession, hProfile, settingId, profileName);
|
||||
if (setting != null)
|
||||
result.Add(CreateSettingItem(setting.Value));
|
||||
else
|
||||
@@ -551,6 +598,29 @@ namespace nspector.Common
|
||||
}
|
||||
}
|
||||
|
||||
var isBaseProfile = profileName.Contains("Base Profile", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
if (isBaseProfile)
|
||||
{
|
||||
var hiddenSettings = HiddenSettings.Where(hs => !result.Any(s => s.SettingId == hs.settingId)).ToList();
|
||||
|
||||
foreach (var hiddenSetting in hiddenSettings)
|
||||
{
|
||||
var setting = ReadSetting(hSession, hProfile, hiddenSetting.settingId);
|
||||
|
||||
if (setting != null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
result.Add(CreateSettingItem(hiddenSetting));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.RemoveAll(s => HiddenSettings.Any(hs => hs.settingId == s.SettingId));
|
||||
}
|
||||
|
||||
if (skipApplications)
|
||||
{
|
||||
return null;
|
||||
|
||||
@@ -63,6 +63,13 @@ namespace nspector.Common
|
||||
}
|
||||
else
|
||||
{
|
||||
if (profileName.Contains("Base Profile", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var res = nvw.DRS_GetBaseProfile(hSession, ref hProfile);
|
||||
|
||||
return hProfile;
|
||||
}
|
||||
|
||||
var nvRes = nvw.DRS_FindProfileByName(hSession, new StringBuilder(profileName), ref hProfile);
|
||||
|
||||
if (nvRes == NvAPI_Status.NVAPI_PROFILE_NOT_FOUND)
|
||||
@@ -174,7 +181,7 @@ namespace nspector.Common
|
||||
|
||||
}
|
||||
|
||||
protected NVDRS_SETTING? ReadSetting(IntPtr hSession, IntPtr hProfile, uint settingId)
|
||||
protected NVDRS_SETTING? ReadSetting(IntPtr hSession, IntPtr hProfile, uint settingId, string? profileName = null)
|
||||
{
|
||||
var newSetting = new NVDRS_SETTING()
|
||||
{
|
||||
@@ -190,8 +197,13 @@ namespace nspector.Common
|
||||
|
||||
if (decrypter != null)
|
||||
{
|
||||
var profile = GetProfileInfo(hSession, hProfile);
|
||||
decrypter.DecryptSettingIfNeeded(profile.profileName, ref newSetting);
|
||||
if (profileName == null)
|
||||
{
|
||||
var profile = GetProfileInfo(hSession, hProfile);
|
||||
profileName = profile.profileName;
|
||||
}
|
||||
|
||||
decrypter.DecryptSettingIfNeeded(profileName, ref newSetting);
|
||||
}
|
||||
|
||||
return newSetting;
|
||||
@@ -254,10 +266,13 @@ namespace nspector.Common
|
||||
protected List<NVDRS_SETTING> GetProfileSettings(IntPtr hSession, IntPtr hProfile, NVDRS_PROFILE profile = default(NVDRS_PROFILE))
|
||||
{
|
||||
uint settingCount = 40;
|
||||
var settings = new NVDRS_SETTING[settingCount];
|
||||
settings[0].version = NvapiDrsWrapper.NVDRS_SETTING_VER;
|
||||
|
||||
var esRes = NvapiDrsWrapper.DRS_EnumSettings(hSession, hProfile, 0, ref settingCount, ref settings);
|
||||
NVDRS_SETTING[] settings;
|
||||
|
||||
//var settings = new NVDRS_SETTING[settingCount];
|
||||
//settings[0].version = NvapiDrsWrapper.NVDRS_SETTING_VER;
|
||||
|
||||
var esRes = NvapiDrsWrapper.DRS_EnumSettings(hSession, hProfile, 0, ref settingCount, out settings);
|
||||
|
||||
if (esRes == NvAPI_Status.NVAPI_END_ENUMERATION)
|
||||
return new List<NVDRS_SETTING>();
|
||||
@@ -282,11 +297,14 @@ namespace nspector.Common
|
||||
|
||||
protected List<NVDRS_APPLICATION_V3> GetProfileApplications(IntPtr hSession, IntPtr hProfile)
|
||||
{
|
||||
uint appCount = 512;
|
||||
var apps = new NVDRS_APPLICATION_V3[512];
|
||||
apps[0].version = NvapiDrsWrapper.NVDRS_APPLICATION_VER_V3;
|
||||
uint appCount = 8;
|
||||
|
||||
var esRes = NvapiDrsWrapper.DRS_EnumApplications(hSession, hProfile, 0, ref appCount, ref apps);
|
||||
NVDRS_APPLICATION_V3[] apps;
|
||||
|
||||
//var apps = new NVDRS_APPLICATION_V3[8];
|
||||
//apps[0].version = NvapiDrsWrapper.NVDRS_APPLICATION_VER_V3;
|
||||
|
||||
var esRes = NvapiDrsWrapper.DRS_EnumApplications(hSession, hProfile, 0, ref appCount, out apps);
|
||||
|
||||
if (esRes == NvAPI_Status.NVAPI_END_ENUMERATION)
|
||||
return new List<NVDRS_APPLICATION_V3>();
|
||||
|
||||
@@ -489,6 +489,10 @@ namespace nspector.Native.NVAPI2
|
||||
public delegate NvAPI_Status DRS_DestroySessionDelegate(IntPtr hSession);
|
||||
public static readonly DRS_DestroySessionDelegate DRS_DestroySession;
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate NvAPI_Status DRS_DecryptSessionDelegate(IntPtr hSession);
|
||||
public static readonly DRS_DecryptSessionDelegate DRS_DecryptSession;
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate NvAPI_Status DRS_LoadSettingsDelegate(IntPtr hSession);
|
||||
public static readonly DRS_LoadSettingsDelegate DRS_LoadSettings;
|
||||
@@ -568,25 +572,39 @@ namespace nspector.Native.NVAPI2
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
private delegate NvAPI_Status DRS_EnumApplicationsDelegate(IntPtr hSession, IntPtr hProfile, uint startIndex, ref uint appCount, IntPtr pApplication);
|
||||
private static readonly DRS_EnumApplicationsDelegate DRS_EnumApplicationsInternal;
|
||||
public static NvAPI_Status DRS_EnumApplications<TDrsAppVersion>(IntPtr hSession, IntPtr hProfile, uint startIndex, ref uint appCount, ref TDrsAppVersion[] apps)
|
||||
|
||||
|
||||
[ThreadStatic]
|
||||
private static IntPtr pSettingsApps;
|
||||
[ThreadStatic]
|
||||
private static NVDRS_APPLICATION_V3[] drsApps;
|
||||
|
||||
public static NvAPI_Status DRS_EnumApplications(IntPtr hSession, IntPtr hProfile, uint startIndex, ref uint appCount, out NVDRS_APPLICATION_V3[] apps)
|
||||
{
|
||||
NvAPI_Status res;
|
||||
|
||||
IntPtr pSettings;
|
||||
NativeArrayHelper.SetArrayData(apps, out pSettings);
|
||||
//IntPtr pSettings;
|
||||
|
||||
if (pSettingsApps == IntPtr.Zero)
|
||||
{
|
||||
drsApps = new NVDRS_APPLICATION_V3[8];
|
||||
drsApps[0].version = NvapiDrsWrapper.NVDRS_APPLICATION_VER_V3;
|
||||
NativeArrayHelper.SetArrayData(drsApps, out pSettingsApps);
|
||||
}
|
||||
|
||||
//NativeArrayHelper.SetArrayData(apps, out pSettingsApps);
|
||||
try
|
||||
{
|
||||
res = DRS_EnumApplicationsInternal(hSession, hProfile, startIndex, ref appCount, pSettings);
|
||||
apps = NativeArrayHelper.GetArrayData<TDrsAppVersion>(pSettings, (int)appCount);
|
||||
res = DRS_EnumApplicationsInternal(hSession, hProfile, startIndex, ref appCount, pSettingsApps);
|
||||
apps = NativeArrayHelper.GetArrayData<NVDRS_APPLICATION_V3>(pSettingsApps, (int)appCount);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Marshal.FreeHGlobal(pSettings);
|
||||
//Marshal.FreeHGlobal(pSettings);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate NvAPI_Status DRS_FindApplicationByNameDelegate(IntPtr hSession, [MarshalAs(UnmanagedType.LPWStr, SizeConst = (int)NvapiDrsWrapper.NVAPI_UNICODE_STRING_MAX)] StringBuilder appName, ref IntPtr phProfile, ref NVDRS_APPLICATION_V3 pApplication);
|
||||
public static readonly DRS_FindApplicationByNameDelegate DRS_FindApplicationByName;
|
||||
@@ -616,14 +634,18 @@ namespace nspector.Native.NVAPI2
|
||||
private static readonly DRS_EnumSettingsDelegate DRS_EnumSettingsInternal;
|
||||
[ThreadStatic]
|
||||
private static IntPtr pSettings;
|
||||
[ThreadStatic]
|
||||
private static NVDRS_SETTING[] drsSettings;
|
||||
|
||||
public static NvAPI_Status DRS_EnumSettings(IntPtr hSession, IntPtr hProfile, uint startIndex, ref uint settingsCount, ref NVDRS_SETTING[] settings)
|
||||
public static NvAPI_Status DRS_EnumSettings(IntPtr hSession, IntPtr hProfile, uint startIndex, ref uint settingsCount, out NVDRS_SETTING[] settings)
|
||||
{
|
||||
NvAPI_Status res;
|
||||
|
||||
if (pSettings == IntPtr.Zero)
|
||||
{
|
||||
NativeArrayHelper.SetArrayData(settings, out pSettings);
|
||||
drsSettings = new NVDRS_SETTING[settingsCount];
|
||||
drsSettings[0].version = NvapiDrsWrapper.NVDRS_SETTING_VER;
|
||||
NativeArrayHelper.SetArrayData(drsSettings, out pSettings);
|
||||
}
|
||||
try
|
||||
{
|
||||
@@ -769,6 +791,8 @@ namespace nspector.Native.NVAPI2
|
||||
GetDelegate(0xFA5F6134, out DRS_RestoreProfileDefault);
|
||||
GetDelegate(0x7DD5B261, out DRS_RestoreProfileDefaultSetting, 0x53F0381E);
|
||||
GetDelegate(0xDA8466A0, out DRS_GetBaseProfile);
|
||||
|
||||
GetDelegate(0x8FC247B7, out DRS_DecryptSession);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,16 +11,16 @@ namespace nspector.Native
|
||||
|
||||
public static T[] GetArrayData<T>(IntPtr sourcePointer, int itemCount)
|
||||
{
|
||||
var lstResult = new List<T>(itemCount);
|
||||
var lstResult = new T[itemCount];
|
||||
if (sourcePointer != IntPtr.Zero && itemCount > 0)
|
||||
{
|
||||
var sizeOfItem = Marshal.SizeOf(typeof(T));
|
||||
for (int i = 0; i < itemCount; i++)
|
||||
{
|
||||
lstResult.Add(GetArrayItemData<T>(sourcePointer + (sizeOfItem * i)));
|
||||
lstResult[i] = GetArrayItemData<T>(sourcePointer + (sizeOfItem * i));
|
||||
}
|
||||
}
|
||||
return lstResult.ToArray();
|
||||
return lstResult;
|
||||
}
|
||||
|
||||
public static void SetArrayData<T>(T[] items, out IntPtr targetPointer)
|
||||
@@ -54,13 +54,5 @@ namespace nspector.Native
|
||||
targetPointer = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetArrayItemData<T>(T item, out IntPtr targetPointer)
|
||||
{
|
||||
var sizeOfItem = Marshal.SizeOf(typeof(T));
|
||||
targetPointer = Marshal.AllocHGlobal(sizeOfItem);
|
||||
Marshal.StructureToPtr(item, targetPointer, true);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Generated
+428
-461
File diff suppressed because it is too large.
Load diff
@@ -19,6 +19,7 @@ namespace nspector
|
||||
|
||||
private List<SettingItem> _currentProfileSettingItems = new List<SettingItem>();
|
||||
private static bool _alreadyScannedForPredefinedSettings = false;
|
||||
private static object[] _baseProfileNames;
|
||||
private IntPtr _taskbarParent = IntPtr.Zero;
|
||||
private bool _activated = false;
|
||||
private bool _isStartup = true;
|
||||
@@ -173,15 +174,16 @@ namespace nspector
|
||||
GC.Collect();
|
||||
for (int i = 0; i < lvSettings.Items.Count; i++)
|
||||
{
|
||||
if (lvSettings.Items[i].Text == lvSelection)
|
||||
var item = lvSettings.Items[i];
|
||||
if (item.Text == lvSelection)
|
||||
{
|
||||
lvSettings.Items[i].Selected = true;
|
||||
lvSettings.Items[i].EnsureVisible();
|
||||
item.Selected = true;
|
||||
item.EnsureVisible();
|
||||
|
||||
if (!cbProfiles.Focused)
|
||||
{
|
||||
lvSettings.Select();
|
||||
cbValues.Text = lvSettings.Items[i].SubItems[1].Text;
|
||||
cbValues.Text = item.SubItems[1].Text;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -193,12 +195,33 @@ namespace nspector
|
||||
{
|
||||
cbProfiles.Items.Clear();
|
||||
|
||||
var profileNames = _drs.GetProfileNames(ref _baseProfileName);
|
||||
cbProfiles.Items.AddRange(profileNames.Cast<object>().ToArray());
|
||||
if (_baseProfileNames != null)
|
||||
{
|
||||
cbProfiles.Items.AddRange(_baseProfileNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
var profileNames = _drs.GetProfileNames(ref _baseProfileName);
|
||||
_baseProfileNames = profileNames.Cast<object>().ToArray();
|
||||
cbProfiles.Items.AddRange(_baseProfileNames);
|
||||
}
|
||||
|
||||
cbProfiles.Sorted = true;
|
||||
}
|
||||
|
||||
public void SetProfileByExecutable(string executable)
|
||||
{
|
||||
var profileName = _drs.GetProfileNameByApps(executable);
|
||||
|
||||
if (profileName != null)
|
||||
{
|
||||
cbProfiles.SelectedIndex = cbProfiles.Items.IndexOf(profileName);
|
||||
return;
|
||||
}
|
||||
|
||||
ShowCreateProfileDialog(Path.GetFileNameWithoutExtension(executable), executable);
|
||||
}
|
||||
|
||||
private void MoveComboToItemAndFill()
|
||||
{
|
||||
if (lvSettings.SelectedItems.Count > 0)
|
||||
|
||||
+421
-248
@@ -1,17 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
@@ -26,260 +26,433 @@
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="ilListView.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>115, 17</value>
|
||||
</metadata>
|
||||
<data name="ilListView.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
|
||||
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
|
||||
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAADI
|
||||
DAAAAk1TRnQBSQFMAgEBBAEAAcABBwHAAQcBEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA
|
||||
AwABIAMAAQEBAAEYBgABGP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/ADMAAcgBvQGvAacBkQF5BgAD/iEA
|
||||
A+QD2gYAA/4hAAGXAcMBqwFMAZwBcAYAA/4hAAOmA2gGAAP+FQAB8gHxAfABqQGPAXQBzwHHAbwD/wG6
|
||||
AaUBjAGuAZQBeAHxAe8B7QHvAe0B6wGhAYgBbQHkAeAB2xIAA/UD3QPmA/8D4APeA/QD8wPaA+4SAAHt
|
||||
AfIB7wE3AaEBZgGlAcwBtwP/AVgBsQGAATUBpgFoAekB8AHsAecB7wHqATwBlQFkAdQB4gHaEgAD7gNi
|
||||
A7UD/wN6A2QD7APqA1oD2BIAAfMB8QHvAbwBoQGGAb4BogGHAb4BpQGIAbsBogGFAbwBogGEAagBlQGB
|
||||
Aa0BlgF/Aa4BkgF3AegB5QHhEgAD9QnjBuIJ3gPwEgAB6wHyAe4BOgG1AXEBPAG2AXQBPgG3AXMBOgG1
|
||||
AXEBOgG1AXEBNwGmAWoBOAGoAWsBNAGkAWcB2QHnAd8SAAPuA3MDdgN0A3EDbwNxA20DZAPeDAAB9AHz
|
||||
AfIB7wHsAekB6AHiAdwByQGyAZcB0wHCAa4BzgG8AaYBzAG6AaUBzAG5AaMBywG3AaIBygG3AaIBvgGn
|
||||
AY8BxgG1AaMB5AHgAdsB4wHeAdoD/wMAA/YD8wPvA+cD7AbqCekG5AbuA/8DAAHvAfQB8QHiAe4B5wHM
|
||||
AeYB1wFCAcMBfAFUAckBiQFOAccBhQFLAcYBggFLAcYBggFJAcUBgQFJAcUBgQE8AbsBdQF7Ab8BmgHT
|
||||
AeIB2gHTAeAB2QP/AwAD8QPnA9cDhAOgA5cDlgmTA34DlgPYA9cD/wMAAcYBswGdAb4BqAGPAcwBtQGa
|
||||
AdMBvwGrAdUBxQGyAccBsAGXAcMBrAGNAb8BpgGMAb8BpwGMAcUBrwGXAcYBswGdAbsBowGJAaIBiwFx
|
||||
AY0BcwFXAeEB3QHYAwAD5QPkA+gD7APtA+cD5APiA+QG5wPjA9sD1APtAwABXQHCAYoBPAG7AXUBSAHE
|
||||
AYEBVAHJAYkBWAHKAYsBQgHDAXwBQAG+AXgBQAG5AXYBOwG5AXQBQAHCAXsBQwHDAX0BOgG2AXIBMQGb
|
||||
AWEBLAGAAVEB0QHeAdcDAAOOA30DhwOdA6UDhQN3A3gDeQOGA40DdwNfA0MD1QMAAekB5AHeAcYBrgGU
|
||||
AdUBxAGtAc0BuQGlAcoBsAGYAeUB3gHXAfgB9wH2A/oB6AHiAdwBwQGpAY4BwAGoAY4BxAGuAZUBsQGZ
|
||||
AYABzwHGAb0D+wMAA+8D5gPsA+oD5gPtA/kD+wPvBuQD5gPgA+cD/AMAAc4B5wHaAUABwgF8AVUByQGJ
|
||||
AUwBxgGDAUcBxAF/AcMB4wHRAfQB9wH2AfkC+gHOAeYB2QFFAbkBeQE8AbwBdgE9AcEBeQE3AawBbAGt
|
||||
AcsBuwH6AvsDAAPZA4IDnQOXA4YD0QP2A/oD2AN6A3wDgwNuA7YD+wMAAfcB9gH1AcgBsAGVAd4BzAG2
|
||||
AcsBtQGcAdQByQG6DAAB4gHdAdoBtwGgAY4BwwGwAaEBpQGSAYAB8AHuAewGAAP4A+cD7wboDAAD7gPj
|
||||
A+gD3gPzBgAB8gH2AfQBQgHCAX0BYAHNAZEBRgHEAX8BmgHRAbMMAAHIAeMB1AE6AbYBcgFFAcQBfgE2
|
||||
AaMBaAHnAe8B6gYAA/QDggOnA4oDsQwAA9gDgQOWA3ID6gMAAc0BuQGiAcsBtAGZAeMBzQG3AecB1gHD
|
||||
AbsBoQGFA/oMAAP6Ab8BpgGMAcwBuQGjAbwBogGEAa4BlAF4AacBkQF5A+cD6APwA/ID4QP7DAAD+wPi
|
||||
A+kD4gPeA9oBXgHJAY4BRQHEAX4BYwHOAZMBbAHQAZkBPAG0AXMB+QL6DAAB+QL6AUABuQF2AUsBxgGC
|
||||
AToBtQFxATUBpgFoAUwBnAFwA5IDhgOnA7YDcwP5DAAD+gN4A5MDbwNkA2gB1wHJAbgBzwG4AaIB5gHR
|
||||
Ab0B7AHbAcoBugGhAYUC+QH4DAAB+AH3AfYBwwGsAY0BzAG6AaUBuwGiAYUBugGlAYwByAG9Aa8D6QPn
|
||||
A/ED9APhA/oMAAP5A+QD6gPiA+AD5AGKAdMBqwFXAccBigFoAc8BlgFyAdIBnQE8AbIBcAH4AfkB+AwA
|
||||
AfQB9wH2AUABvgF4AUsBxgGCAToBtQFxAVgBsQGAAZcBwwGrA6wDkgOvA74DcQP4DAAD9gN3A5YDcQN6
|
||||
A6YDAAP7AdwByQGzAewB3AHLAccBswGaAc4BxAG5DAAB5QHeAdcBxwGwAZcBzgG8AaYBvgGlAYgD/wYA
|
||||
A/sD7QP0A+cD5QwAA+0D5wPqA+MD/wYAAfoC+wFeAcwBjwFyAdIBnQFCAcMBfAGoAckBtgwAAcMB4wHR
|
||||
AUIBwwF8AU4BxwGFAT4BtwFzA/8GAAP7A6MDvwOIA7IMAAPRA4UDlwN0A/8GAAHxAe8B7AHZAcQBrQHv
|
||||
Ad8BzgHfAc0BuwG2AaEBhQHOAcQBuQL5AfgD+gHUAckBugHKAbABmAHVAcUBsgHTAcIBrgG+AaIBhwHP
|
||||
AccBvAYAA/QD7QP1A/AD4QPlA/oD+wPoA+YD7QPsA+MD5gYAAeUB8QHqAVkBygGNAXcB1AGhAWMBzgGT
|
||||
ATwBsQFwAagByQG2AfgB+QH4AfkC+gGaAdEBswFHAcQBfwFYAcoBiwFUAckBiQE8AbYBdAGlAcwBtwYA
|
||||
A+oDmwPCA64DcQOyA/gD+QOxA4YDpQOgA3YDtQYAAdYBxgGyAdABuAGdAdsBxQGwAfIB4gHSAeABzwG8
|
||||
AccBswGaAboBoQGFAbsBoQGFAcsBtQGcAc0BuQGlAdMBvwGrAckBsgGXAbwBoQGGAakBjwF0BgAD6APp
|
||||
A+wD9gPwA+cG4QPoA+oD7APnA+MD3QYAAXsB0QGhAUkBxQGBAV0BywGOAXsB1QGkAWQBzgGUAUIBwwF8
|
||||
ATwBsgFwATwBtAFzAUYBxAF/AUwBxgGDAVQByQGJAUIBwwF8AToBtQFxATcBoQFmBgADowOKA6ADxwOv
|
||||
A4gDcQNzA4oDlwOdA4QDcwNiBgAB8wHxAe8B8AHtAeoB8QHuAesB4gHOAboB7gHfAc0B7AHcAcsB7AHb
|
||||
AcoB5wHWAcMB3gHMAbYB1QHEAa0BzAG1AZoB6AHiAdwB8wHxAe8B8gHxAfAGAAP1A/ID8wPwA/UG9APy
|
||||
A+8D7APoA+8G9QYAAeoB8wHuAeEB7wHnAeMB8AHoAWQBzgGUAXUB0wGfAXIB0gGdAXIB0gGdAWwB0AGZ
|
||||
AWABzQGRAVUByQGJAUgBxAGBAcwB5gHXAesB8gHuAe0B8gHvBgAD7gPoA+kDrAPAA78DvgO2A6cDnQOH
|
||||
A9cG7gwAAfQB8wHxAdUBwAGnAdkBwwGqAdwByQGzAeYB0QG9AeMBzQG3AcgBsAGVAcYBrgGUAb4BqAGP
|
||||
Ae8B7AHpEgAD9gPrA+wD7QPxA/AD5wPmA+QD8xIAAe0B9AHwAVIByAGHAVcByQGJAV4BzAGPAWgBzwGW
|
||||
AWMBzgGTAUIBwgF9AUABwgF8ATwBuwF1AeIB7gHnEgAD8AOVA5gDowOvA6cGggN9A+cSAAH1AfQB8gHQ
|
||||
Ab0BpAHgAdYBzAP7Ac8BuAGiAcsBtAGZAfcB9gH1AekB5AHeAcYBswGdAfQB8wHyEgAD9gPpA+sD+wPn
|
||||
A+gD+APvA+UD9hIAAe4B9QHxAVsByQGNAasB3QHCAfoC+wFXAccBigFFAcQBfgHyAfYB9AHOAecB2gFd
|
||||
AcIBigHvAfQB8RIAA/EDkgPEA/sDkgOGA/QD2QOOA/EVAAH9AvwD/gMAAdcByQG4Ac0BuQGiIQAD/QP+
|
||||
AwAD6QPnIQAD/AP+AwABigHTAasBXgHJAY4hAAP8A/4DAAOsA5IVAAFCAU0BPgcAAT4DAAEoAwABQAMA
|
||||
ASADAAEBAQABAQYAAQEWAAP/gQAB/gFvAf4BbwH+AW8B/gFvAeABBwHgAQcB4AEHAeABBwHgAQcB4AEH
|
||||
AeABBwHgAQcBgAEAAYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAAGAAQABgwHB
|
||||
AYMBwQGDAcEBgwHBAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAQMBwAEDAcABgwHBAYMBwQGDAcEBgwHB
|
||||
AYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAeABBwHgAQcB4AEH
|
||||
AeABBwHgAQcB4AEHAeABBwHgAQcB8gF/AfIBfwHyAX8B8gF/Cw==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="pbMain.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="tsMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>217, 17</value>
|
||||
</metadata>
|
||||
<metadata name="tsMain.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tsbRefreshProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGgSURBVDhPrZPLSsNAFIb7BoKP4Upw5UoQBHfmMrG1olCa
|
||||
pFoExY2KiHcRERFEwYUKglSQesFeQK2rFkFr0Y26MRAKpa2+QS+/MzGpaS114wdhQv7/nDknZ8bx7xDi
|
||||
a+FFeYvnFU2QFHCcRxdEOcQTmTctjWHB4UgM2Wwe5XIZ+fwnko/PWF3bhiAqJzRRp2mtD0/U7oWlTbAK
|
||||
Bj1jYO/vmo5SqYR44gG9fcPgiNpu2uvDkrCVEG+zIMkqcfqQuEuiWCwidhsHJ8qHhtEOLX2H9cxW81MF
|
||||
nni7XP1+5PIfKBQKmJlbR1UrVnAul0O9JJa+fxAwPJehqx+fPdh6apPU6nZfY9Gk4SaWGDwN09FlsUfL
|
||||
rIg2LB/z/NI5SW4bHZ9FJpPBy+sbnG4//Unfk7BjJalNbsBGEzwLIZ1OIxK9AXGqdCdZlSS1iel/HiB2
|
||||
OCTXEM4vItB1nc79HpPTK3APjBiHamJquXp09eCI0sGJyvH84gat4hqp1BM0TUMymcJRIEhLV3ZNa2ME
|
||||
4nXSCxQ1LhLrmVbAgnskudW0/BcOxxdQeE7WHAMG/AAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbRestoreProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFcSURBVDhP3VFNK0RhFL4/wNbM3PdcCgsfsbHDgkJKWPgD
|
||||
ilJGNN73XEs/gbKUmvITuPc9d5iwYKfZyULZ26BkhTjnnXs1TWTNqafOx/M895z3ev84FsrwigQfvyGl
|
||||
1yNM1IyO4cQNrUKdqGFj1awmuGgWZnDC9Wouz8U1xnATkj+oE78HLVyWKPeAlH9EUkOa1FyzWOAxeVIS
|
||||
JuxtRoVeERhS51zviLlsIHNjYRltW1ejWOChDdbqhEIfRoVbE0PZbXXoP3G/ygZFNyeYZ4xlwgzC9fAI
|
||||
7rmomUrQL01TyXekPUfSVo3zSSVXW3Ug75PNnEEpau+Uglff5XsnOH9D8reZuBJamOa6JvPQqkXhF89a
|
||||
W9jw+MtAIiTVjRE88+AKY3/E5fKVGO74jC3hbMTBAPf2XT+FEzcGb7BqrH/KWNIUTLk34LX5V740Cn80
|
||||
yGKU4P07QTNS+t8Nz/sEkToIpLSWKNoAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbCreateProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEgSURBVDhP3Y/PKwRhHIf3f5g/wMWUlIuDUk5y5MCB3Dk4
|
||||
7EUbBwdXJ3EXsksjidlk2x27NrXt5kdjlTQXbSFK2iaGaX7s491Zjppx5FNP7/et9/n0fmP/PFwu8JGd
|
||||
5OsaLdxpNIyVQPL1GcyDwWDmVsEx1sLLGvdHeLtduKVh/GIPTlbGPRvF3mmjXm0Vh8a9SEBGAl1gCMoS
|
||||
j2p/uOyX5/AK4/i5bqgI8UrQPFUJO9mOr43gHk/9XOToy9QLCd4O+yAvxCb7gg0JK9WJqcWxTubDf+Kd
|
||||
x0ERYkqwLliVeE8PRNufWhpnUxY7j2Fu92IlO3jOT+AqMk+lxfAS+6HI6/VW8NA5neVlb6g11zLcVNRo
|
||||
v/gO1SXM3PTvpL+WWOwT04jC5H73kgIAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="btnResetValue.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblApplications.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<data name="toolStripButton5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
|
||||
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
|
||||
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
|
||||
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
|
||||
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
|
||||
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
|
||||
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
|
||||
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="toolStripButton6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
|
||||
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
|
||||
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
|
||||
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
|
||||
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
|
||||
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
|
||||
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
|
||||
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="ilCombo.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="cbValues.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth96.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth330.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth16.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth30.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="ilListView.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>115, 17</value>
|
||||
</metadata>
|
||||
<data name="ilListView.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>
|
||||
AAEAAAD/////AQAAAAAAAAAMAgAAAEZTeXN0ZW0uV2luZG93cy5Gb3JtcywgQ3VsdHVyZT1uZXV0cmFs
|
||||
LCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5BQEAAAAmU3lzdGVtLldpbmRvd3MuRm9ybXMu
|
||||
SW1hZ2VMaXN0U3RyZWFtZXIBAAAABERhdGEHAgIAAAAJAwAAAA8DAAAAyAwAAAJNU0Z0AUkBTAIBAQQB
|
||||
AAHIAQcByAEHARABAAEQAQAE/wEZAQAI/wFCAU0BNgcAATYDAAEoAwABQAMAASADAAEBAQABGAYAARj/
|
||||
AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wAzAAHIAb0BrwGnAZEBeQYAA/4hAAPkA9oGAAP+IQABlwHDAasB
|
||||
TAGcAXAGAAP+IQADpgNoBgAD/hUAAfIB8QHwAakBjwF0Ac8BxwG8A/8BugGlAYwBrgGUAXgB8QHvAe0B
|
||||
7wHtAesBoQGIAW0B5AHgAdsSAAP1A90D5gP/A+AD3gP0A/MD2gPuEgAB7QHyAe8BNwGhAWYBpQHMAbcD
|
||||
/wFYAbEBgAE1AaYBaAHpAfAB7AHnAe8B6gE8AZUBZAHUAeIB2hIAA+4DYgO1A/8DegNkA+wD6gNaA9gS
|
||||
AAHzAfEB7wG8AaEBhgG+AaIBhwG+AaUBiAG7AaIBhQG8AaIBhAGoAZUBgQGtAZYBfwGuAZIBdwHoAeUB
|
||||
4RIAA/UJ4wbiCd4D8BIAAesB8gHuAToBtQFxATwBtgF0AT4BtwFzAToBtQFxAToBtQFxATcBpgFqATgB
|
||||
qAFrATQBpAFnAdkB5wHfEgAD7gNzA3YDdANxA28DcQNtA2QD3gwAAfQB8wHyAe8B7AHpAegB4gHcAckB
|
||||
sgGXAdMBwgGuAc4BvAGmAcwBugGlAcwBuQGjAcsBtwGiAcoBtwGiAb4BpwGPAcYBtQGjAeQB4AHbAeMB
|
||||
3gHaA/8DAAP2A/MD7wPnA+wG6gnpBuQG7gP/AwAB7wH0AfEB4gHuAecBzAHmAdcBQgHDAXwBVAHJAYkB
|
||||
TgHHAYUBSwHGAYIBSwHGAYIBSQHFAYEBSQHFAYEBPAG7AXUBewG/AZoB0wHiAdoB0wHgAdkD/wMAA/ED
|
||||
5wPXA4QDoAOXA5YJkwN+A5YD2APXA/8DAAHGAbMBnQG+AagBjwHMAbUBmgHTAb8BqwHVAcUBsgHHAbAB
|
||||
lwHDAawBjQG/AaYBjAG/AacBjAHFAa8BlwHGAbMBnQG7AaMBiQGiAYsBcQGNAXMBVwHhAd0B2AMAA+UD
|
||||
5APoA+wD7QPnA+QD4gPkBucD4wPbA9QD7QMAAV0BwgGKATwBuwF1AUgBxAGBAVQByQGJAVgBygGLAUIB
|
||||
wwF8AUABvgF4AUABuQF2ATsBuQF0AUABwgF7AUMBwwF9AToBtgFyATEBmwFhASwBgAFRAdEB3gHXAwAD
|
||||
jgN9A4cDnQOlA4UDdwN4A3kDhgONA3cDXwNDA9UDAAHpAeQB3gHGAa4BlAHVAcQBrQHNAbkBpQHKAbAB
|
||||
mAHlAd4B1wH4AfcB9gP6AegB4gHcAcEBqQGOAcABqAGOAcQBrgGVAbEBmQGAAc8BxgG9A/sDAAPvA+YD
|
||||
7APqA+YD7QP5A/sD7wbkA+YD4APnA/wDAAHOAecB2gFAAcIBfAFVAckBiQFMAcYBgwFHAcQBfwHDAeMB
|
||||
0QH0AfcB9gH5AvoBzgHmAdkBRQG5AXkBPAG8AXYBPQHBAXkBNwGsAWwBrQHLAbsB+gL7AwAD2QOCA50D
|
||||
lwOGA9ED9gP6A9gDegN8A4MDbgO2A/sDAAH3AfYB9QHIAbABlQHeAcwBtgHLAbUBnAHUAckBugwAAeIB
|
||||
3QHaAbcBoAGOAcMBsAGhAaUBkgGAAfAB7gHsBgAD+APnA+8G6AwAA+4D4wPoA94D8wYAAfIB9gH0AUIB
|
||||
wgF9AWABzQGRAUYBxAF/AZoB0QGzDAAByAHjAdQBOgG2AXIBRQHEAX4BNgGjAWgB5wHvAeoGAAP0A4ID
|
||||
pwOKA7EMAAPYA4EDlgNyA+oDAAHNAbkBogHLAbQBmQHjAc0BtwHnAdYBwwG7AaEBhQP6DAAD+gG/AaYB
|
||||
jAHMAbkBowG8AaIBhAGuAZQBeAGnAZEBeQPnA+gD8APyA+ED+wwAA/sD4gPpA+ID3gPaAV4ByQGOAUUB
|
||||
xAF+AWMBzgGTAWwB0AGZATwBtAFzAfkC+gwAAfkC+gFAAbkBdgFLAcYBggE6AbUBcQE1AaYBaAFMAZwB
|
||||
cAOSA4YDpwO2A3MD+QwAA/oDeAOTA28DZANoAdcByQG4Ac8BuAGiAeYB0QG9AewB2wHKAboBoQGFAvkB
|
||||
+AwAAfgB9wH2AcMBrAGNAcwBugGlAbsBogGFAboBpQGMAcgBvQGvA+kD5wPxA/QD4QP6DAAD+QPkA+oD
|
||||
4gPgA+QBigHTAasBVwHHAYoBaAHPAZYBcgHSAZ0BPAGyAXAB+AH5AfgMAAH0AfcB9gFAAb4BeAFLAcYB
|
||||
ggE6AbUBcQFYAbEBgAGXAcMBqwOsA5IDrwO+A3ED+AwAA/YDdwOWA3EDegOmAwAD+wHcAckBswHsAdwB
|
||||
ywHHAbMBmgHOAcQBuQwAAeUB3gHXAccBsAGXAc4BvAGmAb4BpQGIA/8GAAP7A+0D9APnA+UMAAPtA+cD
|
||||
6gPjA/8GAAH6AvsBXgHMAY8BcgHSAZ0BQgHDAXwBqAHJAbYMAAHDAeMB0QFCAcMBfAFOAccBhQE+AbcB
|
||||
cwP/BgAD+wOjA78DiAOyDAAD0QOFA5cDdAP/BgAB8QHvAewB2QHEAa0B7wHfAc4B3wHNAbsBtgGhAYUB
|
||||
zgHEAbkC+QH4A/oB1AHJAboBygGwAZgB1QHFAbIB0wHCAa4BvgGiAYcBzwHHAbwGAAP0A+0D9QPwA+ED
|
||||
5QP6A/sD6APmA+0D7APjA+YGAAHlAfEB6gFZAcoBjQF3AdQBoQFjAc4BkwE8AbEBcAGoAckBtgH4AfkB
|
||||
+AH5AvoBmgHRAbMBRwHEAX8BWAHKAYsBVAHJAYkBPAG2AXQBpQHMAbcGAAPqA5sDwgOuA3EDsgP4A/kD
|
||||
sQOGA6UDoAN2A7UGAAHWAcYBsgHQAbgBnQHbAcUBsAHyAeIB0gHgAc8BvAHHAbMBmgG6AaEBhQG7AaEB
|
||||
hQHLAbUBnAHNAbkBpQHTAb8BqwHJAbIBlwG8AaEBhgGpAY8BdAYAA+gD6QPsA/YD8APnBuED6APqA+wD
|
||||
5wPjA90GAAF7AdEBoQFJAcUBgQFdAcsBjgF7AdUBpAFkAc4BlAFCAcMBfAE8AbIBcAE8AbQBcwFGAcQB
|
||||
fwFMAcYBgwFUAckBiQFCAcMBfAE6AbUBcQE3AaEBZgYAA6MDigOgA8cDrwOIA3EDcwOKA5cDnQOEA3MD
|
||||
YgYAAfMB8QHvAfAB7QHqAfEB7gHrAeIBzgG6Ae4B3wHNAewB3AHLAewB2wHKAecB1gHDAd4BzAG2AdUB
|
||||
xAGtAcwBtQGaAegB4gHcAfMB8QHvAfIB8QHwBgAD9QPyA/MD8AP1BvQD8gPvA+wD6APvBvUGAAHqAfMB
|
||||
7gHhAe8B5wHjAfAB6AFkAc4BlAF1AdMBnwFyAdIBnQFyAdIBnQFsAdABmQFgAc0BkQFVAckBiQFIAcQB
|
||||
gQHMAeYB1wHrAfIB7gHtAfIB7wYAA+4D6APpA6wDwAO/A74DtgOnA50DhwPXBu4MAAH0AfMB8QHVAcAB
|
||||
pwHZAcMBqgHcAckBswHmAdEBvQHjAc0BtwHIAbABlQHGAa4BlAG+AagBjwHvAewB6RIAA/YD6wPsA+0D
|
||||
8QPwA+cD5gPkA/MSAAHtAfQB8AFSAcgBhwFXAckBiQFeAcwBjwFoAc8BlgFjAc4BkwFCAcIBfQFAAcIB
|
||||
fAE8AbsBdQHiAe4B5xIAA/ADlQOYA6MDrwOnBoIDfQPnEgAB9QH0AfIB0AG9AaQB4AHWAcwD+wHPAbgB
|
||||
ogHLAbQBmQH3AfYB9QHpAeQB3gHGAbMBnQH0AfMB8hIAA/YD6QPrA/sD5wPoA/gD7wPlA/YSAAHuAfUB
|
||||
8QFbAckBjQGrAd0BwgH6AvsBVwHHAYoBRQHEAX4B8gH2AfQBzgHnAdoBXQHCAYoB7wH0AfESAAPxA5ID
|
||||
xAP7A5IDhgP0A9kDjgPxFQAB/QL8A/4DAAHXAckBuAHNAbkBoiEAA/0D/gMAA+kD5yEAA/wD/gMAAYoB
|
||||
0wGrAV4ByQGOIQAD/AP+AwADrAOSFQABQgFNAT4HAAE+AwABKAMAAUADAAEgAwABAQEAAQEGAAEBFgAD
|
||||
/4EAAf4BbwH+AW8B/gFvAf4BbwHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB4AEHAYABAAGAAQAB
|
||||
gAEAAYABAAGAAQABgAEAAYABAAGAAQABgAEAAYABAAGAAQABgAEAAYMBwQGDAcEBgwHBAYMBwQEDAcAB
|
||||
AwHAAQMBwAEDAcABAwHAAQMBwAEDAcABAwHAAYMBwQGDAcEBgwHBAYMBwQGAAQEBgAEBAYABAQGAAQEB
|
||||
gAEBAYABAQGAAQEBgAEBAYABAQGAAQEBgAEBAYABAQHgAQcB4AEHAeABBwHgAQcB4AEHAeABBwHgAQcB
|
||||
4AEHAfIBfwHyAX8B8gF/AfIBfws=
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="pbMain.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="tsMain.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>217, 17</value>
|
||||
</metadata>
|
||||
<metadata name="tsMain.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="tsMain.BackgroundImage" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAANklEQVQ4T6XIsREAIAADIfdf
|
||||
Oi5A4Z8FDWfbF2bBLJgFs2AWzIJZMAtmwSyYBbNgFsyC+W7nAsWt/R/ojsvuAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbModifiedProfiles.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKzSURBVDhPrZJJTBNhGIbnoCHehHgwJsREOGiILYsxBBE1
|
||||
YPCIshVjAInRYliCW0BpFcUom1BRWhYRkB0UgxGNZWdmqgW0hZIuyAgUhTCF0FJEBXltYTwJXvRNvtv3
|
||||
PHm/Pz/x32KId3Vgzrt/UYW4sMqw3SnKcDdnMspvkIoJYGkB/zi3tnFWcry3WNP80RPqjDp/x6dUuGe5
|
||||
vvoejF0NIE/56CkBz4NbXT8tx1wdFCd2zubv24wsn+0r43V5oCvvol16FcMvikFH+mopwZ6/SzQCl5Le
|
||||
EB4MVdmgqjKglVeAUTShp/Qm9M9lUMQcGqKCN5CQAo8dVJBbv7YyC3RNJjSvH8MyOQTzhBofu2pBVqRD
|
||||
1yQFHXNY0xPmxuewtdjv6wrhyXXVOau17fDCtB6LM8NYmBrEHEPDIC9bk9ia0KcPasmTfHcOtwmi/HSG
|
||||
2lxQFbehb32CpTkGPy2jq/D8eC8Wx0hYDXKMyIvRXZoGQ3MRyGg/LYcThErIC+7MjZseVzZDp9Ui+kwC
|
||||
jgSGQtneBPNYHzyDkrHr6AVkZmTBRBahsygVqnO8SA4niIHYvY7dkmhm5eskhrQGxF2+gwMBEehoLoPF
|
||||
JvCKKMDWABlE6YVYVpWAKk2EJsnbicMJoqPw7LYOqZD5YR7D1OcJSPJlSLwkxoDtD3wz0sgrLgCx/wGu
|
||||
iB9iqa8AdGkC7AyH/xbEMlbbq3+fGQGso8ACA4vhDUy6Nggu3gLBlyAhJQ/LvfdBP1pPIBMy88b3MH+i
|
||||
MatrhUndDFN/PYzqdhBeeSB42YhPzsaSXbBeg06ZcNQy+hbm4S7MDr2C6cMzsO8qMaFuw6bAMhC+5Ui8
|
||||
LsWyUvKngK5LciKrk/vpxhss3Shm6QbR2tSnslSDmG0pF7Evy0RsW2Uqq6i/xpI1Kayd4fB/CUH8AppD
|
||||
2GmutIMCAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbRefreshProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGgSURBVDhPrZPLSsNAFIb7BoKP4Upw5UoQBHfmMrG1olCa
|
||||
pFoExY2KiHcRERFEwYUKglSQesFeQK2rFkFr0Y26MRAKpa2+QS+/MzGpaS114wdhQv7/nDknZ8bx7xDi
|
||||
a+FFeYvnFU2QFHCcRxdEOcQTmTctjWHB4UgM2Wwe5XIZ+fwnko/PWF3bhiAqJzRRp2mtD0/U7oWlTbAK
|
||||
Bj1jYO/vmo5SqYR44gG9fcPgiNpu2uvDkrCVEG+zIMkqcfqQuEuiWCwidhsHJ8qHhtEOLX2H9cxW81MF
|
||||
nni7XP1+5PIfKBQKmJlbR1UrVnAul0O9JJa+fxAwPJehqx+fPdh6apPU6nZfY9Gk4SaWGDwN09FlsUfL
|
||||
rIg2LB/z/NI5SW4bHZ9FJpPBy+sbnG4//Unfk7BjJalNbsBGEzwLIZ1OIxK9AXGqdCdZlSS1iel/HiB2
|
||||
OCTXEM4vItB1nc79HpPTK3APjBiHamJquXp09eCI0sGJyvH84gat4hqp1BM0TUMymcJRIEhLV3ZNa2ME
|
||||
4nXSCxQ1LhLrmVbAgnskudW0/BcOxxdQeE7WHAMG/AAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbRestoreProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFcSURBVDhP3VFNK0RhFL4/wNbM3PdcCgsfsbHDgkJKWPgD
|
||||
ilJGNN73XEs/gbKUmvITuPc9d5iwYKfZyULZ26BkhTjnnXs1TWTNqafOx/M895z3ev84FsrwigQfvyGl
|
||||
1yNM1IyO4cQNrUKdqGFj1awmuGgWZnDC9Wouz8U1xnATkj+oE78HLVyWKPeAlH9EUkOa1FyzWOAxeVIS
|
||||
JuxtRoVeERhS51zviLlsIHNjYRltW1ejWOChDdbqhEIfRoVbE0PZbXXoP3G/ygZFNyeYZ4xlwgzC9fAI
|
||||
7rmomUrQL01TyXekPUfSVo3zSSVXW3Ug75PNnEEpau+Uglff5XsnOH9D8reZuBJamOa6JvPQqkXhF89a
|
||||
W9jw+MtAIiTVjRE88+AKY3/E5fKVGO74jC3hbMTBAPf2XT+FEzcGb7BqrH/KWNIUTLk34LX5V740Cn80
|
||||
yGKU4P07QTNS+t8Nz/sEkToIpLSWKNoAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbCreateProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEgSURBVDhP3Y/PKwRhHIf3f5g/wMWUlIuDUk5y5MCB3Dk4
|
||||
7EUbBwdXJ3EXsksjidlk2x27NrXt5kdjlTQXbSFK2iaGaX7s491Zjppx5FNP7/et9/n0fmP/PFwu8JGd
|
||||
5OsaLdxpNIyVQPL1GcyDwWDmVsEx1sLLGvdHeLtduKVh/GIPTlbGPRvF3mmjXm0Vh8a9SEBGAl1gCMoS
|
||||
j2p/uOyX5/AK4/i5bqgI8UrQPFUJO9mOr43gHk/9XOToy9QLCd4O+yAvxCb7gg0JK9WJqcWxTubDf+Kd
|
||||
x0ERYkqwLliVeE8PRNufWhpnUxY7j2Fu92IlO3jOT+AqMk+lxfAS+6HI6/VW8NA5neVlb6g11zLcVNRo
|
||||
v/gO1SXM3PTvpL+WWOwT04jC5H73kgIAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbDeleteProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFtSURBVDhP3ZJPSwJBGIfd2ZnddcWLiKC76sKgIHryQ/QZ
|
||||
+h5FlhJGB79HBF09RIga5Z901xVTSKxYzEw2EIICDx6nKYYg1uxcD7yX5/3NvDPMuP4ZY4yXs1jMHicS
|
||||
h0x98ZRIFKYYzx8jkSVTTugG9nM8TnqqagxTqfyHI/k8mCSTB1Y02p1gTMaKYn+GVzGjk/uK0u6EQsTU
|
||||
tKtxOp29CYc3hsFg26LOUpTmNBp1nO4btxhnTZ+v8aBpbyO/v0vLvA+FFnc+X32iKLssth5LVbevvd5u
|
||||
SxCIiRAZeDx9KxDYYu3fGcjyniFJvZYoEp2WIYr9oSxnWHs9uiTtVwAwmhAumqLYaQhC+5LnX8oANHqS
|
||||
lGOx1egIFejiToXjSJnjLnQIM20Id4ocVz0CgJwAoPfc7gKLO6kiNK/wPCkBUK9BmGXaVROEXJHnR8e0
|
||||
16AZpp2UIFyeQWifI+R4qlMANul1XusI/fyR/iIu1ztb44EJFA1Z/gAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbAddApplication.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVDhPrZPNSwJRFMXvP9auqH27Fv0HQQRhFC00LCIk
|
||||
RRRMWiguhJCiheAHagqpJOIXD4wyRgUNdYwCBY1O7zk65Bhk0YEfc2d499zDHR79j84+lskB/ArRo4p/
|
||||
cGTmZ8E3NlE1cTW25sPSnzVgjE1RLDJkswx3dwzJJEMiwRCNMgSDDH4/mzXQqlqV4Xbfwum8QanUQbMJ
|
||||
1GpApQKUy+PEqjQG/f4ALleST39BLNaE2RyAJA3mN7i+ziKdlhEIVHn9gHi8hlyujtdXoNtVkswYDIcK
|
||||
3W4P5+cphEJ1XF09wOtlKBSeQVbiy+OYCO32Nwa9noLPl0I4XMXlZZk/n5DPN5DJ1ECnBEt/HXRMaLUA
|
||||
Y1ZjIOIJrNYgb76Hx1PgsRvqVDohmN7WQAe81nP2Oaq4QaejYDD4eOwibLY4IpHSqFlMFs2H7VXsSSvY
|
||||
qSyBdjQG4jcJ9PoL6HQe2O0hyPI76IgfNCpTRTPt8nqbs6kxEJv9iiQphrKsJBORdY+LoC1Co6HdwQ+X
|
||||
aXR4MnWDlPepy/RnEX0CXRRDb0PokG0AAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="tssbRemoveApplication.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHsSURBVDhPrZPfS1NhGMd33020ftyIpGAZbXVRLQtC6ia6
|
||||
8R+oCd20uohgd104ZRiGMDMQzF/F7MfVjjBLs7PsWLPNk0PLHV7ZnNY2gtEohIqFQZ/OWWuwI8GKvvCF
|
||||
l5f3+3me9+F9Lf9Hgz9OWwbgr2xkytI3BmLV+4RUgpT1m3otX51vFjYDhBAVjscFCwuC+XlBNCoIhwWK
|
||||
IpBlweSk2AwwK5P5xOhohKGh52jaR3I5yGZhbQ0SiVLHZZkAhcKGHp7Tq68zM5Ojt/cJ6fRG9QBZjuuB
|
||||
r8RiHxgfTyFJCUZGIn8G1D2A9afThE+eKlaPSgrywUO8C4b0e6fx+1/T0RHU5/KZVAqWl02Aqyq8qN0J
|
||||
l48RafPy0HFUX+8n1NiIqmbp63uJz6fQ36+wsmIM3AS4FIYxmx3amlltroHz+wjXb0OdeMXwsEpXV4jO
|
||||
zse43f5i+5pmArRMwdupZyj1W+GCnS9napi+eIVAYE4P3cXrncDjCeJ09hSrLy2ZAIPtd4g0WMFlA2cD
|
||||
nN2NXGvl/ZtVkslvdHc/orX1Bi7XrWJ4cdEEuL/nALhtaId3MHukDlp2wTl93eQgn/81dWNwRutGOKY/
|
||||
5wrAbNPxjLR9Cz7PbdrV79yzOwjstXF9LInVXzpsdsVn+mdZLD8BfTZF0/R8bMwAAAAASUVORK5CYII=
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbExportProfiles.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIbSURBVDhPtdBfaFJRHAdwXzMW1EuswRa1go2psBg97WFv
|
||||
4WQ6VnmZ7mEb6KhIyUww/2wKUTCFa21sqxWOkJYSERh7qOGF6aU1cdBLM2okXMk5piR48w9+03FAorX2
|
||||
UB84L+d8v7/DOYL/RrnSenpkpXtdyYjS/UxzI9k+GM1ao3DgbfsXP2yYSA/jwptTi+ToYAaW2ziaH8IM
|
||||
RvG4dBv9EUml53WTlBzv7/Jye9KRVqA2wJUbxEx5FDe5QXQ9a9oULxw/TGJ/NhSTsBQjLlsSvbiXuVQd
|
||||
QmG2eBU9TAdED4/Ok9j+xC8azsqX2uBM9WFyZwT2rT7Yv1PoXDxRPrMglJDY72iaPjI+7hyeomffSZda
|
||||
MPGtF/TOFbTOHULXg5NoudNQqq69/yIQCDyPxWI8wzCYnnuEzifHoHrfgbvZi2ieF+Dzp81KkktWgsEg
|
||||
b7fbX5Jand/vL/M8D5ZlYTAYcGPsFq45x9A9KUJ4dQ1b29vIZrMIhULQarUVUqvz+Xx8PB5HIpFAsVgE
|
||||
G2ExdX8avqc+bHzcQCQSgcPhgMlkgkqlKpFancvlWo1Go0ilUuA4DplMBoVCAbWhHo9nt2i1WqHX66FU
|
||||
Kj+Q2q90Op3e6/X+yOVyyOfzqDEajbDZbLBYLFCr1TxFUddJfG8ymUxYvS0YDocrtQFms3n3zdVbX2k0
|
||||
GiGJ/Z1UKj3vdrs5uVz+VaFQnCPb/5pA8BMNdy5aS5fTsQAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbImportProfiles.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIkSURBVDhPtdJdaJJRGAfw142IWd1FrUW7aNFF1GoF1cU2
|
||||
6iIqs2mL0KUE3Sh2kYaJbfmFg1aQBkZrtYikkppWFtnHRqCUChviRUSbEDWHLmdTwfCdluefjgMjtnIE
|
||||
/W6f//M853AO818cG2Cqdw82pNoCTWzr64YPmx+veUpLi2RkqvZ6Nxat3zvwgHRiy6NVhFYq2/Bi5ZOd
|
||||
Q/Ufm4fWF3um23Ezp0Dt3RrQcmXr3Ctcl1MS0vNVREzxw7gyfYJU32BQ1cdIl/QzO2jsrziNr1aP66MH
|
||||
oIsehHnyCLk0JSbdk22kabAuWXOfc4Hm/ox7h3P96PCm4rnP+6Cf4OFiqp1sfVlbXHqLcTNgODS2MJOp
|
||||
++Tou099h563FDon9sAY34965zLScrv5i1Vj3U5j87lcroFwOMz6fD70Xu1Fx9njaH1bh7UPlxPdm/Ng
|
||||
v82QeCxOPB4PazQa3bRtjtPp/MmyLILBINRqNVSnzmCbrRGKfgVG/CNITiWRyWTg9Xohl8vnP6vD4WAj
|
||||
kQii0SgKhQKCgSCulU7iuOfA2OgYAoEAzGYztFotJBLJD9o2x2KxDIdCISQSCcRiMaTTaeTzeZSH2my2
|
||||
2Ua9Xg+VSgWRSPSetv1OqVSq7Hb7TDabRS6XQ5lGo4HBYIBOp4NUKmXFYvFpGl8Yn8/nlrZ5/H4/KQ/o
|
||||
6uqavXNp6zOZTMalscp4PN4uq9UaEwgE40KhcFE/8B8wzC+qySa+SK8LKwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="tscbShowCustomSettingNamesOnly.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJuSURBVDhPxY9NTNIBGIdta262TnXo2qpLh07ZlgfdtNVa
|
||||
oumCFBlK+TXzE6Wc6fyHM2I6SKcYGpVkiqCZIhPTVAhCWyo5DaVIExIlnOlwoM38ZfTva6TXnvPzvPu9
|
||||
fv8fjnxSlSc3Ibf5DdhN48h+NIashlFkSIeR/uAl0iSDSK3TI1msRaKoH5eqepFQoQZTqEJcebvaj1BM
|
||||
+OfIxtWyQSt2wvxpDRML6zDav6BcOQZ6WVsHjVD4e1ew5YaATOlIT6N+Bs4VNxzLbtg/e2Bd8mDa6cGo
|
||||
xYF6RScKinnILuKDVSp9+iv+yfcjW3P7Hmrf/Y4X12Cyu9DVO4Bb3ELkpKfhXDgF8fGssq1k14/yD9gC
|
||||
Q0DSHY1G0jfpjb2zZ50wa+Ww9YmhEeci4nQwAk+GPKNQKHvI7G+oW0cSKrt1Nd0T3p9HpmbxoqUCZpUQ
|
||||
WnEWChjBuBBFaSMIYjeZ+EKrVuxlCTvxcWUDPcYPkFXmryvLE6Hg0nHzcvAqIzqSSqrbE8NrgXV5A+3G
|
||||
BXCKuHMCVuC6MCUUV84ctkQxmftJbXuoJU2wu76ixbgI6g3JJDuBZuWE7sN1etBG9u0ngyEXM0NJ9d9E
|
||||
F0sx79rEXd0YiHbDan2rZrOxNAlVCg3uDblQKjd6jhwPo5G6L5GFErx1uMFTPge/Ywb619MwOQHJkBuP
|
||||
XzlQO2ADi2iwkLov4dfEw2evVg/HEnVLJa0mqPQWSLVzqBmw477GCkHnFDi1WpD69hw8GhQSlyfQiZoN
|
||||
EPXaUKtfgqh/Hnzle6TwZG5S25mwiNgDMan552MzuI0MTpkuuUhkZuTwDYeOnTj1DdeVozI6609oAAAA
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="tscbShowScannedUnknownSettings.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAANWSURBVDhPdZNbTNJRHMf/bT70mFuvvbTWbd2xrYeeaj1X
|
||||
W1msNYoUu9DNmgKCqEiW/iMuEmX8ESkFQf54QQVFILzQX1A0DStJMv0HZpartMzi1x+lFVt9trOzc/b7
|
||||
nv3O5+wgv5FbiFN38G6mDO9JV9YTgJq6d97Suy8Xaa20RMm/AYAV8VnbPqizeEehPTD5wTkUAU1r/4wC
|
||||
7wJRVVvmUuH/kNb3Hlc19VW3+McH/GMzYCVCUOsaBnNnEAzOQZCavR6Osr7yXGnNtkQkGYm5Z5ep80Ws
|
||||
d/Q9KEyPFxn5KtFhOpN3TYi+VVaZobyyFq4L0XnWJe7+RCQZKU4cdQTImWZiFBh8lSiDcTIzT/bopdU/
|
||||
MRaamlsMkp/ARox8F4rR4JGDB7cmYn9QNhAQv7OBajtHKM7hopphgTMmf/055n07+20uGJ2D3jezgPdN
|
||||
w0VOoeumzp6TJLbU2LUDs/V9MHuCcIUjHOPVjZsE7hhvZOrHE4t/esHon4X6wOef9tA8yGs9iyKFNlls
|
||||
aY3rYtx2XBhPhEKxLRoW4OFBzEXOtzydhcDEAvjCX8D35hOona9BLLmbLLbogZUm1jnOyMzex4VlClA5
|
||||
SUAbn0Hb0AyEp7+BY5CkXiQ02TAQcaOWYPQ6XwxG11PgqxrenSvB1ib6QBCO0qI/yeZ9lOPEpMk7Drgv
|
||||
uuijXsbQPhAanopxG8aBJVDU2i/k3+7X2XyQj7XaWSJsbyKOIOwS3XZBEcpSyBVQ1T4EjqEomDwjcKfO
|
||||
ndcRie273zFWTqPRyou1djlmfQKFGhtkFVe+SsQRJIORscfaZF8ok6pi67bQcjV1LV87fM+hookYKZBg
|
||||
1Vs3b5SlZ/J2laqbByrMbuDKDZ3HstE1S2HmCeYGS11TJPwqDKmpqTKOSPLwLL8MsrL5kHVNAMycm/4b
|
||||
NS7pLb2rX4l3g8zohvNi9cKhCyUshMFgrHpYpQ+QEySkpaV5qPM2/S3WRAnT2fygptrGGnvgnqULuHct
|
||||
nfRcWe7hSzd2I1iF1hEhI0Cn0yep8AFqLH2uOHGxeapGUqhuthVoWoEnNzZflegjZwoxTqIEQap1euBx
|
||||
uZCSksKmliuXd5eJi2WLKzeybxu2U8bD2Wj16tNCbPMxjmL9cgWC/AIp/hYHsS2RwgAAAABJRU5ErkJg
|
||||
gg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbBitValueEditor.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGcSURBVDhPrZPpSwJRFMXn/y2ktGy3KNM00xapHn0IogKF
|
||||
hIo2Iykpoxr6EFi0QUGRUkZ7aObJM+Pw1IIW+sHDYZhz7rn3PpV/w7ecUgdjafijz+iP3KM3nIJ3PgnP
|
||||
zCXcoXN0BU/hmDyEfSwOkzWoFmQ6A6sPajzxjp+ye3RbasLKZPEEWD0DNi/yH10B+9fAUQo4vQXO7+RJ
|
||||
p9OwDW6hIFcUxiYWh8DOJWDzCLT1CE3o6hNIPAE3L4DXL7RDg5aBmDRgz6TOJbCXBDq8As5eXUjBYz7g
|
||||
6xvgHxLayWQyaPJFpQEHRozYjEnx3asufCsbTzabRUN3RBpw2oSxO316ZYpZzUAI/Zm/uVwOdc6wNOCq
|
||||
CKOzZ/bLyoaIFBuQWvuCNOCeCYfG6uy5PHY5lrZZaeAM5PeXh71zaEb14qrlCaqaQtLAPn6gvfyNgcka
|
||||
kAbto3vaSxoY/X9HpXlCGrSO7Kq8nrwgPNwzV8Vpf8X65jEqqidK/w+tw9sqr2dz/wYavWuod6/A6lhC
|
||||
TfsczLZpVDVOabFZ+ZP47yjKB3q7lEPomoQ8AAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<data name="tsbApplyProfile.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKqSURBVDhPY8AGVFQY2DUdxM1NQqQiQFjDRcxCRoaBEyqN
|
||||
H6jZi9pET9LfVL7P9m3dEdf/VYfs/mevMX8f0KixVdtZ3AGqDDuwTZAraT8R9H/yueT/7ScC/zcc9fhf
|
||||
e9gZbAgIZ60y+28eKVsNVY4KLCJlUkAau0+F/2886vm//ojb/+pDDv+BLvlfstP6f8Emy/85a83BhhgF
|
||||
SWVCtUGAvKmoRMVBm899p6P/Nx3zBtuKrDlvg8X/nDXm/ws2W/5PWWD8H+jFH3Im/EpQ7QwMdinyTRPP
|
||||
JoA1Vx60BWsGaYRpzlhm+v/Sq33/v//+DHZJ4mzD/1Yxcu0M9gwsDFpaojzRk/QO9J6O+l+x3/b/qeeb
|
||||
/r/8+gDsiqyVZmAnX3l98D8I3Hl/5n/8DMP/YZ06/93yVY4oW4iqMCibCMomzTG8BAo0kI0HHi0BK371
|
||||
9SE44C6/PgDm33p36n/MJP3/wS1aYAM8S1Wuq1oImYH9HzlB7yzI+SAXgGzcfGfS/6+/Pvx/8+3x/y+/
|
||||
3v+/+uYw2O8h7dpgHNal89+7TPWSsq2IEQPIH865ystAcV68wxpsQPI8o/8rrjf+f/r51v8zz7f+z1hu
|
||||
CrYVpBHkgqgJev/t0xRXShrziIADUd1O2A8URaAAAvk7daHx/6S5Rv/nXioEi4E0RvTogm0PbNQEG6Dp
|
||||
KBIG1gwFTA6pitthIQ5yLiikQX6O6tf7H9EL1Nym/T+gAaLZPllhLzgGkIGCoYC8a77yVZALQAbETTOA
|
||||
aAbaDHJ2ULMW2ED3QtU7cnr8ilBtqAAUI+bh0suA/v2ZMNMQHGVxUw3AGkPatH5bRsusAlkEVY4TMCqY
|
||||
Ctjpeog3mYXLLAZhPU/xFnljflBGYoIoIQJISkpyyRoKS8noC0mL64lzQ4XRAAMDAPInffz2odmOAAAA
|
||||
AElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="btnResetValue.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<data name="btnResetValue.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAAA8AAAAJCAYAAADtj3ZXAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAAA50lEQVQoU3XRvSuGURgHYBY2
|
||||
mUxvlMl/oRT1TiaTTFZ5SmHgjSxCIYXB4GMRJXaSQcmuDAwYRFE+BhJx3TyPPG8Zrjqdc36n+75PRZIk
|
||||
f9XRwhJnnPL5nyxUSSezbKX6GWCEPcrDTxGsZ4oTxuhmgmV2mKbICh/kwkPpZhvrbLDIIA3ExXi0Nl3n
|
||||
wq280MM2vXQRFy6Yp4NdorpD4uw563mcB9pZ44A5hpnhkk0KNHHHb7iKSW4pscoVx8RjzTQSVR3xynfZ
|
||||
mWqihRjUAjG4PuIH9jknQrmey9UwyjU3PJJN+Z23H8n9FxjlApHDfpvMAAAAAElFTkSuQmCC
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="lblApplications.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<data name="toolStripButton5.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
|
||||
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
|
||||
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
|
||||
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
|
||||
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
|
||||
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
|
||||
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
|
||||
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<data name="toolStripButton6.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
|
||||
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIDSURBVDhPpZLrS5NhGMb3j4SWh0oRQVExD4gonkDpg4hG
|
||||
YKxG6WBogkMZKgPNCEVJFBGdGETEvgwyO9DJE5syZw3PIlPEE9pgBCLZ5XvdMB8Ew8gXbl54nuf63dd9
|
||||
0OGSnwCahxbPRNPAPMw9Xpg6ZmF46kZZ0xSKzJPIrhpDWsVnpBhGkKx3nAX8Pv7z1zg8OoY/cITdn4fw
|
||||
bf/C0kYAN3Ma/w3gWfZL5kzTKBxjWyK2DftwI9tyMYCZKXbNHaD91bLYJrDXsYbrWfUKwJrPE9M2M1Oc
|
||||
VzOOpHI7Jr376Hi9ogHqFIANO0/MmmmbmSmm9a8ze+I4MrNWAdjtoJgWcx+PSzg166yZZ8xM8XvXDix9
|
||||
c4jIqFYAjoriBV9AhEPv1mH/sonogha0afbZMMZz+yreTGyhpusHwtNNCsA5U1zS4BLxzJIfg299qO32
|
||||
Ir7UJtZfftyATqeT+8o2D8JSjQrAJblrncYL7ZJ2+bfaFnC/1S1NjL3diRat7qrO7wLRP3HjWsojBeCo
|
||||
mDEo5mNjuweFGvjWg2EBhCbpkW78htSHHwRyNdmgAFzPEee2iFkzayy2OLXzT4gr6UdUnlXrullsxxQ+
|
||||
kx0g8BTA3aZlButjSTyjODq/WcQcW/B/Je4OQhLvKQDnzN1mp0nnkvAhR8VuMzNrpm1mpjgkoVwB/v8D
|
||||
TgDQASA1MVpwzwAAAABJRU5ErkJggg==
|
||||
</value>
|
||||
</data>
|
||||
<metadata name="ilCombo.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
<metadata name="cbValues.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth96.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth330.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth16.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
<metadata name="lblWidth30.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -4971,5 +4971,17 @@
|
||||
</SettingValues>
|
||||
<SettingMasks />
|
||||
</CustomSetting>
|
||||
<CustomSetting>
|
||||
<UserfriendlyName>DLSS/DLAA: Force DLAA</UserfriendlyName>
|
||||
<HexSettingID>0x10E41DF4</HexSettingID>
|
||||
<Description />
|
||||
<GroupName>8 - Extra</GroupName>
|
||||
</CustomSetting>
|
||||
<CustomSetting>
|
||||
<UserfriendlyName>DLSS/DLAA: Override Scale Ratio</UserfriendlyName>
|
||||
<HexSettingID>0x10E41DF5</HexSettingID>
|
||||
<Description />
|
||||
<GroupName>8 - Extra</GroupName>
|
||||
</CustomSetting>
|
||||
</Settings>
|
||||
</CustomSettingNames>
|
||||
@@ -1,12 +1,12 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.GPU;
|
||||
using NvAPIWrapper.Native;
|
||||
using NvAPIWrapper.Native.Display;
|
||||
using NvAPIWrapper.Native.Display.Structures;
|
||||
using NvAPIWrapper.Native.Exceptions;
|
||||
using NvAPIWrapper.Native.GPU;
|
||||
using NvAPIWrapper.Native.Interfaces.Display;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NvAPIWrapper.Display
|
||||
{
|
||||
@@ -41,12 +41,25 @@ namespace NvAPIWrapper.Display
|
||||
get => new DVCInformation(Handle);
|
||||
}
|
||||
|
||||
|
||||
private DisplayDevice _displayDevice;
|
||||
|
||||
/// <summary>
|
||||
/// Gets corresponding DisplayDevice based on display name
|
||||
/// </summary>
|
||||
public DisplayDevice DisplayDevice
|
||||
{
|
||||
get => new DisplayDevice(Name);
|
||||
get
|
||||
{
|
||||
|
||||
if (_displayDevice == null)
|
||||
{
|
||||
_displayDevice = new DisplayDevice(Name);
|
||||
|
||||
}
|
||||
|
||||
return _displayDevice;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -189,7 +202,7 @@ namespace NvAPIWrapper.Display
|
||||
return false;
|
||||
}
|
||||
|
||||
return Equals((Display) obj);
|
||||
return Equals((Display)obj);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -6,9 +6,9 @@ using System.ComponentModel;
|
||||
namespace ColorControl.Shared.Common
|
||||
|
||||
{
|
||||
public class AppContext
|
||||
public class GlobalContext
|
||||
{
|
||||
public static AppContext CurrentContext { get; private set; }
|
||||
public static GlobalContext CurrentContext { get; private set; }
|
||||
|
||||
public Config Config { get; private set; }
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace ColorControl.Shared.Common
|
||||
public DateTime StartTime { get; private set; } = DateTime.Now;
|
||||
public string MutexId { get; private set; }
|
||||
|
||||
public AppContext(Config config, StartUpParams startUpParams, string dataPath, LoggingRule loggingRule, string mutexId = null)
|
||||
public GlobalContext(Config config, StartUpParams startUpParams, string dataPath, LoggingRule loggingRule, string mutexId = null)
|
||||
{
|
||||
Config = config;
|
||||
StartUpParams = startUpParams;
|
||||
@@ -30,11 +30,6 @@ namespace ColorControl.Shared.Common
|
||||
CurrentContext = this;
|
||||
}
|
||||
|
||||
public bool IsServiceRunning()
|
||||
{
|
||||
return Utils.IsServiceRunning();
|
||||
}
|
||||
|
||||
public void SetLogLevel(LogLevel logLevel)
|
||||
{
|
||||
Config.LogLevel = logLevel.ToString();
|
||||
+10
-20
@@ -7,11 +7,14 @@ namespace ColorControl.Shared.Common
|
||||
{
|
||||
public static class PipeUtils
|
||||
{
|
||||
public const string ServicePipe = "servicepipe";
|
||||
public const string ElevatedPipe = "elevatedpipe";
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
public static string SendMessage(string message, int timeout = 2000)
|
||||
public static string SendMessage(string message, int timeout = 2000, string pipeName = ServicePipe)
|
||||
{
|
||||
var pipeClient = new NamedPipeClientStream(".", "testpipe", PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None);
|
||||
var pipeClient = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.None, TokenImpersonationLevel.None);
|
||||
try
|
||||
{
|
||||
pipeClient.Connect(timeout);
|
||||
@@ -61,37 +64,24 @@ namespace ColorControl.Shared.Common
|
||||
return SendMessage(message);
|
||||
}
|
||||
|
||||
public static bool? SendRpcMessage(string command)
|
||||
public static T SendRpcMessage<T>(SvcRpcMessage message, int timeout = 2000, string pipeName = ServicePipe)
|
||||
{
|
||||
var message = new SvcMessage { MessageType = SvcMessageType.ExecuteRpc, Data = command };
|
||||
|
||||
var messageJson = JsonConvert.SerializeObject(message);
|
||||
|
||||
var resultJson = SendMessage(messageJson);
|
||||
var resultJson = SendMessage(messageJson, timeout, pipeName);
|
||||
|
||||
if (resultJson == null)
|
||||
{
|
||||
return null;
|
||||
return default;
|
||||
}
|
||||
|
||||
var resultMessage = JsonConvert.DeserializeObject<SvcResultMessage>(resultJson);
|
||||
|
||||
return resultMessage.Result;
|
||||
}
|
||||
|
||||
public static T SendRpcMessage<T>(SvcRpcMessage message, int timeout = 2000) where T : class
|
||||
{
|
||||
var messageJson = JsonConvert.SerializeObject(message);
|
||||
|
||||
var resultJson = SendMessage(messageJson, timeout);
|
||||
|
||||
if (resultJson == null)
|
||||
if (resultMessage?.Data == null)
|
||||
{
|
||||
return null;
|
||||
return default;
|
||||
}
|
||||
|
||||
var resultMessage = JsonConvert.DeserializeObject<SvcResultMessage>(resultJson);
|
||||
|
||||
var result = JsonConvert.DeserializeObject<T>(resultMessage.Data);
|
||||
|
||||
return result;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using ColorControl.Shared.Services;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using static ColorControl.Shared.Native.WinApi;
|
||||
@@ -46,7 +47,7 @@ namespace ColorControl.Shared.Common
|
||||
|
||||
public static Process Parent(this Process process, IEnumerable<Process> processes = null)
|
||||
{
|
||||
if (Utils.IsAdministrator())
|
||||
if (WinApiService.IsAdministratorStatic())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
+1
-391
@@ -1,7 +1,4 @@
|
||||
using ColorControl.Shared.Contracts;
|
||||
using ColorControl.Shared.Native;
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using ColorControl.Shared.Native;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NStandard;
|
||||
@@ -14,10 +11,7 @@ using System.IO.Compression;
|
||||
using System.Net.Http;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
using System.Text;
|
||||
using Windows.Devices.Enumeration;
|
||||
using Windows.Devices.Enumeration.Pnp;
|
||||
@@ -36,7 +30,6 @@ namespace ColorControl.Shared.Common
|
||||
public static Guid GUID_CONSOLE_DISPLAY_STATE = Guid.Parse("6FE69556-704A-47A0-8F24-C28D936FDA47");
|
||||
|
||||
public static bool ConsoleOpened { get; private set; }
|
||||
public static bool UseDedicatedElevatedProcess = false;
|
||||
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
@@ -111,168 +104,6 @@ The best and suggested method to provide this is via a Windows Service. Only whe
|
||||
return path;
|
||||
}
|
||||
|
||||
private static bool? _IsAdministrator;
|
||||
|
||||
public static bool IsAdministrator()
|
||||
{
|
||||
if (_IsAdministrator.HasValue)
|
||||
{
|
||||
return _IsAdministrator.Value;
|
||||
}
|
||||
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
_IsAdministrator = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
return _IsAdministrator.Value;
|
||||
}
|
||||
|
||||
public 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();
|
||||
|
||||
WinApi.CopyData.Send(ElevatedProcessWindowHandle, 1, args);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
var fileName = Process.GetCurrentProcess().MainModule.FileName;
|
||||
|
||||
var info = new ProcessStartInfo(fileName, args)
|
||||
{
|
||||
Verb = "runas", // indicates to elevate privileges
|
||||
UseShellExecute = true,
|
||||
};
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
EnableRaisingEvents = true, // enable WaitForExit()
|
||||
StartInfo = info
|
||||
};
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
if (wait)
|
||||
{
|
||||
process.WaitForExit(); // sleep calling process thread until evoked process exit
|
||||
}
|
||||
|
||||
return process.Id;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("ExecuteElevated: " + e.Message);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static nint ElevatedProcessWindowHandle = nint.Zero;
|
||||
|
||||
public static void CheckElevatedProcess()
|
||||
{
|
||||
ElevatedProcessWindowHandle = NativeMethods.FindWindowW(null, "ElevatedForm");
|
||||
|
||||
if (ElevatedProcessWindowHandle == nint.Zero)
|
||||
{
|
||||
ExecuteElevated(StartUpParams.StartElevatedParam, false, true, true);
|
||||
|
||||
var delay = 1000;
|
||||
|
||||
while (delay >= 0)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
ElevatedProcessWindowHandle = NativeMethods.FindWindowW(null, "ElevatedForm");
|
||||
|
||||
if (ElevatedProcessWindowHandle != nint.Zero)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
break;
|
||||
}
|
||||
|
||||
delay -= 100;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsChromeFixInstalled()
|
||||
{
|
||||
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command");
|
||||
return key != null && key.GetValue(null).ToString().Contains("--disable-lcd-text");
|
||||
}
|
||||
|
||||
public static bool InstallChromeFix(bool install, string applicationDataFolder)
|
||||
{
|
||||
var argument = "--disable-lcd-text";
|
||||
|
||||
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command", true);
|
||||
if (key != null)
|
||||
{
|
||||
var value = key.GetValue(null).ToString();
|
||||
value = value.Replace("chrome.exe\" " + argument + " --", "chrome.exe\" --");
|
||||
if (install)
|
||||
{
|
||||
value = value.Replace("chrome.exe\" --", "chrome.exe\" " + argument + " --");
|
||||
}
|
||||
key.SetValue(null, value);
|
||||
}
|
||||
|
||||
var roamingFolder = applicationDataFolder ?? 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;
|
||||
}
|
||||
|
||||
public static bool IsChromeInstalled()
|
||||
{
|
||||
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command");
|
||||
return key != null;
|
||||
}
|
||||
|
||||
public static bool UpdateShortcut(string path, string arguments, bool removeArguments = false)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
|
||||
|
||||
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(path);
|
||||
|
||||
shortcut.Arguments = shortcut.Arguments.Replace(arguments, "");
|
||||
if (!removeArguments)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(shortcut.Arguments))
|
||||
{
|
||||
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;
|
||||
@@ -489,63 +320,6 @@ The best and suggested method to provide this is via a Windows Service. Only whe
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void RegisterTask(string taskName, bool enabled, TaskRunLevel runLevel = TaskRunLevel.LUA)
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated(enabled ? $"{StartUpParams.EnableAutoStartParam} {(int)runLevel}" : StartUpParams.DisableAutoStartParam, skipService: true);
|
||||
return;
|
||||
}
|
||||
|
||||
var file = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var directory = Path.GetDirectoryName(file);
|
||||
|
||||
try
|
||||
{
|
||||
using (TaskService ts = new TaskService())
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
var td = ts.NewTask();
|
||||
|
||||
td.RegistrationInfo.Description = "Start ColorControl";
|
||||
td.Principal.RunLevel = runLevel;
|
||||
|
||||
td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name });
|
||||
|
||||
td.Actions.Add(new ExecAction(file, StartUpParams.RunningFromScheduledTaskParam, directory));
|
||||
|
||||
ts.RootFolder.RegisterTaskDefinition(taskName, td);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.RootFolder.DeleteTask(taskName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Could not create/delete task: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TaskExists(string taskName)
|
||||
{
|
||||
using (TaskService ts = new TaskService())
|
||||
{
|
||||
var task = ts.RootFolder.Tasks.FirstOrDefault(x => x.Name.Equals(taskName));
|
||||
|
||||
return task != null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CheckWin32Error(string message)
|
||||
{
|
||||
var errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
|
||||
|
||||
throw new Exception($"{message}: {errorMessage}");
|
||||
}
|
||||
|
||||
public static bool OpenConsole()
|
||||
{
|
||||
if (ConsoleOpened)
|
||||
@@ -601,76 +375,6 @@ The best and suggested method to provide this is via a Windows Service. Only whe
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Process StartProcess(string fileName, string arguments = null, bool hidden = false, bool wait = false, bool setWorkingDir = false, bool elevate = false, uint affinityMask = 0, uint priorityClass = 0)
|
||||
{
|
||||
var process = Process.Start(new ProcessStartInfo(fileName, arguments)
|
||||
{
|
||||
Verb = elevate ? "runas" : string.Empty, // indicates to elevate privileges
|
||||
UseShellExecute = true,
|
||||
WindowStyle = hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal,
|
||||
WorkingDirectory = setWorkingDir ? Path.GetDirectoryName(fileName) : null
|
||||
});
|
||||
|
||||
if (affinityMask > 0)
|
||||
{
|
||||
SetProcessAffinity(process.Id, affinityMask);
|
||||
}
|
||||
|
||||
if (priorityClass > 0 && priorityClass != NativeConstants.NORMAL_PRIORITY_CLASS)
|
||||
{
|
||||
SetProcessPriority(process.Id, priorityClass);
|
||||
}
|
||||
|
||||
if (wait)
|
||||
{
|
||||
process.WaitForExit();
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
public static void SetProcessAffinity(int processId, uint affinityMask)
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated($"{StartUpParams.SetProcessAffinityParam} {processId} {affinityMask}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var hProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_ALL_ACCESS, false, (uint)processId);
|
||||
|
||||
if (hProcess == nint.Zero)
|
||||
{
|
||||
CheckWin32Error($"Unable to set processor affinity on process {processId}");
|
||||
}
|
||||
|
||||
NativeMethods.SetProcessAffinityMask(hProcess, affinityMask);
|
||||
|
||||
//var AffinityMask = (long)process.ProcessorAffinity;
|
||||
//AffinityMask &= 0x000F; // use only any of the first 4 available processors
|
||||
//process.ProcessorAffinity = (IntPtr)AffinityMask;
|
||||
}
|
||||
|
||||
public static void SetProcessPriority(int processId, uint priorityClass)
|
||||
{
|
||||
if (!IsAdministrator())
|
||||
{
|
||||
ExecuteElevated($"{StartUpParams.SetProcessPriorityParam} {processId} {priorityClass}");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var hProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_ALL_ACCESS, false, (uint)processId);
|
||||
|
||||
if (hProcess == nint.Zero)
|
||||
{
|
||||
CheckWin32Error($"Unable to set process priority on process {processId}");
|
||||
}
|
||||
|
||||
NativeMethods.SetPriorityClass(hProcess, priorityClass);
|
||||
}
|
||||
|
||||
public static string GetResourceFile(string resourceName)
|
||||
{
|
||||
resourceName = "ColorControl.Resources." + resourceName;
|
||||
@@ -794,100 +498,6 @@ The best and suggested method to provide this is via a Windows Service. Only whe
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
public 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();
|
||||
}
|
||||
|
||||
public 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 async Task<bool> PingHost(string nameOrAddress)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
using ColorControl.Shared.Contracts;
|
||||
using NLog;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using Vanara.PInvoke;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
|
||||
namespace ColorControl.Shared.Common
|
||||
{
|
||||
public 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, string ipAddress = null)
|
||||
{
|
||||
return WakeFunctionToAllNics(macAddress, ipAddress);
|
||||
}
|
||||
|
||||
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 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") || ni.Name.Contains("vEthernet") || ni.Description.Contains("Virtual")*/)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Logger.Debug($"Found network: {ni.Name} ({ni.Description}), type: {ni.NetworkInterfaceType}");
|
||||
try
|
||||
{
|
||||
if (ni.SupportsMulticast && ni.GetIPProperties().GetIPv4Properties() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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 && Utils.IsAdministrator())
|
||||
{
|
||||
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)
|
||||
{
|
||||
Logger.Error($"WakeFunctionToAllNics: while sending to specific network: {ni.Name} ({ni.Description}): {ex.ToLogString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"WakeFunctionToAllNics: {ex.ToLogString()}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <exception cref="ArgumentNullException"><paramref name="macAddress"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException">The length of the <see cref="T:System.Byte" /> array <paramref name="macAddress"/> is not 6.</exception>
|
||||
/// <exception cref="ArgumentException">The length of the <see cref="T:System.Byte" /> array <paramref name="password"/> is not 0 or 6.</exception>
|
||||
private static byte[] GetWolPacket(byte[] macAddress, byte[] password = null)
|
||||
{
|
||||
if (macAddress == null)
|
||||
throw new ArgumentNullException(nameof(macAddress));
|
||||
if (macAddress.Length != 6)
|
||||
throw new ArgumentException(ArgumentExceptionInvalidMacAddressLength);
|
||||
|
||||
password = password ?? new byte[0];
|
||||
if (password.Length != 0 && password.Length != 6)
|
||||
throw new ArgumentException(ArgumentExceptionInvalidPasswordLength);
|
||||
|
||||
var packet = new byte[17 * 6 + password.Length];
|
||||
|
||||
int offset, i;
|
||||
for (offset = 0; offset < 6; ++offset)
|
||||
packet[offset] = 0xFF;
|
||||
|
||||
for (offset = 6; offset < 17 * 6; offset += 6)
|
||||
for (i = 0; i < 6; ++i)
|
||||
packet[i + offset] = macAddress[i];
|
||||
|
||||
if (password.Length > 0)
|
||||
{
|
||||
for (offset = 16 * 6 + 6; offset < 17 * 6 + password.Length; offset += 6)
|
||||
for (i = 0; i < 6; ++i)
|
||||
packet[i + offset] = password[i];
|
||||
}
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,8 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
|
||||
namespace ColorControl.Shared.Contracts
|
||||
namespace ColorControl.Shared.Contracts
|
||||
{
|
||||
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 const string ExecuteHelpParam = "--help";
|
||||
public const string ExecuteNvidiaPresetParam = "--nvpreset";
|
||||
public const string ExecuteAmdPresetParam = "--amdpreset";
|
||||
@@ -15,21 +10,9 @@ namespace ColorControl.Shared.Contracts
|
||||
public const string ExecuteSamsungPresetParam = "--sampreset";
|
||||
public const string NoDeviceRefreshParam = "--no-refresh";
|
||||
public const string NoGuiParam = "--nogui";
|
||||
public const string EnableAutoStartParam = "--enable-auto-start";
|
||||
public const string DisableAutoStartParam = "--disable-auto-start";
|
||||
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; }
|
||||
public bool DeactivateChromeFontFix { get; private set; }
|
||||
public string ChromeFontFixApplicationDataFolder { get; private set; }
|
||||
public bool ExecuteHelp { get; private set; }
|
||||
public bool ExecuteNvidiaPreset { get; private set; }
|
||||
public string NvidiaPresetIdOrName { get; private set; }
|
||||
@@ -41,22 +24,7 @@ namespace ColorControl.Shared.Contracts
|
||||
public string SamsungPresetName { get; private set; }
|
||||
public bool NoDeviceRefresh { 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; }
|
||||
public uint AffinityMask { get; private set; }
|
||||
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)
|
||||
{
|
||||
@@ -68,12 +36,6 @@ namespace ColorControl.Shared.Contracts
|
||||
{
|
||||
switch (parseNameParam)
|
||||
{
|
||||
case ActivateChromeFontFixParam:
|
||||
case DeactivateChromeFontFixParam:
|
||||
{
|
||||
settings.ChromeFontFixApplicationDataFolder = arg;
|
||||
break;
|
||||
}
|
||||
case ExecuteNvidiaPresetParam:
|
||||
{
|
||||
settings.NvidiaPresetIdOrName = arg;
|
||||
@@ -94,44 +56,6 @@ namespace ColorControl.Shared.Contracts
|
||||
settings.SamsungPresetName = arg;
|
||||
break;
|
||||
}
|
||||
case SetProcessAffinityParam:
|
||||
{
|
||||
if (settings.ProcessId == 0)
|
||||
{
|
||||
settings.ProcessId = int.Parse(arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
settings.AffinityMask = uint.Parse(arg);
|
||||
break;
|
||||
}
|
||||
case SetProcessPriorityParam:
|
||||
{
|
||||
if (settings.ProcessId == 0)
|
||||
{
|
||||
settings.ProcessId = int.Parse(arg);
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -145,18 +69,6 @@ namespace ColorControl.Shared.Contracts
|
||||
settings.RunningFromScheduledTask = true;
|
||||
break;
|
||||
}
|
||||
case ActivateChromeFontFixParam:
|
||||
{
|
||||
settings.ActivateChromeFontFix = true;
|
||||
parseNameParam = ActivateChromeFontFixParam;
|
||||
break;
|
||||
}
|
||||
case DeactivateChromeFontFixParam:
|
||||
{
|
||||
settings.DeactivateChromeFontFix = true;
|
||||
parseNameParam = DeactivateChromeFontFixParam;
|
||||
break;
|
||||
}
|
||||
case ExecuteHelpParam:
|
||||
{
|
||||
settings.ExecuteHelp = true;
|
||||
@@ -192,60 +104,11 @@ namespace ColorControl.Shared.Contracts
|
||||
settings.NoGui = true;
|
||||
break;
|
||||
}
|
||||
case EnableAutoStartParam:
|
||||
{
|
||||
settings.EnableAutoStart = true;
|
||||
parseNameParam = EnableAutoStartParam;
|
||||
break;
|
||||
}
|
||||
case DisableAutoStartParam:
|
||||
{
|
||||
settings.DisableAutoStart = true;
|
||||
break;
|
||||
}
|
||||
case SetProcessAffinityParam:
|
||||
{
|
||||
settings.SetProcessAffinity = true;
|
||||
parseNameParam = SetProcessAffinityParam;
|
||||
break;
|
||||
}
|
||||
case SetProcessPriorityParam:
|
||||
{
|
||||
settings.SetProcessPriority = true;
|
||||
parseNameParam = SetProcessPriorityParam;
|
||||
break;
|
||||
}
|
||||
case StartElevatedParam:
|
||||
{
|
||||
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;
|
||||
}
|
||||
case NoDeviceRefreshParam:
|
||||
{
|
||||
settings.NoDeviceRefresh = true;
|
||||
|
||||
@@ -1,70 +1,81 @@
|
||||
using ColorControl.Shared.Contracts.NVIDIA;
|
||||
|
||||
namespace ColorControl.Shared.Contracts
|
||||
namespace ColorControl.Shared.Contracts;
|
||||
|
||||
public enum SvcMessageType
|
||||
{
|
||||
public enum SvcMessageType
|
||||
SetLgConfig = 1,
|
||||
GetLog = 2,
|
||||
ClearLog = 3,
|
||||
ExecuteRpc = 10,
|
||||
ExecuteRpcGeneric = 11,
|
||||
ExecuteRpcGenericTyped = 12,
|
||||
ExecuteUpdate = 20,
|
||||
RestartAfterUpdate = 21,
|
||||
}
|
||||
|
||||
public class SvcMessage
|
||||
{
|
||||
public SvcMessageType MessageType { get; set; }
|
||||
|
||||
public string Data { get; set; }
|
||||
}
|
||||
|
||||
public class SvcInstallUpdateMessage : SvcMessage
|
||||
{
|
||||
public SvcInstallUpdateMessage()
|
||||
{
|
||||
SetLgConfig = 1,
|
||||
GetLog = 2,
|
||||
ClearLog = 3,
|
||||
ExecuteRpc = 10,
|
||||
ExecuteRpcGeneric = 11,
|
||||
ExecuteUpdate = 20,
|
||||
RestartAfterUpdate = 21,
|
||||
ApplyNvidiaDriverSettings = 101,
|
||||
RestoreNvidiaDriverSetting = 102,
|
||||
ApplyNvidiaOverclocking = 110,
|
||||
MessageType = SvcMessageType.ExecuteUpdate;
|
||||
}
|
||||
|
||||
public class SvcMessage
|
||||
{
|
||||
public SvcMessageType MessageType { get; set; }
|
||||
public string DownloadUrl { get; set; }
|
||||
public string ClientPath { get; set; }
|
||||
}
|
||||
|
||||
public string Data { get; set; }
|
||||
public class SvcRpcMessage : SvcMessage
|
||||
{
|
||||
public SvcRpcMessage()
|
||||
{
|
||||
MessageType = SvcMessageType.ExecuteRpcGeneric;
|
||||
}
|
||||
|
||||
public class SvcInstallUpdateMessage : SvcMessage
|
||||
private string _typeName;
|
||||
public string TypeName
|
||||
{
|
||||
public SvcInstallUpdateMessage()
|
||||
get
|
||||
{
|
||||
MessageType = SvcMessageType.ExecuteUpdate;
|
||||
}
|
||||
if (_typeName == null)
|
||||
{
|
||||
_typeName = GetType().Name;
|
||||
}
|
||||
|
||||
public string DownloadUrl { get; set; }
|
||||
public string ClientPath { get; set; }
|
||||
return _typeName;
|
||||
|
||||
}
|
||||
set { _typeName = value; }
|
||||
}
|
||||
public string ServiceName { get; set; }
|
||||
public string MethodName { get; set; }
|
||||
public object[] Arguments { get; set; }
|
||||
}
|
||||
|
||||
public class SvcNvDriverSettingsMessage : SvcMessage
|
||||
public class SvcRpcMessageTyped : SvcRpcMessage
|
||||
{
|
||||
public SvcRpcMessageTyped() : base()
|
||||
{
|
||||
public SvcNvDriverSettingsMessage(SvcMessageType messageType = SvcMessageType.ApplyNvidiaDriverSettings)
|
||||
{
|
||||
MessageType = messageType;
|
||||
}
|
||||
|
||||
public string ProfileName { get; set; }
|
||||
|
||||
public List<KeyValuePair<uint, string>> DriverSettings { get; set; }
|
||||
}
|
||||
|
||||
public class SvcNvOverclockingMessage : SvcMessage
|
||||
{
|
||||
public SvcNvOverclockingMessage(SvcMessageType messageType = SvcMessageType.ApplyNvidiaOverclocking)
|
||||
{
|
||||
MessageType = messageType;
|
||||
}
|
||||
|
||||
public List<NvGpuOcSettings> OverclockingSettings { get; set; }
|
||||
}
|
||||
|
||||
public class SvcRpcMessage : SvcMessage
|
||||
{
|
||||
public SvcRpcMessage()
|
||||
{
|
||||
MessageType = SvcMessageType.ExecuteRpcGeneric;
|
||||
}
|
||||
|
||||
public string ServiceName { get; set; }
|
||||
public string MethodName { get; set; }
|
||||
public object[] Arguments { get; set; }
|
||||
MessageType = SvcMessageType.ExecuteRpcGenericTyped;
|
||||
}
|
||||
}
|
||||
|
||||
public class SvcRpcSetNvDriverSettingsMessage : SvcRpcMessageTyped
|
||||
{
|
||||
public string ProfileName { get; set; }
|
||||
|
||||
public List<KeyValuePair<uint, string>> DriverSettings { get; set; }
|
||||
}
|
||||
|
||||
public class SvcRpcSetNvOverclockingMessage : SvcRpcMessageTyped
|
||||
{
|
||||
public List<NvGpuOcSettings> OverclockingSettings { get; set; }
|
||||
}
|
||||
|
||||
@@ -531,5 +531,31 @@ namespace ColorControl.Shared.Forms
|
||||
|
||||
return prompt;
|
||||
}
|
||||
|
||||
public static Form ShowControl(Control control, string title)
|
||||
{
|
||||
var prompt = new Form()
|
||||
{
|
||||
Icon = MainForm.Icon,
|
||||
Text = title,
|
||||
Width = 800,
|
||||
Height = 400,
|
||||
StartPosition = FormStartPosition.CenterScreen,
|
||||
BackColor = FormUtils.CurrentBackColor,
|
||||
ForeColor = FormUtils.CurrentForeColor,
|
||||
};
|
||||
|
||||
prompt.Controls.Add(control);
|
||||
|
||||
control.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
|
||||
control.Width = prompt.ClientRectangle.Width;
|
||||
control.Height = prompt.ClientRectangle.Height;
|
||||
|
||||
prompt.UpdateTheme(onlyIfDark: true);
|
||||
|
||||
prompt.Show(MainForm);
|
||||
|
||||
return prompt;
|
||||
}
|
||||
}
|
||||
}
|
||||
+77
-163
@@ -1,170 +1,84 @@
|
||||
using NWin32.NativeTypes;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace ColorControl.Shared.Native
|
||||
namespace ColorControl.Shared.Native;
|
||||
|
||||
public static class WinApi
|
||||
{
|
||||
public static class WinApi
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct POWERBROADCAST_SETTING
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
||||
public struct POWERBROADCAST_SETTING
|
||||
{
|
||||
public Guid PowerSetting;
|
||||
public uint DataLength;
|
||||
public byte Data;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct COPYDATASTRUCT
|
||||
{
|
||||
public IntPtr dwData; // in C/C++ this is an UINT_PTR, not an UINT
|
||||
public int cbData;
|
||||
public IntPtr lpData;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CopyData : IDisposable
|
||||
{
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
|
||||
static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, IntPtr wParam, ref CopyData target,
|
||||
SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);
|
||||
|
||||
[Flags]
|
||||
enum SendMessageTimeoutFlags : uint
|
||||
{
|
||||
SMTO_NORMAL = 0x0,
|
||||
SMTO_BLOCK = 0x1,
|
||||
SMTO_ABORTIFHUNG = 0x2,
|
||||
SMTO_NOTIMEOUTIFNOTHUNG = 0x8
|
||||
}
|
||||
const uint WM_COPYDATA = 0x4A;
|
||||
|
||||
public IntPtr dwData;
|
||||
public int cbData;
|
||||
public IntPtr lpData;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (lpData != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeCoTaskMem(lpData);
|
||||
lpData = IntPtr.Zero;
|
||||
cbData = 0;
|
||||
}
|
||||
}
|
||||
public string AsAnsiString
|
||||
{
|
||||
get { return Marshal.PtrToStringAnsi(lpData, cbData); }
|
||||
}
|
||||
public string AsUnicodeString
|
||||
{
|
||||
get { return Marshal.PtrToStringUni(lpData); }
|
||||
}
|
||||
public static CopyData CreateForString(int dwData, string value, bool Unicode = false)
|
||||
{
|
||||
var result = new CopyData();
|
||||
result.dwData = (IntPtr)dwData;
|
||||
result.lpData = Unicode ? Marshal.StringToCoTaskMemUni(value) : Marshal.StringToCoTaskMemAnsi(value);
|
||||
result.cbData = value.Length + 2;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static UIntPtr Send(IntPtr targetHandle, int dwData, string value, uint timeoutMs = 1000, bool Unicode = false)
|
||||
{
|
||||
var cds = CreateForString(dwData, value, Unicode);
|
||||
UIntPtr result;
|
||||
SendMessageTimeout(targetHandle, WM_COPYDATA, IntPtr.Zero, ref cds, SendMessageTimeoutFlags.SMTO_NORMAL, timeoutMs, out result);
|
||||
cds.Dispose();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public enum MessageFilterInfo : uint
|
||||
{
|
||||
None = 0, AlreadyAllowed = 1, AlreadyDisAllowed = 2, AllowedHigher = 3
|
||||
};
|
||||
|
||||
public enum ChangeWindowMessageFilterExAction : uint
|
||||
{
|
||||
Reset = 0, Allow = 1, DisAllow = 2
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct CHANGEFILTERSTRUCT
|
||||
{
|
||||
public uint size;
|
||||
public MessageFilterInfo info;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ParentProcessUtilities
|
||||
{
|
||||
// These members must match PROCESS_BASIC_INFORMATION
|
||||
internal IntPtr Reserved1;
|
||||
internal IntPtr PebBaseAddress;
|
||||
internal IntPtr Reserved2_0;
|
||||
internal IntPtr Reserved2_1;
|
||||
internal IntPtr UniqueProcessId;
|
||||
internal IntPtr InheritedFromUniqueProcessId;
|
||||
}
|
||||
|
||||
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||
public const int ENUM_REGISTRY_SETTINGS = -2;
|
||||
|
||||
public static int PBT_POWERSETTINGCHANGE = 32787;
|
||||
|
||||
public delegate void PCREATE_PROCESS_NOTIFY_ROUTINE(IntPtr ParentId, IntPtr ProcessId, bool Create);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumDisplaySettingsA(string deviceName, int modeNum, out DEVMODEA devMode);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool AllocConsole();
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
public static extern bool AttachConsole(int processId);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FreeConsole();
|
||||
|
||||
[DllImport(@"User32", SetLastError = true)]
|
||||
public static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid, Int32 Flags);
|
||||
|
||||
[DllImport("User32.dll", SetLastError = true)]
|
||||
public static extern bool UnregisterPowerSettingNotification(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, ChangeWindowMessageFilterExAction action, ref CHANGEFILTERSTRUCT changeInfo);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, EntryPoint = "#104")]
|
||||
public static extern int RefreshImmersiveColorPolicyState();
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, EntryPoint = "#133")]
|
||||
public static extern int AllowDarkModeForWindow(IntPtr hWnd, bool allow);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, EntryPoint = "#135")]
|
||||
public static extern int SetPreferredAppMode(int appMode);
|
||||
|
||||
[DllImport("uxtheme.dll", EntryPoint = "#136")]
|
||||
public static extern void FlushMenuThemes();
|
||||
|
||||
[DllImport("dwmapi.dll", PreserveSig = true)]
|
||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
public static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
|
||||
|
||||
[DllImport("dwmapi.dll", EntryPoint = "#171")]
|
||||
public static extern void DwmpSDRToHDRBoostPtr(IntPtr monitor, double brightness);
|
||||
public Guid PowerSetting;
|
||||
public uint DataLength;
|
||||
public byte Data;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ParentProcessUtilities
|
||||
{
|
||||
// These members must match PROCESS_BASIC_INFORMATION
|
||||
internal IntPtr Reserved1;
|
||||
internal IntPtr PebBaseAddress;
|
||||
internal IntPtr Reserved2_0;
|
||||
internal IntPtr Reserved2_1;
|
||||
internal IntPtr UniqueProcessId;
|
||||
internal IntPtr InheritedFromUniqueProcessId;
|
||||
}
|
||||
|
||||
public const int ENUM_CURRENT_SETTINGS = -1;
|
||||
public const int ENUM_REGISTRY_SETTINGS = -2;
|
||||
|
||||
public static int PBT_POWERSETTINGCHANGE = 32787;
|
||||
|
||||
public delegate void PCREATE_PROCESS_NOTIFY_ROUTINE(IntPtr ParentId, IntPtr ProcessId, bool Create);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool EnumDisplaySettingsA(string deviceName, int modeNum, out DEVMODEA devMode);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool AllocConsole();
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
||||
public static extern bool AttachConsole(int processId);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool FreeConsole();
|
||||
|
||||
[DllImport(@"User32", SetLastError = true)]
|
||||
public static extern IntPtr RegisterPowerSettingNotification(IntPtr hRecipient, ref Guid PowerSettingGuid, Int32 Flags);
|
||||
|
||||
[DllImport("User32.dll", SetLastError = true)]
|
||||
public static extern bool UnregisterPowerSettingNotification(IntPtr hWnd);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int SetWindowTheme(IntPtr hWnd, string pszSubAppName, string pszSubIdList);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, EntryPoint = "#104")]
|
||||
public static extern int RefreshImmersiveColorPolicyState();
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, EntryPoint = "#133")]
|
||||
public static extern int AllowDarkModeForWindow(IntPtr hWnd, bool allow);
|
||||
|
||||
[DllImport("uxtheme.dll", CharSet = CharSet.Unicode, EntryPoint = "#135")]
|
||||
public static extern int SetPreferredAppMode(int appMode);
|
||||
|
||||
[DllImport("uxtheme.dll", EntryPoint = "#136")]
|
||||
public static extern void FlushMenuThemes();
|
||||
|
||||
[DllImport("dwmapi.dll", PreserveSig = true)]
|
||||
public static extern int DwmSetWindowAttribute(IntPtr hwnd, int attr, ref int attrValue, int attrSize);
|
||||
|
||||
[DllImport("ntdll.dll")]
|
||||
public static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, ref ParentProcessUtilities processInformation, int processInformationLength, out int returnLength);
|
||||
|
||||
[DllImport("dwmapi.dll", EntryPoint = "#171")]
|
||||
public static extern void DwmpSDRToHDRBoostPtr(IntPtr monitor, double brightness);
|
||||
}
|
||||
@@ -2,14 +2,14 @@
|
||||
{
|
||||
public class AppContextProvider
|
||||
{
|
||||
private Common.AppContext _appContext;
|
||||
private Common.GlobalContext _appContext;
|
||||
|
||||
public void SetAppContext(Common.AppContext appContext)
|
||||
public void SetAppContext(Common.GlobalContext appContext)
|
||||
{
|
||||
_appContext = appContext;
|
||||
}
|
||||
|
||||
public Common.AppContext GetAppContext()
|
||||
public Common.GlobalContext GetAppContext()
|
||||
{
|
||||
return _appContext;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ColorControl.Shared.Services;
|
||||
|
||||
public class RpcClientService
|
||||
{
|
||||
private readonly WinElevatedProcessManager _elevatedProcessManager;
|
||||
private readonly WinApiService _winApiService;
|
||||
private readonly RpcServerService _rpcServerService;
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public RpcClientService(WinElevatedProcessManager elevatedProcessManager, WinApiService winApiService, RpcServerService rpcServerService)
|
||||
{
|
||||
_elevatedProcessManager = elevatedProcessManager;
|
||||
_winApiService = winApiService;
|
||||
_rpcServerService = rpcServerService;
|
||||
}
|
||||
|
||||
public T Call<T>(string method, params object[] arguments)
|
||||
{
|
||||
if (!_winApiService.IsServiceRunning())
|
||||
{
|
||||
// Last resort: try via elevated process
|
||||
return ExecuteViaElevatedProcess<T>(method, arguments);
|
||||
}
|
||||
|
||||
var rpcMessage = new SvcRpcMessage
|
||||
{
|
||||
ServiceName = Name,
|
||||
MethodName = method,
|
||||
Arguments = arguments
|
||||
};
|
||||
|
||||
//var json = JsonConvert.SerializeObject(rpcMessage);
|
||||
//var msg = JsonConvert.DeserializeObject<SvcRpcMessage>(json);
|
||||
//var _ = _rpcServerService.ExecuteRpcAsync(msg);
|
||||
//return default;
|
||||
|
||||
return PipeUtils.SendRpcMessage<T>(rpcMessage);
|
||||
}
|
||||
|
||||
public T Call<T>(SvcRpcMessage message)
|
||||
{
|
||||
message.ServiceName = Name;
|
||||
|
||||
if (Debugger.IsAttached)
|
||||
{
|
||||
return PipeUtils.SendRpcMessage<T>(message, pipeName: PipeUtils.ElevatedPipe);
|
||||
}
|
||||
|
||||
if (!_winApiService.IsServiceRunning())
|
||||
{
|
||||
// Last resort: try via elevated process
|
||||
return ExecuteViaElevatedProcess<T>(message);
|
||||
}
|
||||
|
||||
return PipeUtils.SendRpcMessage<T>(message);
|
||||
}
|
||||
|
||||
private T ExecuteViaElevatedProcess<T>(string method, params object[] arguments)
|
||||
{
|
||||
return _elevatedProcessManager.ExecuteElevated<T>(method, arguments);
|
||||
}
|
||||
|
||||
private T ExecuteViaElevatedProcess<T>(SvcRpcMessage message)
|
||||
{
|
||||
return _elevatedProcessManager.ExecuteElevated<T>(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using ColorControl.Shared.Contracts;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Newtonsoft.Json;
|
||||
using System.Reflection;
|
||||
|
||||
namespace ColorControl.Shared.Services;
|
||||
|
||||
public class RpcServerService
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
|
||||
public static List<Type> ServiceTypes = new List<Type>();
|
||||
|
||||
public RpcServerService(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public async Task<SvcResultMessage> ExecuteRpcAsync(SvcRpcMessage message)
|
||||
{
|
||||
try
|
||||
{
|
||||
var service = GetServiceInstance(message.ServiceName);
|
||||
|
||||
var method = service.GetType().GetMethod(message.MethodName);
|
||||
|
||||
var convertedArgs = new List<object>();
|
||||
|
||||
var methodParams = method.GetParameters();
|
||||
for (var i = 0; i < message.Arguments.Length; i++)
|
||||
{
|
||||
var arg = message.Arguments[i];
|
||||
var methodParam = methodParams[i];
|
||||
|
||||
var convertedArg = ConvertArgument(arg, methodParam.ParameterType);
|
||||
convertedArgs.Add(arg);
|
||||
}
|
||||
|
||||
Logger.Debug($"Executing RPC: {message.ServiceName}.{message.MethodName}({string.Join(", ", convertedArgs)})");
|
||||
|
||||
var result = method.Invoke(service, convertedArgs.ToArray());
|
||||
|
||||
var data = JsonConvert.SerializeObject(result);
|
||||
|
||||
return SvcResultMessage.FromResult(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex, $"ExecuteRpcAsync: {ex.Message}");
|
||||
|
||||
return new SvcResultMessage { ErrorMessage = ex.Message, Result = false };
|
||||
}
|
||||
}
|
||||
|
||||
private object ConvertArgument(object arg, Type type)
|
||||
{
|
||||
if (arg.GetType() != type)
|
||||
{
|
||||
if (type.IsEnum)
|
||||
{
|
||||
return Enum.ToObject(type, arg);
|
||||
}
|
||||
|
||||
var convertedArg = Convert.ChangeType(arg, type);
|
||||
return convertedArg;
|
||||
}
|
||||
|
||||
return arg;
|
||||
|
||||
}
|
||||
|
||||
public async Task<SvcResultMessage> ExecuteRpcTypedAsync(SvcRpcMessageTyped message)
|
||||
{
|
||||
try
|
||||
{
|
||||
var service = GetServiceInstance(message.ServiceName);
|
||||
|
||||
var method = service.GetType().GetMethod(message.MethodName);
|
||||
|
||||
var props = message.GetType().GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);
|
||||
var methodParams = method.GetParameters();
|
||||
|
||||
var convertedArgs = new List<object>();
|
||||
var paramIndex = 0;
|
||||
|
||||
foreach (var prop in props)
|
||||
{
|
||||
Logger.Debug($"Prop: {prop.Name}");
|
||||
|
||||
var arg = prop.GetValue(message);
|
||||
var methodParam = methodParams[paramIndex];
|
||||
|
||||
var convertedArg = ConvertArgument(arg, methodParam.ParameterType);
|
||||
convertedArgs.Add(arg);
|
||||
|
||||
paramIndex++;
|
||||
}
|
||||
|
||||
Logger.Debug($"Executing RPC-typed: {message.ServiceName}.{message.MethodName}({string.Join(", ", convertedArgs)})");
|
||||
|
||||
var result = method.Invoke(service, convertedArgs.ToArray());
|
||||
|
||||
var data = JsonConvert.SerializeObject(result);
|
||||
|
||||
return SvcResultMessage.FromResult(data);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error(ex, $"ExecuteRpcTypedAsync: {ex.Message}");
|
||||
|
||||
return new SvcResultMessage { ErrorMessage = ex.Message, Result = false };
|
||||
}
|
||||
}
|
||||
|
||||
private object GetServiceInstance(string name)
|
||||
{
|
||||
var type = Type.GetType($"ColorControl.Shared.Services.{name}");
|
||||
|
||||
type ??= Type.GetType($"ColorControl.Services.NVIDIA.{name}");
|
||||
|
||||
type ??= ServiceTypes.FirstOrDefault(t => t.Name == name);
|
||||
|
||||
if (type == null)
|
||||
{
|
||||
throw new InvalidOperationException($"Type not found: {name}");
|
||||
}
|
||||
|
||||
var service = _serviceProvider.GetRequiredService(type);
|
||||
|
||||
return service;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
|
||||
namespace ColorControl.Shared.Services
|
||||
{
|
||||
public class RpcService
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public T Call<T>(string method, params object[] arguments) where T : class
|
||||
{
|
||||
var rpcMessage = new SvcRpcMessage
|
||||
{
|
||||
ServiceName = Name,
|
||||
MethodName = method,
|
||||
Arguments = arguments
|
||||
};
|
||||
|
||||
return PipeUtils.SendRpcMessage<T>(rpcMessage);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
using ColorControl.Shared.Contracts;
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using NWin32;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace ColorControl.Shared.Services
|
||||
{
|
||||
public class WinApiAdminService
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
public static string SERVICE_NAME = "Color Control Service";
|
||||
private readonly WinApiService _winApiService;
|
||||
private RpcClientService _rpcService;
|
||||
private readonly WinElevatedProcessManager _elevatedProcessManager;
|
||||
private bool? _IsAdministrator;
|
||||
|
||||
public WinApiAdminService(WinApiService winApiService, RpcClientService rpcService, WinElevatedProcessManager elevatedProcessManager)
|
||||
{
|
||||
_winApiService = winApiService;
|
||||
_rpcService = rpcService;
|
||||
_elevatedProcessManager = elevatedProcessManager;
|
||||
_rpcService.Name = nameof(WinApiAdminService);
|
||||
}
|
||||
|
||||
public bool SuspendThread(uint threadId)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<bool>(nameof(SuspendThread), threadId);
|
||||
}
|
||||
|
||||
var handle = NativeMethods.OpenThread(NativeConstants.THREAD_ALL_ACCESS, false, threadId);
|
||||
|
||||
try
|
||||
{
|
||||
var result = NativeMethods.SuspendThread(handle);
|
||||
|
||||
return ProcessResult(result);
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
|
||||
private int GetProcessMainThread(Process process)
|
||||
{
|
||||
var minStartTime = DateTime.MaxValue;
|
||||
var mainThread = default(ProcessThread);
|
||||
|
||||
for (var i = 0; i < process.Threads.Count; i++)
|
||||
{
|
||||
var thread = process.Threads[i];
|
||||
try
|
||||
{
|
||||
if (thread.StartTime < minStartTime)
|
||||
{
|
||||
mainThread = thread;
|
||||
minStartTime = thread.StartTime;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
return mainThread.Id;
|
||||
}
|
||||
|
||||
public int SuspendMainThread(int processId)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<int>(nameof(SuspendMainThread), processId);
|
||||
}
|
||||
|
||||
var process = Process.GetProcessById(processId);
|
||||
var threadId = GetProcessMainThread(process);
|
||||
|
||||
if (SuspendThread((uint)threadId))
|
||||
{
|
||||
return threadId;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool ResumeThread(uint threadId)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<bool>(nameof(ResumeThread), threadId);
|
||||
}
|
||||
|
||||
var handle = NativeMethods.OpenThread(NativeConstants.THREAD_ALL_ACCESS, false, threadId);
|
||||
|
||||
try
|
||||
{
|
||||
var result = NativeMethods.ResumeThread(handle);
|
||||
|
||||
return ProcessResult(result);
|
||||
}
|
||||
finally
|
||||
{
|
||||
NativeMethods.CloseHandle(handle);
|
||||
}
|
||||
}
|
||||
|
||||
public Process StartProcess(string fileName, string arguments = null, bool hidden = false, bool wait = false, bool setWorkingDir = false, bool elevate = false, uint affinityMask = 0, uint priorityClass = 0)
|
||||
{
|
||||
var process = Process.Start(new ProcessStartInfo(fileName, arguments)
|
||||
{
|
||||
Verb = elevate ? "runas" : string.Empty, // indicates to elevate privileges
|
||||
UseShellExecute = true,
|
||||
WindowStyle = hidden ? ProcessWindowStyle.Hidden : ProcessWindowStyle.Normal,
|
||||
WorkingDirectory = setWorkingDir ? Path.GetDirectoryName(fileName) : null
|
||||
});
|
||||
|
||||
if (affinityMask > 0)
|
||||
{
|
||||
SetProcessAffinity(process.Id, affinityMask);
|
||||
}
|
||||
|
||||
if (priorityClass > 0 && priorityClass != NativeConstants.NORMAL_PRIORITY_CLASS)
|
||||
{
|
||||
SetProcessPriority(process.Id, priorityClass);
|
||||
}
|
||||
|
||||
if (wait)
|
||||
{
|
||||
process.WaitForExit();
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
|
||||
public bool StopProcess(int processId)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<bool>(nameof(StopProcess), processId);
|
||||
}
|
||||
|
||||
var process = Process.GetProcessById(processId);
|
||||
|
||||
if (process == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
process.Kill();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetProcessAffinity(int processId, uint affinityMask)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<bool>(nameof(SetProcessAffinity), processId, affinityMask);
|
||||
}
|
||||
|
||||
var hProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_ALL_ACCESS, false, (uint)processId);
|
||||
|
||||
if (hProcess == nint.Zero)
|
||||
{
|
||||
CheckWin32Error($"Unable to set processor affinity on process {processId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return NativeMethods.SetProcessAffinityMask(hProcess, affinityMask);
|
||||
}
|
||||
|
||||
public bool SetProcessPriority(int processId, uint priorityClass)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<bool>(nameof(SetProcessPriority), processId, priorityClass);
|
||||
}
|
||||
|
||||
var hProcess = NativeMethods.OpenProcess(NativeConstants.PROCESS_ALL_ACCESS, false, (uint)processId);
|
||||
|
||||
if (hProcess == nint.Zero)
|
||||
{
|
||||
CheckWin32Error($"Unable to set process priority on process {processId}");
|
||||
return false;
|
||||
}
|
||||
|
||||
return NativeMethods.SetPriorityClass(hProcess, priorityClass);
|
||||
}
|
||||
|
||||
public void InstallService()
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
_elevatedProcessManager.ExecuteElevated(nameof(InstallService));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!_winApiService.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();
|
||||
}
|
||||
|
||||
public void UninstallService()
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
_elevatedProcessManager.ExecuteElevated(nameof(UninstallService));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_winApiService.IsServiceInstalled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
StopService();
|
||||
|
||||
StartProcess("sc.exe", @$"delete ""{SERVICE_NAME}""", wait: true);
|
||||
}
|
||||
|
||||
public void StartService()
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
_elevatedProcessManager.ExecuteElevated(nameof(StartService));
|
||||
return;
|
||||
}
|
||||
|
||||
var controller = new ServiceController(SERVICE_NAME);
|
||||
|
||||
if (controller.Status == ServiceControllerStatus.Stopped)
|
||||
{
|
||||
controller.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public void StopService()
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
_elevatedProcessManager.ExecuteElevated(nameof(StopService));
|
||||
return;
|
||||
}
|
||||
|
||||
var controller = new ServiceController(SERVICE_NAME);
|
||||
|
||||
if (controller.Status == ServiceControllerStatus.Running)
|
||||
{
|
||||
controller.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public bool InstallChromeFix(bool install, string applicationDataFolder)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
return _rpcService.Call<bool>(nameof(InstallChromeFix), new object[] { install, applicationDataFolder });
|
||||
}
|
||||
|
||||
var argument = "--disable-lcd-text";
|
||||
|
||||
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command", true);
|
||||
if (key != null)
|
||||
{
|
||||
var value = key.GetValue(null).ToString();
|
||||
value = value.Replace("chrome.exe\" " + argument + " --", "chrome.exe\" --");
|
||||
if (install)
|
||||
{
|
||||
value = value.Replace("chrome.exe\" --", "chrome.exe\" " + argument + " --");
|
||||
}
|
||||
key.SetValue(null, value);
|
||||
}
|
||||
|
||||
var roamingFolder = applicationDataFolder ?? 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;
|
||||
}
|
||||
|
||||
public void RegisterTask(string taskName, bool enabled, TaskRunLevel runLevel = TaskRunLevel.LUA)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
_elevatedProcessManager.ExecuteElevated(nameof(RegisterTask), new object[] { taskName, enabled, runLevel });
|
||||
return;
|
||||
}
|
||||
|
||||
var file = Process.GetCurrentProcess().MainModule.FileName;
|
||||
var directory = Path.GetDirectoryName(file);
|
||||
|
||||
try
|
||||
{
|
||||
using (TaskService ts = new TaskService())
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
var td = ts.NewTask();
|
||||
|
||||
td.RegistrationInfo.Description = "Start ColorControl";
|
||||
td.Principal.RunLevel = runLevel;
|
||||
|
||||
td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name });
|
||||
|
||||
td.Actions.Add(new ExecAction(file, StartUpParams.RunningFromScheduledTaskParam, directory));
|
||||
|
||||
ts.RootFolder.RegisterTaskDefinition(taskName, td);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts.RootFolder.DeleteTask(taskName, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error($"Could not create/delete task: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool UpdateShortcut(string path, string arguments, bool removeArguments = false)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
{
|
||||
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
|
||||
|
||||
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(path);
|
||||
|
||||
shortcut.Arguments = shortcut.Arguments.Replace(arguments, "");
|
||||
if (!removeArguments)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(shortcut.Arguments))
|
||||
{
|
||||
shortcut.Arguments = shortcut.Arguments + " ";
|
||||
}
|
||||
shortcut.Arguments = shortcut.Arguments + arguments;
|
||||
}
|
||||
|
||||
// save it / create
|
||||
shortcut.Save();
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool ProcessResult(uint result, [CallerMemberName] string callerName = "")
|
||||
{
|
||||
if (result != NativeConstants.ERROR_SUCCESS)
|
||||
{
|
||||
// Logging
|
||||
Logger.Error("Error executing {CallerName}: error code {Result}", callerName, result);
|
||||
}
|
||||
|
||||
return result == NativeConstants.ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
private static void CheckWin32Error(string message)
|
||||
{
|
||||
var errorMessage = new Win32Exception(Marshal.GetLastWin32Error()).Message;
|
||||
|
||||
throw new Exception($"{message}: {errorMessage}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.Win32.TaskScheduler;
|
||||
using System.Security.Principal;
|
||||
using System.ServiceProcess;
|
||||
|
||||
namespace ColorControl.Shared.Services;
|
||||
|
||||
public class WinApiService
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
public static string SERVICE_NAME = "Color Control Service";
|
||||
|
||||
private static bool? _IsAdministrator;
|
||||
|
||||
public WinApiService()
|
||||
{
|
||||
}
|
||||
|
||||
public static bool IsAdministratorStatic()
|
||||
{
|
||||
if (_IsAdministrator.HasValue)
|
||||
{
|
||||
return _IsAdministrator.Value;
|
||||
}
|
||||
|
||||
var identity = WindowsIdentity.GetCurrent();
|
||||
var principal = new WindowsPrincipal(identity);
|
||||
_IsAdministrator = principal.IsInRole(WindowsBuiltInRole.Administrator);
|
||||
|
||||
return _IsAdministrator.Value;
|
||||
}
|
||||
|
||||
public bool IsAdministrator()
|
||||
{
|
||||
return IsAdministratorStatic();
|
||||
}
|
||||
|
||||
public bool IsServiceInstalled()
|
||||
{
|
||||
return GetServiceStatus() != 0;
|
||||
}
|
||||
|
||||
public bool IsServiceRunning()
|
||||
{
|
||||
return GetServiceStatus() == ServiceControllerStatus.Running;
|
||||
}
|
||||
|
||||
public bool IsChromeInstalled()
|
||||
{
|
||||
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command");
|
||||
return key != null;
|
||||
}
|
||||
|
||||
public bool IsChromeFixInstalled()
|
||||
{
|
||||
var key = Registry.ClassesRoot.OpenSubKey(@"ChromeHTML\shell\open\command");
|
||||
return key != null && key.GetValue(null).ToString().Contains("--disable-lcd-text");
|
||||
}
|
||||
|
||||
public bool TaskExists(string taskName)
|
||||
{
|
||||
using (TaskService ts = new TaskService())
|
||||
{
|
||||
var task = ts.RootFolder.Tasks.FirstOrDefault(x => x.Name.Equals(taskName));
|
||||
|
||||
return task != null;
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceControllerStatus GetServiceStatus()
|
||||
{
|
||||
var controller = new ServiceController(SERVICE_NAME);
|
||||
|
||||
try
|
||||
{
|
||||
return controller.Status;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using ColorControl.Shared.Contracts;
|
||||
using NWin32;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace ColorControl.Shared.Services;
|
||||
|
||||
public class WinElevatedProcessManager
|
||||
{
|
||||
private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
|
||||
private bool UseDedicatedElevatedProcess = true;
|
||||
|
||||
public WinElevatedProcessManager()
|
||||
{
|
||||
}
|
||||
|
||||
public void ExecuteElevated(string method, params object[] arguments)
|
||||
{
|
||||
ExecuteElevated<object>(method, arguments);
|
||||
}
|
||||
|
||||
public T ExecuteElevated<T>(string method, params object[] arguments)
|
||||
{
|
||||
CheckElevatedProcess();
|
||||
|
||||
var rpcMessage = new SvcRpcMessage
|
||||
{
|
||||
ServiceName = nameof(WinApiAdminService),
|
||||
MethodName = method,
|
||||
Arguments = arguments
|
||||
};
|
||||
|
||||
return PipeUtils.SendRpcMessage<T>(rpcMessage, pipeName: PipeUtils.ElevatedPipe);
|
||||
}
|
||||
|
||||
public T ExecuteElevated<T>(SvcRpcMessage message)
|
||||
{
|
||||
CheckElevatedProcess();
|
||||
|
||||
return PipeUtils.SendRpcMessage<T>(message, pipeName: PipeUtils.ElevatedPipe);
|
||||
}
|
||||
|
||||
private int ExecuteDirect(string args, bool wait = true)
|
||||
{
|
||||
var fileName = Process.GetCurrentProcess().MainModule.FileName;
|
||||
|
||||
var info = new ProcessStartInfo(fileName, args)
|
||||
{
|
||||
Verb = "runas", // indicates to elevate privileges
|
||||
UseShellExecute = true,
|
||||
};
|
||||
|
||||
var process = new Process
|
||||
{
|
||||
EnableRaisingEvents = true, // enable WaitForExit()
|
||||
StartInfo = info
|
||||
};
|
||||
try
|
||||
{
|
||||
process.Start();
|
||||
|
||||
if (wait)
|
||||
{
|
||||
process.WaitForExit(); // sleep calling process thread until evoked process exit
|
||||
}
|
||||
|
||||
return process.Id;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Error("ExecuteElevated: " + e.Message);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
private static nint ElevatedProcessWindowHandle = nint.Zero;
|
||||
|
||||
public void CheckElevatedProcess()
|
||||
{
|
||||
ElevatedProcessWindowHandle = NativeMethods.FindWindowW(null, "ElevatedForm");
|
||||
|
||||
if (ElevatedProcessWindowHandle != nint.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ExecuteDirect(StartUpParams.StartElevatedParam, false);
|
||||
|
||||
var delay = 1000;
|
||||
|
||||
while (delay >= 0)
|
||||
{
|
||||
Thread.Sleep(100);
|
||||
|
||||
ElevatedProcessWindowHandle = NativeMethods.FindWindowW(null, "ElevatedForm");
|
||||
|
||||
if (ElevatedProcessWindowHandle != nint.Zero)
|
||||
{
|
||||
Thread.Sleep(500);
|
||||
break;
|
||||
}
|
||||
|
||||
delay -= 100;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
using ColorControl.Shared.Common;
|
||||
using NLog;
|
||||
using System.Net;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Net.Sockets;
|
||||
using Vanara.PInvoke;
|
||||
using static Vanara.PInvoke.IpHlpApi;
|
||||
|
||||
namespace ColorControl.Shared.Services;
|
||||
|
||||
public class WolService
|
||||
{
|
||||
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;
|
||||
|
||||
private readonly WinApiService _winApiService;
|
||||
private readonly RpcClientService _rpcService;
|
||||
|
||||
public WolService(WinApiService winApiService, RpcClientService rpcService)
|
||||
{
|
||||
_winApiService = winApiService;
|
||||
_rpcService = rpcService;
|
||||
_rpcService.Name = nameof(WolService);
|
||||
}
|
||||
|
||||
public bool SendWol(string macAddress, string ipAddress = null)
|
||||
{
|
||||
if (!_winApiService.IsAdministrator())
|
||||
{
|
||||
if (_rpcService.Call<bool>("SendWol", macAddress, ipAddress))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// If RPC faield, execute local WOL anyway
|
||||
}
|
||||
|
||||
return WakeFunctionToAllNics(macAddress, ipAddress);
|
||||
}
|
||||
|
||||
private bool WakeFunctionToAllNics(string macAddress, string ipAddressString)
|
||||
{
|
||||
var result = false;
|
||||
Logger.Debug($"Sending WOL packet to MAC-address {macAddress}");
|
||||
|
||||
try
|
||||
{
|
||||
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") || ni.Name.Contains("vEthernet") || ni.Description.Contains("Virtual")*/)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Logger.Debug($"Found network: {ni.Name} ({ni.Description}), type: {ni.NetworkInterfaceType}");
|
||||
try
|
||||
{
|
||||
if (ni.SupportsMulticast && ni.GetIPProperties().GetIPv4Properties() == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
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 && _winApiService.IsAdministrator())
|
||||
{
|
||||
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)
|
||||
{
|
||||
Logger.Error($"WakeFunctionToAllNics: while sending to specific network: {ni.Name} ({ni.Description}): {ex.ToLogString()}");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error($"WakeFunctionToAllNics: {ex.ToLogString()}");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <exception cref="ArgumentNullException"><paramref name="macAddress"/> is null.</exception>
|
||||
/// <exception cref="ArgumentException">The length of the <see cref="T:System.Byte" /> array <paramref name="macAddress"/> is not 6.</exception>
|
||||
/// <exception cref="ArgumentException">The length of the <see cref="T:System.Byte" /> array <paramref name="password"/> is not 0 or 6.</exception>
|
||||
private static byte[] GetWolPacket(byte[] macAddress, byte[] password = null)
|
||||
{
|
||||
if (macAddress == null)
|
||||
throw new ArgumentNullException(nameof(macAddress));
|
||||
if (macAddress.Length != 6)
|
||||
throw new ArgumentException(ArgumentExceptionInvalidMacAddressLength);
|
||||
|
||||
password = password ?? new byte[0];
|
||||
if (password.Length != 0 && password.Length != 6)
|
||||
throw new ArgumentException(ArgumentExceptionInvalidPasswordLength);
|
||||
|
||||
var packet = new byte[17 * 6 + password.Length];
|
||||
|
||||
int offset, i;
|
||||
for (offset = 0; offset < 6; ++offset)
|
||||
packet[offset] = 0xFF;
|
||||
|
||||
for (offset = 6; offset < 17 * 6; offset += 6)
|
||||
for (i = 0; i < 6; ++i)
|
||||
packet[i + offset] = macAddress[i];
|
||||
|
||||
if (password.Length > 0)
|
||||
{
|
||||
for (offset = 16 * 6 + 6; offset < 17 * 6 + password.Length; offset += 6)
|
||||
for (i = 0; i < 6; ++i)
|
||||
packet[i + offset] = password[i];
|
||||
}
|
||||
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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace novideo_srgb
|
||||
UpdateMonitors();
|
||||
}
|
||||
|
||||
private void UpdateMonitors()
|
||||
public void UpdateMonitors(bool? forceClamp = null)
|
||||
{
|
||||
Monitors.Clear();
|
||||
List<XElement> config = null;
|
||||
@@ -66,12 +66,13 @@ namespace novideo_srgb
|
||||
|
||||
foreach (var monitor in Monitors)
|
||||
{
|
||||
monitor.ReapplyClamp();
|
||||
monitor.ReapplyClamp(forceClamp);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDisplaySettingsChanged(object sender, EventArgs e)
|
||||
public async void OnDisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
await Task.Delay(1000);
|
||||
UpdateMonitors();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,21 @@ namespace novideo_srgb
|
||||
return _novideoWindow != null;
|
||||
}
|
||||
|
||||
public static void BeforeDisplaySettingsChange()
|
||||
{
|
||||
if (!IsInitialized())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_novideoWindow.UpdateMonitors();
|
||||
}
|
||||
|
||||
private void UpdateMonitors()
|
||||
{
|
||||
_viewModel.UpdateMonitors(false);
|
||||
}
|
||||
|
||||
public static void UpdateContextMenu(ToolStripMenuItem parent)
|
||||
{
|
||||
if (_novideoWindow == null)
|
||||
|
||||
@@ -75,9 +75,16 @@ namespace novideo_srgb
|
||||
|
||||
private void UpdateClamp(bool doClamp)
|
||||
{
|
||||
if (HdrActive)
|
||||
{
|
||||
_clamped = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_clamped)
|
||||
{
|
||||
Novideo.DisableColorSpaceConversion(_output);
|
||||
_clamped = Novideo.IsColorSpaceConversionActive(_output);
|
||||
}
|
||||
|
||||
if (!doClamp) return;
|
||||
@@ -159,11 +166,11 @@ namespace novideo_srgb
|
||||
get => _clamped;
|
||||
}
|
||||
|
||||
public void ReapplyClamp()
|
||||
public void ReapplyClamp(bool? forceClamp = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var clamped = CanClamp && ClampSdr;
|
||||
var clamped = CanClamp && ClampSdr && (!forceClamp.HasValue || forceClamp.Value);
|
||||
UpdateClamp(clamped);
|
||||
_clamped = clamped;
|
||||
OnPropertyChanged(nameof(CanClamp));
|
||||
|
||||
Reference in new issue
Block a user