GUI/StartupManager.cs
author moel.mich
Sun, 23 Sep 2012 18:37:43 +0000
changeset 380 573f1fff48b2
parent 185 edb59f3745e8
permissions -rw-r--r--
Fixed Issue 387. The new implementation does not try to start a ring 0 driver that already exists, but could not be opened. It tries to delete the driver and install it new. The driver is now stored temporarily in the application folder. The driver is not correctly removed on system shutdown.
moel@82
     1
/*
moel@82
     2
 
moel@344
     3
  This Source Code Form is subject to the terms of the Mozilla Public
moel@344
     4
  License, v. 2.0. If a copy of the MPL was not distributed with this
moel@344
     5
  file, You can obtain one at http://mozilla.org/MPL/2.0/.
moel@82
     6
 
moel@344
     7
  Copyright (C) 2009-2010 Michael Möller <mmoeller@openhardwaremonitor.org>
moel@344
     8
	
moel@82
     9
*/
moel@82
    10
moel@82
    11
using System;
moel@82
    12
using System.Collections.Generic;
moel@82
    13
using System.IO;
moel@139
    14
using System.Runtime.InteropServices;
moel@142
    15
using System.Security;
moel@123
    16
using System.Security.Principal;
moel@82
    17
using System.Windows.Forms;
moel@82
    18
using Microsoft.Win32;
moel@82
    19
using OpenHardwareMonitor.TaskScheduler;
moel@82
    20
moel@82
    21
