Server/StartupManager.cs
author Stephane Lenclud
Fri, 19 Aug 2016 17:12:54 +0200
changeset 243 cc2251d065db
parent 92 787dee27fc0a
permissions -rw-r--r--
Optical drive eject action now functional.
     1 /*
     2 
     3   This Source Code Form is subject to the terms of the Mozilla Public
     4   License, v. 2.0. If a copy of the MPL was not distributed with this
     5   file, You can obtain one at http://mozilla.org/MPL/2.0/.
     6 
     7   Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
     8 
     9 */
    10 
    11 using Microsoft.Win32;
    12 using SharpDisplayManager.TaskScheduler;
    13 using System;
    14 using System.IO;
    15 using System.Runtime.InteropServices;
    16 using System.Security;
    17 using System.Security.Principal;
    18 using System.Windows.Forms;
    19 using System.Deployment.Application;
    20 
    21 namespace SharpDisplayManager
    22 {
    23 	public class StartupManager
    24 	{
    25 		private TaskSchedulerClass scheduler;
    26 		private bool startup;
    27 		private bool isAvailable;
    28 
    29 		private const string REGISTRY_RUN =
    30 		  @"Software\Microsoft\Windows\CurrentVersion\Run";
    31 
    32 		private bool IsAdministrator()
    33 		{
    34 			try
    35 			{
    36 				WindowsIdentity identity = WindowsIdentity.GetCurrent();
    37 				WindowsPrincipal principal = new WindowsPrincipal(identity);
    38 				return principal.IsInRole(WindowsBuiltInRole.Administrator);
    39 			}
    40 			catch
    41 			{
    42 				return false;
    43 			}
    44 		}
    45 
    46 		public StartupManager()
    47 		{
    48 			int p = (int)System.Environment.OSVersion.Platform;
    49 			if ((p == 4) || (p == 128))
    50 			{
    51 				scheduler = null;
    52 				isAvailable = false;
    53 				return;
    54 			}
    55 
    56 			if (IsAdministrator())
    57 			{
    58 				try
    59 				{
    60 					scheduler = new TaskSchedulerClass();
    61 					scheduler.Connect(null, null, null, null);
    62 				}
    63 				catch
    64 				{
    65 					scheduler = null;
    66 				}
    67 
    68 				if (scheduler != null)
    69 				{
    70 					try
    71 					{
    72 						// check if the task scheduler is running
    73 						IRunningTaskCollection collection = scheduler.GetRunningTasks(0);
    74 
    75 						ITaskFolder folder = scheduler.GetFolder("\\Sharp Display Manager");
    76 						IRegisteredTask task = folder.GetTask("Startup");
    77 						startup = (task != null) &&
    78 						  (task.Definition.Triggers.Count > 0) &&
    79 						  (task.Definition.Triggers[1].Type ==
    80 							TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON) &&
    81 						  (task.Definition.Actions.Count > 0) &&
    82 						  (task.Definition.Actions[1].Type ==
    83 							TASK_ACTION_TYPE.TASK_ACTION_EXEC) &&
    84 						  (task.Definition.Actions[1] as IExecAction != null) &&
    85 						  ((task.Definition.Actions[1] as IExecAction).Path ==
    86 							Application.ExecutablePath);
    87 					}
    88 					catch (IOException)
    89 					{
    90 						startup = false;
    91 					}
    92 					catch (UnauthorizedAccessException)
    93 					{
    94 						scheduler = null;
    95 					}
    96 					catch (COMException)
    97 					{
    98 						scheduler = null;
    99 					}
   100 				}
   101 			}
   102 			else
   103 			{
   104 				scheduler = null;
   105 			}
   106 
   107 			if (scheduler == null)
   108 			{
   109 				try
   110 				{
   111 					using (RegistryKey key =
   112 					  Registry.CurrentUser.OpenSubKey(REGISTRY_RUN))
   113 					{
   114 						startup = false;
   115 						if (key != null)
   116 						{
   117 							string value = (string)key.GetValue("SharpDisplayManager");
   118 							if (value != null)
   119 								startup = value == LaunchCommand;
   120 						}
   121 					}
   122 					isAvailable = true;
   123 				}
   124 				catch (SecurityException)
   125 				{
   126 					isAvailable = false;
   127 				}
   128 			}
   129 			else
   130 			{
   131 				isAvailable = true;
   132 			}
   133 		}
   134 
   135 		private void CreateSchedulerTask()
   136 		{
   137 			ITaskDefinition definition = scheduler.NewTask(0);
   138 			definition.RegistrationInfo.Description =
   139 			  "This task starts the Sharp Display Manager on Windows startup.";
   140 			definition.Principal.RunLevel =
   141 			  TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST;
   142 			definition.Settings.DisallowStartIfOnBatteries = false;
   143 			definition.Settings.StopIfGoingOnBatteries = false;
   144 			definition.Settings.ExecutionTimeLimit = "PT0S";
   145 
   146 			ILogonTrigger trigger = (ILogonTrigger)definition.Triggers.Create(
   147 			  TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON);
   148 
   149 			IExecAction action = (IExecAction)definition.Actions.Create(
   150 			  TASK_ACTION_TYPE.TASK_ACTION_EXEC);
   151 			action.Path = Application.ExecutablePath;
   152 			action.WorkingDirectory =
   153 			  Path.GetDirectoryName(Application.ExecutablePath);
   154 
   155 			ITaskFolder root = scheduler.GetFolder("\\");
   156 			ITaskFolder folder;
   157 			try
   158 			{
   159 				folder = root.GetFolder("Sharp Display Manager");
   160 			}
   161 			catch (IOException)
   162 			{
   163 				folder = root.CreateFolder("Sharp Display Manager", "");
   164 			}
   165 			folder.RegisterTaskDefinition("Startup", definition,
   166 			  (int)TASK_CREATION.TASK_CREATE_OR_UPDATE, null, null,
   167 			  TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
   168 		}
   169 
   170 		private void DeleteSchedulerTask()
   171 		{
   172 			ITaskFolder root = scheduler.GetFolder("\\");
   173 			try
   174 			{
   175 				ITaskFolder folder = root.GetFolder("Sharp Display Manager");
   176 				folder.DeleteTask("Startup", 0);
   177 			}
   178 			catch (IOException) { }
   179 			try
   180 			{
   181 				root.DeleteFolder("Sharp Display Manager", 0);
   182 			}
   183 			catch (IOException) { }
   184 		}
   185 
   186 		string LaunchCommand
   187 		{
   188 			get
   189 			{	
   190 				//Executable path won't launch ClickOnce Application with deployment enabled.
   191 				//return Application.ExecutablePath;
   192 				//Instead we need to launch the application using the .appref-ms shortcut.
   193 				//That shortcut is located at <programs>\<publisher>\<suite>\<product>.appref-ms
   194 				return string.Concat(Environment.GetFolderPath(Environment.SpecialFolder.Programs), "\\", "Slions", "\\", "Sharp Display Manager" , "\\" ,"Sharp Display Manager", ".appref-ms");
   195 			}
   196 		}
   197 
   198 		private void CreateRegistryRun()
   199 		{
   200 			RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);
   201 			//Rather than the executable name we pass in the ClickOnce shortcut to make sure we launch with deployment support
   202 			key.SetValue("SharpDisplayManager", LaunchCommand);
   203 		}
   204 
   205 		private void DeleteRegistryRun()
   206 		{
   207 			RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);
   208 			key.DeleteValue("SharpDisplayManager");
   209 		}
   210 
   211 		public bool IsAvailable
   212 		{
   213 			get { return isAvailable; }
   214 		}
   215 
   216 		public bool Startup
   217 		{
   218 			get
   219 			{
   220 				return startup;
   221 			}
   222 			set
   223 			{
   224 				if (startup != value)
   225 				{
   226 					if (isAvailable)
   227 					{
   228 						if (scheduler != null)
   229 						{
   230 							if (value)
   231 								CreateSchedulerTask();
   232 							else
   233 								DeleteSchedulerTask();
   234 							startup = value;
   235 						}
   236 						else
   237 						{
   238 							try
   239 							{
   240 								if (value)
   241 									CreateRegistryRun();
   242 								else
   243 									DeleteRegistryRun();
   244 								startup = value;
   245 							}
   246 							catch (UnauthorizedAccessException)
   247 							{
   248 								throw new InvalidOperationException();
   249 							}
   250 						}
   251 					}
   252 					else
   253 					{
   254 						throw new InvalidOperationException();
   255 					}
   256 				}
   257 			}
   258 		}
   259 	}
   260 }