11using System ;
2+ using System . IO ;
3+ using System . Linq ;
4+ using System . Security . Principal ;
25using Flow . Launcher . Infrastructure ;
36using Flow . Launcher . Infrastructure . Logger ;
47using Microsoft . Win32 ;
8+ using Microsoft . Win32 . TaskScheduler ;
59
610namespace Flow . Launcher . Helper ;
711
812public class AutoStartup
913{
1014 private const string StartupPath = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Run" ;
15+ private const string LogonTaskName = $ "{ Constant . FlowLauncher } Startup";
16+ private const string LogonTaskDesc = $ "{ Constant . FlowLauncher } Auto Startup";
1117
1218 public static bool IsEnabled
1319 {
1420 get
1521 {
22+ // Check if logon task is enabled
23+ if ( CheckLogonTask ( ) )
24+ {
25+ return true ;
26+ }
27+
28+ // Check if registry is enabled
1629 try
1730 {
1831 using var key = Registry . CurrentUser . OpenSubKey ( StartupPath , true ) ;
@@ -28,12 +41,74 @@ public static bool IsEnabled
2841 }
2942 }
3043
31- public static void Disable ( )
44+ private static bool CheckLogonTask ( )
45+ {
46+ using var taskService = new TaskService ( ) ;
47+ var task = taskService . RootFolder . AllTasks . FirstOrDefault ( t => t . Name == LogonTaskName ) ;
48+ if ( task != null )
49+ {
50+ try
51+ {
52+ // Check if the action is the same as the current executable path
53+ var action = task . Definition . Actions . FirstOrDefault ( ) ! . ToString ( ) . Trim ( ) ;
54+ if ( ! Constant . ExecutablePath . Equals ( action , StringComparison . OrdinalIgnoreCase ) && ! File . Exists ( action ) )
55+ {
56+ UnscheduleLogonTask ( ) ;
57+ ScheduleLogonTask ( ) ;
58+ }
59+
60+ return true ;
61+ }
62+ catch ( Exception e )
63+ {
64+ Log . Error ( "AutoStartup" , $ "Failed to check logon task: { e } ") ;
65+ }
66+ }
67+
68+ return false ;
69+ }
70+
71+ public static void DisableViaLogonTaskAndRegistry ( )
72+ {
73+ Disable ( true ) ;
74+ Disable ( false ) ;
75+ }
76+
77+ public static void EnableViaLogonTask ( )
78+ {
79+ Enable ( true ) ;
80+ }
81+
82+ public static void EnableViaRegistry ( )
83+ {
84+ Enable ( false ) ;
85+ }
86+
87+ public static void ChangeToViaLogonTask ( )
88+ {
89+ Disable ( false ) ;
90+ Enable ( true ) ;
91+ }
92+
93+ public static void ChangeToViaRegistry ( )
94+ {
95+ Disable ( true ) ;
96+ Enable ( false ) ;
97+ }
98+
99+ private static void Disable ( bool logonTask )
32100 {
33101 try
34102 {
35- using var key = Registry . CurrentUser . OpenSubKey ( StartupPath , true ) ;
36- key ? . DeleteValue ( Constant . FlowLauncher , false ) ;
103+ if ( logonTask )
104+ {
105+ UnscheduleLogonTask ( ) ;
106+ }
107+ else
108+ {
109+ using var key = Registry . CurrentUser . OpenSubKey ( StartupPath , true ) ;
110+ key ? . DeleteValue ( Constant . FlowLauncher , false ) ;
111+ }
37112 }
38113 catch ( Exception e )
39114 {
@@ -42,17 +117,74 @@ public static void Disable()
42117 }
43118 }
44119
45- internal static void Enable ( )
120+ private static void Enable ( bool logonTask )
46121 {
47122 try
48123 {
49- using var key = Registry . CurrentUser . OpenSubKey ( StartupPath , true ) ;
50- key ? . SetValue ( Constant . FlowLauncher , $ "\" { Constant . ExecutablePath } \" ") ;
124+ if ( logonTask )
125+ {
126+ ScheduleLogonTask ( ) ;
127+ }
128+ else
129+ {
130+ using var key = Registry . CurrentUser . OpenSubKey ( StartupPath , true ) ;
131+ key ? . SetValue ( Constant . FlowLauncher , $ "\" { Constant . ExecutablePath } \" ") ;
132+ }
51133 }
52134 catch ( Exception e )
53135 {
54136 Log . Error ( "AutoStartup" , $ "Failed to enable auto-startup: { e } ") ;
55137 throw ;
56138 }
57139 }
140+
141+ private static bool ScheduleLogonTask ( )
142+ {
143+ using var td = TaskService . Instance . NewTask ( ) ;
144+ td . RegistrationInfo . Description = LogonTaskDesc ;
145+ td . Triggers . Add ( new LogonTrigger { UserId = WindowsIdentity . GetCurrent ( ) . Name , Delay = TimeSpan . FromSeconds ( 2 ) } ) ;
146+ td . Actions . Add ( Constant . ExecutablePath ) ;
147+
148+ if ( IsCurrentUserIsAdmin ( ) )
149+ {
150+ td . Principal . RunLevel = TaskRunLevel . Highest ;
151+ }
152+
153+ td . Settings . StopIfGoingOnBatteries = false ;
154+ td . Settings . DisallowStartIfOnBatteries = false ;
155+ td . Settings . ExecutionTimeLimit = TimeSpan . Zero ;
156+
157+ try
158+ {
159+ TaskService . Instance . RootFolder . RegisterTaskDefinition ( LogonTaskName , td ) ;
160+ return true ;
161+ }
162+ catch ( Exception e )
163+ {
164+ Log . Error ( "AutoStartup" , $ "Failed to schedule logon task: { e } ") ;
165+ return false ;
166+ }
167+ }
168+
169+ private static bool UnscheduleLogonTask ( )
170+ {
171+ using var taskService = new TaskService ( ) ;
172+ try
173+ {
174+ taskService . RootFolder . DeleteTask ( LogonTaskName ) ;
175+ return true ;
176+ }
177+ catch ( Exception e )
178+ {
179+ Log . Error ( "AutoStartup" , $ "Failed to unschedule logon task: { e } ") ;
180+ return false ;
181+ }
182+ }
183+
184+ private static bool IsCurrentUserIsAdmin ( )
185+ {
186+ var identity = WindowsIdentity . GetCurrent ( ) ;
187+ var principal = new WindowsPrincipal ( identity ) ;
188+ return principal . IsInRole ( WindowsBuiltInRole . Administrator ) ;
189+ }
58190}
0 commit comments