namespace OpenHardwareMonitor.GUI {
moel@82
    22
  public class StartupManager {
moel@82
    23
moel@82
    24
    private TaskSchedulerClass scheduler;
moel@82
    25
    private bool startup;
moel@142
    26
    private bool isAvailable;
moel@82
    27
moel@82
    28
    private const string REGISTRY_RUN =
moel@82
    29
      @"Software\Microsoft\Windows\CurrentVersion\Run";
moel@82
    30
moel@123
    31
    private bool IsAdministrator() {
moel@123
    32
      try {
moel@123
    33
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
moel@123
    34
        WindowsPrincipal principal = new WindowsPrincipal(identity);
moel@123
    35
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
moel@123
    36
      } catch {
moel@123
    37
        return false;
moel@123
    38
      }
moel@123
    39
    }
moel@123
    40
moel@82
    41
    public StartupManager() {
moel@142
    42
      int p = (int)System.Environment.OSVersion.Platform;
moel@142
    43
      if ((p == 4) || (p == 128)) {
moel@142
    44
        scheduler = null;        
moel@142
    45
        isAvailable = false;
moel@142
    46
        return;
moel@142
    47
      }
moel@142
    48
moel@123
    49
      if (IsAdministrator()) {
moel@123
    50
        try {
moel@123
    51
          scheduler = new TaskSchedulerClass();
moel@123
    52
          scheduler.Connect(null, null, null, null);
moel@123
    53
        } catch {
moel@123
    54
          scheduler = null;
moel@123
    55
        }
moel@123
    56
moel@123
    57
        if (scheduler != null) {
moel@123
    58
          try {
moel@139
    59
            // check if the taskscheduler is running
moel@139
    60
            IRunningTaskCollection collection = scheduler.GetRunningTasks(0);            
moel@139
    61
moel@123
    62
            ITaskFolder folder = scheduler.GetFolder("\\Open Hardware Monitor");
moel@123
    63
            IRegisteredTask task = folder.GetTask("Startup");
moel@129
    64
            startup = (task != null) && 
moel@129
    65
              (task.Definition.Triggers.Count > 0) &&
moel@129
    66
              (task.Definition.Triggers[1].Type == 
moel@129
    67
                TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON) &&
moel@129
    68
              (task.Definition.Actions.Count > 0) &&
moel@129
    69
              (task.Definition.Actions[1].Type ==
moel@129
    70
                TASK_ACTION_TYPE.TASK_ACTION_EXEC) &&
moel@129
    71
              (task.Definition.Actions[1] as IExecAction != null) &&
moel@129
    72
              ((task.Definition.Actions[1] as IExecAction).Path ==
moel@129
    73
                Application.ExecutablePath);
moel@129
    74
              
moel@123
    75
          } catch (IOException) {
moel@123
    76
            startup = false;
moel@123
    77
          } catch (UnauthorizedAccessException) {
moel@123
    78
            scheduler = null;
moel@139
    79
          } catch (COMException) {
moel@139
    80
            scheduler = null;
moel@123
    81
          }
moel@123
    82
        } 
moel@123
    83
      } else {
moel@82
    84
        scheduler = null;
moel@82
    85
      }
moel@142
    86
moel@120
    87
      if (scheduler == null) {
moel@142
    88
        try {
moel@142
    89
          using (RegistryKey key =
moel@142
    90
            Registry.CurrentUser.OpenSubKey(REGISTRY_RUN)) {
moel@142
    91
            startup = false;
moel@142
    92
            if (key != null) {
moel@142
    93
              string value = (string)key.GetValue("OpenHardwareMonitor");
moel@142
    94
              if (value != null)
moel@142
    95
                startup = value == Application.ExecutablePath;
moel@142
    96
            }            
moel@142
    97
          }
moel@142
    98
          isAvailable = true;
moel@142
    99
        } catch (SecurityException) {
moel@142
   100
          isAvailable = false;
moel@82
   101
        }
moel@142
   102
      } else {
moel@142
   103
        isAvailable = true;
moel@82
   104
      }
moel@82
   105
    }
moel@82
   106
moel@82
   107
    private void CreateSchedulerTask() {
moel@82
   108
      ITaskDefinition definition = scheduler.NewTask(0);
moel@82
   109
      definition.RegistrationInfo.Description =
moel@82
   110
        "This task starts the Open Hardware Monitor on Windows startup.";
moel@82
   111
      definition.Principal.RunLevel =
moel@82
   112
        TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST;
moel@82
   113
      definition.Settings.DisallowStartIfOnBatteries = false;
moel@82
   114
      definition.Settings.StopIfGoingOnBatteries = false;
moel@82
   115
      definition.Settings.ExecutionTimeLimit = "PT0S";
moel@82
   116
moel@82
   117
      ILogonTrigger trigger = (ILogonTrigger)definition.Triggers.Create(
moel@82
   118
        TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON);
moel@82
   119
moel@82
   120
      IExecAction action = (IExecAction)definition.Actions.Create(
moel@82
   121
        TASK_ACTION_TYPE.TASK_ACTION_EXEC);
moel@82
   122
      action.Path = Application.ExecutablePath;
moel@82
   123
      action.WorkingDirectory =
moel@82
   124
        Path.GetDirectoryName(Application.ExecutablePath);
moel@82
   125
moel@82
   126
      ITaskFolder root = scheduler.GetFolder("\\");
moel@82
   127
      ITaskFolder folder;
moel@82
   128
      try {
moel@82
   129
        folder = root.GetFolder("Open Hardware Monitor");
moel@104
   130
      } catch (IOException) {
moel@82
   131
        folder = root.CreateFolder("Open Hardware Monitor", "");
moel@82
   132
      }
moel@82
   133
      folder.RegisterTaskDefinition("Startup", definition,
moel@82
   134
        (int)TASK_CREATION.TASK_CREATE_OR_UPDATE, null, null,
moel@82
   135
        TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
moel@82
   136
    }
moel@82
   137
moel@82
   138
    private void DeleteSchedulerTask() {
moel@82
   139
      ITaskFolder root = scheduler.GetFolder("\\");
moel@82
   140
      try {
moel@82
   141
        ITaskFolder folder = root.GetFolder("Open Hardware Monitor");
moel@82
   142
        folder.DeleteTask("Startup", 0);
moel@104
   143
      } catch (IOException) { }
moel@82
   144
      try {
moel@82
   145
        root.DeleteFolder("Open Hardware Monitor", 0);
moel@104
   146
      } catch (IOException) { }
moel@82
   147
    }
moel@82
   148
moel@82
   149
    private void CreateRegistryRun() {
moel@185
   150
      RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);     
moel@82
   151
      key.SetValue("OpenHardwareMonitor", Application.ExecutablePath);
moel@82
   152
    }
moel@82
   153
moel@82
   154
    private void DeleteRegistryRun() {
moel@82
   155
      RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);
moel@82
   156
      key.DeleteValue("OpenHardwareMonitor");
moel@82
   157
    }
moel@82
   158
moel@142
   159
    public bool IsAvailable {
moel@142
   160
      get { return isAvailable; }
moel@142
   161
    }
moel@142
   162
moel@82
   163
    public bool Startup {
moel@82
   164
      get {
moel@82
   165
        return startup;
moel@82
   166
      }
moel@82
   167
      set {
moel@185
   168
        if (startup != value) {          
moel@142
   169
          if (isAvailable) {
moel@142
   170
            if (scheduler != null) {
moel@185
   171
              if (value)
moel@142
   172
                CreateSchedulerTask();
moel@142
   173
              else
moel@142
   174
                DeleteSchedulerTask();
moel@185
   175
              startup = value;
moel@142
   176
            } else {
moel@185
   177
              try {
moel@185
   178
                if (value)
moel@185
   179
                  CreateRegistryRun();
moel@185
   180
                else
moel@185
   181
                  DeleteRegistryRun();
moel@185
   182
                startup = value;
moel@185
   183
              } catch (UnauthorizedAccessException) {
moel@185
   184
                throw new InvalidOperationException();
moel@185
   185
              }
moel@142
   186
            }
moel@185
   187
          } else {
moel@185
   188
            throw new InvalidOperationException();
moel@82
   189
          }
moel@82
   190
        }
moel@82
   191
      }
moel@82
   192
    }
moel@82
   193
  }
moel@82
   194
moel@82
   195
}