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