11using System ;
22using System . IO ;
3+ using System . Runtime . InteropServices ;
34using System . Security ;
45using System . Security . Principal ;
56using System . Windows . Forms ;
@@ -10,14 +11,15 @@ namespace OpenHardwareMonitor.UI
1011 public class StartupManager
1112 {
1213
14+ private readonly TaskSchedulerClass _scheduler ;
1315 private bool _startup ;
1416 private const string REGISTRY_RUN = @"Software\Microsoft\Windows\CurrentVersion\Run" ;
1517
1618 private bool IsAdministrator ( )
1719 {
1820 try
1921 {
20- var identity = WindowsIdentity . GetCurrent ( ) ;
22+ WindowsIdentity identity = WindowsIdentity . GetCurrent ( ) ;
2123 WindowsPrincipal principal = new ( identity ) ;
2224 return principal . IsInRole ( WindowsBuiltInRole . Administrator ) ;
2325 }
@@ -31,6 +33,7 @@ public StartupManager()
3133 {
3234 if ( Software . OperatingSystem . IsUnix )
3335 {
36+ _scheduler = null ;
3437 IsAvailable = false ;
3538 return ;
3639 }
@@ -39,58 +42,127 @@ public StartupManager()
3942 {
4043 try
4144 {
42- var _scheduler = new TaskSchedulerClass ( ) ;
43- _scheduler . Connect ( ) ;
44-
45- var folder = _scheduler . GetFolder ( "\\ Open Hardware Monitor" ) ;
46- var task = folder . GetTask ( "Startup" ) ;
47- _startup = task != null &&
48- task . Definition . Triggers . Count > 0 &&
49- task . Definition . Triggers [ 1 ] . Type == TASK_TRIGGER_TYPE2 . TASK_TRIGGER_LOGON &&
50- task . Definition . Actions . Count > 0 &&
51- task . Definition . Actions [ 1 ] . Type == TASK_ACTION_TYPE . TASK_ACTION_EXEC &&
52- task . Definition . Actions [ 1 ] is IExecAction execAction &&
53- execAction . Path == Application . ExecutablePath ;
54-
55- if ( _startup )
56- {
57- //old versions compatibility - convert task to registry
58- DeleteSchedulerTask ( _scheduler ) ;
59- CreateRegistryRun ( ) ;
60- }
45+ _scheduler = new TaskSchedulerClass ( ) ;
46+ _scheduler . Connect ( null , null , null , null ) ;
6147 }
6248 catch
6349 {
64- _startup = false ;
50+ _scheduler = null ;
6551 }
52+
53+ if ( _scheduler != null )
54+ {
55+ try
56+ {
57+ try
58+ {
59+ // check if the taskscheduler is running
60+ IRunningTaskCollection collection = _scheduler . GetRunningTasks ( 0 ) ;
61+ }
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 ;
6699 }
67100
68- try
101+ if ( _scheduler == null )
69102 {
70- using ( var key = Registry . CurrentUser . OpenSubKey ( REGISTRY_RUN ) )
103+ try
71104 {
72- _startup = false ;
73- if ( key != null )
105+ using ( RegistryKey key =
106+ Registry . CurrentUser . OpenSubKey ( REGISTRY_RUN ) )
74107 {
75- var value = ( string ) key . GetValue ( "OpenHardwareMonitor" ) ;
76- if ( value != null )
77- _startup = value == Application . ExecutablePath ;
108+ _startup = false ;
109+ if ( key != null )
110+ {
111+ string value = ( string ) key . GetValue ( "OpenHardwareMonitor" ) ;
112+ if ( value != null )
113+ _startup = value == Application . ExecutablePath ;
114+ }
78115 }
116+ IsAvailable = true ;
79117 }
118+ catch ( SecurityException )
119+ {
120+ IsAvailable = false ;
121+ }
122+ }
123+ else
124+ {
80125 IsAvailable = true ;
81126 }
82- catch ( SecurityException )
127+ }
128+
129+ private void CreateSchedulerTask ( )
130+ {
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
83148 {
84- IsAvailable = false ;
149+ folder = root . GetFolder ( "Open Hardware Monitor" ) ;
85150 }
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 , "" ) ;
86158 }
87159
88- private static void DeleteSchedulerTask ( TaskSchedulerClass scheduler )
160+ private void DeleteSchedulerTask ( )
89161 {
90- var root = scheduler . GetFolder ( "\\ " ) ;
162+ ITaskFolder root = _scheduler . GetFolder ( "\\ " ) ;
91163 try
92164 {
93- var folder = root . GetFolder ( "Open Hardware Monitor" ) ;
165+ ITaskFolder folder = root . GetFolder ( "Open Hardware Monitor" ) ;
94166 folder . DeleteTask ( "Startup" , 0 ) ;
95167 }
96168 catch ( IOException ) { }
@@ -101,16 +173,16 @@ private static void DeleteSchedulerTask(TaskSchedulerClass scheduler)
101173 catch ( IOException ) { }
102174 }
103175
104- private static void CreateRegistryRun ( )
176+ private void CreateRegistryRun ( )
105177 {
106- var key = Registry . CurrentUser . CreateSubKey ( REGISTRY_RUN ) ;
107- key ? . SetValue ( "OpenHardwareMonitor" , Application . ExecutablePath ) ;
178+ RegistryKey key = Registry . CurrentUser . CreateSubKey ( REGISTRY_RUN ) ;
179+ key . SetValue ( "OpenHardwareMonitor" , Application . ExecutablePath ) ;
108180 }
109181
110- private static void DeleteRegistryRun ( )
182+ private void DeleteRegistryRun ( )
111183 {
112- var key = Registry . CurrentUser . CreateSubKey ( REGISTRY_RUN ) ;
113- key ? . DeleteValue ( "OpenHardwareMonitor" ) ;
184+ RegistryKey key = Registry . CurrentUser . CreateSubKey ( REGISTRY_RUN ) ;
185+ key . DeleteValue ( "OpenHardwareMonitor" ) ;
114186 }
115187
116188 public bool IsAvailable { get ; }
@@ -123,23 +195,38 @@ public bool Startup
123195 }
124196 set
125197 {
126- if ( _startup == value )
127- return ;
128-
129- if ( ! IsAvailable )
130- throw new InvalidOperationException ( ) ;
131-
132- try
198+ if ( _startup != value )
133199 {
134- if ( value )
135- CreateRegistryRun ( ) ;
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+ }
136226 else
137- DeleteRegistryRun ( ) ;
138- _startup = value ;
139- }
140- catch ( UnauthorizedAccessException )
141- {
142- throw new InvalidOperationException ( ) ;
227+ {
228+ throw new InvalidOperationException ( ) ;
229+ }
143230 }
144231 }
145232 }
0 commit comments