Skip to content

Commit ace7b94

Browse files
committed
old TaskScheduler restored (old versions support fix)
1 parent fe968d5 commit ace7b94

3 files changed

Lines changed: 827 additions & 134 deletions

File tree

OpenHardwareMonitor/OpenHardwareMonitor.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
<PrivateAssets>all</PrivateAssets>
2929
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
3030
</PackageReference>
31-
<PackageReference Include="TaskScheduler" Version="2.11.0" />
3231
<PackageReference Include="System.Management" Version="9.0.0" />
3332
</ItemGroup>
3433
<ItemGroup>
Lines changed: 187 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,180 +1,234 @@
1-
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
2-
// If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
3-
// Copyright (C) OpenHardwareMonitor and Contributors.
4-
// Partial Copyright (C) Michael Möller <mmoeller@openhardwaremonitor.org> and Contributors.
5-
// All Rights Reserved.
6-
7-
using System;
1+
using System;
82
using System.IO;
9-
using System.Linq;
3+
using System.Runtime.InteropServices;
104
using System.Security;
115
using System.Security.Principal;
126
using System.Windows.Forms;
137
using Microsoft.Win32;
14-
using Microsoft.Win32.TaskScheduler;
15-
using Action = Microsoft.Win32.TaskScheduler.Action;
16-
17-
namespace OpenHardwareMonitor.UI;
188

19-
public class StartupManager
9+
namespace OpenHardwareMonitor.UI
2010
{
21-
private const string RegistryPath = @"Software\Microsoft\Windows\CurrentVersion\Run";
22-
private bool _startup;
23-
24-
public StartupManager()
11+
public class StartupManager
2512
{
26-
if (Environment.OSVersion.Platform >= PlatformID.Unix)
27-
{
28-
IsAvailable = false;
29-
return;
30-
}
3113

32-
if (IsAdministrator() && TaskService.Instance.Connected)
33-
{
34-
IsAvailable = true;
14+
private readonly TaskSchedulerClass _scheduler;
15+
private bool _startup;
16+
private const string REGISTRY_RUN = @"Software\Microsoft\Windows\CurrentVersion\Run";
3517

36-
Task task = GetTask();
37-
if (task != null)
38-
{
39-
foreach (Action action in task.Definition.Actions)
40-
{
41-
if (action.ActionType == TaskActionType.Execute && action is ExecAction execAction)
42-
{
43-
if (execAction.Path.Equals(Application.ExecutablePath, StringComparison.OrdinalIgnoreCase))
44-
_startup = true;
45-
}
46-
}
47-
}
48-
}
49-
else
18+
private bool IsAdministrator()
5019
{
5120
try
5221
{
53-
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(RegistryPath))
54-
{
55-
string value = (string)registryKey?.GetValue(nameof(OpenHardwareMonitor));
56-
57-
if (value != null)
58-
_startup = value == Application.ExecutablePath;
59-
}
60-
61-
IsAvailable = true;
22+
WindowsIdentity identity = WindowsIdentity.GetCurrent();
23+
WindowsPrincipal principal = new(identity);
24+
return principal.IsInRole(WindowsBuiltInRole.Administrator);
6225
}
63-
catch (SecurityException)
26+
catch
6427
{
65-
IsAvailable = false;
28+
return false;
6629
}
6730
}
68-
}
69-
70-
public bool IsAvailable { get; }
7131

72-
public bool Startup
73-
{
74-
get { return _startup; }
75-
set
32+
public StartupManager()
7633
{
77-
if (_startup != value)
34+
if (Software.OperatingSystem.IsUnix)
7835
{
79-
if (IsAvailable)
36+
_scheduler = null;
37+
IsAvailable = false;
38+
return;
39+
}
40+
41+
if (IsAdministrator())
42+
{
43+
try
8044
{
81-
if (TaskService.Instance.Connected)
82-
{
83-
if (value)
84-
CreateTask();
85-
else
86-
DeleteTask();
45+
_scheduler = new TaskSchedulerClass();
46+
_scheduler.Connect(null, null, null, null);
47+
}
48+
catch
49+
{
50+
_scheduler = null;
51+
}
8752

88-
_startup = value;
89-
}
90-
else
53+
if (_scheduler != null)
54+
{
55+
try
9156
{
9257
try
9358
{
94-
if (value)
95-
CreateRegistryKey();
96-
else
97-
DeleteRegistryKey();
98-
99-
_startup = value;
59+
// check if the taskscheduler is running
60+
IRunningTaskCollection collection = _scheduler.GetRunningTasks(0);
10061
}
101-
catch (UnauthorizedAccessException)
62+
catch (ArgumentException) { }
63+
64+
ITaskFolder folder = _scheduler.GetFolder("\\Open Hardware Monitor");
65+
IRegisteredTask task = folder.GetTask("Startup");
66+
_startup = (task != null) &&
67+
(task.Definition.Triggers.Count > 0) &&
68+
(task.Definition.Triggers[1].Type ==
69+
TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON) &&
70+
(task.Definition.Actions.Count > 0) &&
71+
(task.Definition.Actions[1].Type ==
72+
TASK_ACTION_TYPE.TASK_ACTION_EXEC) &&
73+
(task.Definition.Actions[1] as IExecAction != null) &&
74+
((task.Definition.Actions[1] as IExecAction).Path ==
75+
Application.ExecutablePath);
76+
77+
}
78+
catch (IOException)
79+
{
80+
_startup = false;
81+
}
82+
catch (UnauthorizedAccessException)
83+
{
84+
_scheduler = null;
85+
}
86+
catch (COMException)
87+
{
88+
_scheduler = null;
89+
}
90+
catch (NotImplementedException)
91+
{
92+
_scheduler = null;
93+
}
94+
}
95+
}
96+
else
97+
{
98+
_scheduler = null;
99+
}
100+
101+
if (_scheduler == null)
102+
{
103+
try
104+
{
105+
using (RegistryKey key =
106+
Registry.CurrentUser.OpenSubKey(REGISTRY_RUN))
107+
{
108+
_startup = false;
109+
if (key != null)
102110
{
103-
throw new InvalidOperationException();
111+
string value = (string)key.GetValue("OpenHardwareMonitor");
112+
if (value != null)
113+
_startup = value == Application.ExecutablePath;
104114
}
105115
}
116+
IsAvailable = true;
106117
}
107-
else
118+
catch (SecurityException)
108119
{
109-
throw new InvalidOperationException();
120+
IsAvailable = false;
110121
}
111122
}
123+
else
124+
{
125+
IsAvailable = true;
126+
}
112127
}
113-
}
114128

115-
private static bool IsAdministrator()
116-
{
117-
try
129+
private void CreateSchedulerTask()
118130
{
119-
WindowsIdentity identity = WindowsIdentity.GetCurrent();
120-
WindowsPrincipal principal = new WindowsPrincipal(identity);
121-
122-
return principal.IsInRole(WindowsBuiltInRole.Administrator);
131+
ITaskDefinition definition = _scheduler.NewTask(0);
132+
definition.RegistrationInfo.Description =
133+
"This task starts the Open Hardware Monitor on Windows startup.";
134+
definition.Principal.RunLevel =
135+
TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST;
136+
definition.Settings.DisallowStartIfOnBatteries = false;
137+
definition.Settings.StopIfGoingOnBatteries = false;
138+
definition.Settings.ExecutionTimeLimit = "PT0S";
139+
_ = (ILogonTrigger)definition.Triggers.Create(TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON);
140+
IExecAction action = (IExecAction)definition.Actions.Create(TASK_ACTION_TYPE.TASK_ACTION_EXEC);
141+
action.Path = Application.ExecutablePath;
142+
action.WorkingDirectory =
143+
Path.GetDirectoryName(Application.ExecutablePath);
144+
145+
ITaskFolder root = _scheduler.GetFolder("\\");
146+
ITaskFolder folder;
147+
try
148+
{
149+
folder = root.GetFolder("Open Hardware Monitor");
150+
}
151+
catch (IOException)
152+
{
153+
folder = root.CreateFolder("Open Hardware Monitor", "");
154+
}
155+
folder.RegisterTaskDefinition("Startup", definition,
156+
(int)TASK_CREATION.TASK_CREATE_OR_UPDATE, null, null,
157+
TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
123158
}
124-
catch
159+
160+
private void DeleteSchedulerTask()
125161
{
126-
return false;
162+
ITaskFolder root = _scheduler.GetFolder("\\");
163+
try
164+
{
165+
ITaskFolder folder = root.GetFolder("Open Hardware Monitor");
166+
folder.DeleteTask("Startup", 0);
167+
}
168+
catch (IOException) { }
169+
try
170+
{
171+
root.DeleteFolder("Open Hardware Monitor", 0);
172+
}
173+
catch (IOException) { }
127174
}
128-
}
129175

130-
private static Task GetTask()
131-
{
132-
try
176+
private void CreateRegistryRun()
133177
{
134-
return TaskService.Instance.AllTasks.FirstOrDefault(x => x.Name.Equals(nameof(OpenHardwareMonitor), StringComparison.OrdinalIgnoreCase));
178+
RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);
179+
key.SetValue("OpenHardwareMonitor", Application.ExecutablePath);
135180
}
136-
catch
181+
182+
private void DeleteRegistryRun()
137183
{
138-
return null;
184+
RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);
185+
key.DeleteValue("OpenHardwareMonitor");
139186
}
140-
}
141-
142-
private void CreateTask()
143-
{
144-
TaskDefinition taskDefinition = TaskService.Instance.NewTask();
145-
taskDefinition.RegistrationInfo.Description = "Starts OpenHardwareMonitor on Windows startup.";
146-
147-
taskDefinition.Triggers.Add(new LogonTrigger());
148-
149-
taskDefinition.Settings.StartWhenAvailable = true;
150-
taskDefinition.Settings.DisallowStartIfOnBatteries = false;
151-
taskDefinition.Settings.StopIfGoingOnBatteries = false;
152-
taskDefinition.Settings.ExecutionTimeLimit = TimeSpan.Zero;
153-
taskDefinition.Settings.AllowHardTerminate = false;
154-
155-
taskDefinition.Principal.RunLevel = TaskRunLevel.Highest;
156-
taskDefinition.Principal.LogonType = TaskLogonType.InteractiveToken;
157-
158-
taskDefinition.Actions.Add(new ExecAction(Application.ExecutablePath, "", Path.GetDirectoryName(Application.ExecutablePath)));
159-
160-
TaskService.Instance.RootFolder.RegisterTaskDefinition(nameof(OpenHardwareMonitor), taskDefinition);
161-
}
162187

163-
private static void DeleteTask()
164-
{
165-
Task task = GetTask();
166-
task?.Folder.DeleteTask(task.Name, false);
167-
}
188+
public bool IsAvailable { get; }
168189

169-
private static void CreateRegistryKey()
170-
{
171-
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(RegistryPath);
172-
registryKey?.SetValue(nameof(OpenHardwareMonitor), Application.ExecutablePath);
173-
}
174-
175-
private static void DeleteRegistryKey()
176-
{
177-
RegistryKey registryKey = Registry.CurrentUser.CreateSubKey(RegistryPath);
178-
registryKey?.DeleteValue(nameof(OpenHardwareMonitor));
190+
public bool Startup
191+
{
192+
get
193+
{
194+
return _startup;
195+
}
196+
set
197+
{
198+
if (_startup != value)
199+
{
200+
if (IsAvailable)
201+
{
202+
if (_scheduler != null)
203+
{
204+
if (value)
205+
CreateSchedulerTask();
206+
else
207+
DeleteSchedulerTask();
208+
_startup = value;
209+
}
210+
else
211+
{
212+
try
213+
{
214+
if (value)
215+
CreateRegistryRun();
216+
else
217+
DeleteRegistryRun();
218+
_startup = value;
219+
}
220+
catch (UnauthorizedAccessException)
221+
{
222+
throw new InvalidOperationException();
223+
}
224+
}
225+
}
226+
else
227+
{
228+
throw new InvalidOperationException();
229+
}
230+
}
231+
}
232+
}
179233
}
180-
}
234+
}

0 commit comments

Comments
 (0)