GUI/StartupManager.cs
author moel.mich
Sun, 24 Jul 2011 22:12:01 +0000
changeset 314 d19c6b4d625e
parent 142 48e487749709
child 344 3145aadca3d2
permissions -rw-r--r--
Replaced the more expensive calls to DateTime.Now with DateTime.UtcNow.
moel@82
     1
/*
moel@82
     2
  
moel@82
     3
  Version: MPL 1.1/GPL 2.0/LGPL 2.1
moel@82
     4
moel@82
     5
  The contents of this file are subject to the Mozilla Public License Version
moel@82
     6
  1.1 (the "License"); you may not use this file except in compliance with
moel@82
     7
  the License. You may obtain a copy of the License at
moel@82
     8
 
moel@82
     9
  http://www.mozilla.org/MPL/
moel@82
    10
moel@82
    11
  Software distributed under the License is distributed on an "AS IS" basis,
moel@82
    12
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
moel@82
    13
  for the specific language governing rights and limitations under the License.
moel@82
    14
moel@82
    15
  The Original Code is the Open Hardware Monitor code.
moel@82
    16
moel@82
    17
  The Initial Developer of the Original Code is 
moel@82
    18
  Michael Möller <m.moeller@gmx.ch>.
moel@82
    19
  Portions created by the Initial Developer are Copyright (C) 2009-2010
moel@82
    20
  the Initial Developer. All Rights Reserved.
moel@82
    21
moel@82
    22
  Contributor(s):
moel@82
    23
moel@82
    24
  Alternatively, the contents of this file may be used under the terms of
moel@82
    25
  either the GNU General Public License Version 2 or later (the "GPL"), or
moel@82
    26
  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
moel@82
    27
  in which case the provisions of the GPL or the LGPL are applicable instead
moel@82
    28
  of those above. If you wish to allow use of your version of this file only
moel@82
    29
  under the terms of either the GPL or the LGPL, and not to allow others to
moel@82
    30
  use your version of this file under the terms of the MPL, indicate your
moel@82
    31
  decision by deleting the provisions above and replace them with the notice
moel@82
    32
  and other provisions required by the GPL or the LGPL. If you do not delete
moel@82
    33
  the provisions above, a recipient may use your version of this file under
moel@82
    34
  the terms of any one of the MPL, the GPL or the LGPL.
moel@82
    35
 
moel@82
    36
*/
moel@82
    37
moel@82
    38
using System;
moel@82
    39
using System.Collections.Generic;
moel@82
    40
using System.IO;
moel@139
    41
using System.Runtime.InteropServices;
moel@142
    42
using System.Security;
moel@123
    43
using System.Security.Principal;
moel@82
    44
using System.Windows.Forms;
moel@82
    45
using Microsoft.Win32;
moel@82
    46
using OpenHardwareMonitor.TaskScheduler;
moel@82
    47
moel@82
    48
namespace OpenHardwareMonitor.GUI {
moel@82
    49
  public class StartupManager {
moel@82
    50
moel@82
    51
    private TaskSchedulerClass scheduler;
moel@82
    52
    private bool startup;
moel@142
    53
    private bool isAvailable;
moel@82
    54
moel@82
    55
    private const string REGISTRY_RUN =
moel@82
    56
      @"Software\Microsoft\Windows\CurrentVersion\Run";
moel@82
    57
moel@123
    58
    private bool IsAdministrator() {
moel@123
    59
      try {
moel@123
    60
        WindowsIdentity identity = WindowsIdentity.GetCurrent();
moel@123
    61
        WindowsPrincipal principal = new WindowsPrincipal(identity);
moel@123
    62
        return principal.IsInRole(WindowsBuiltInRole.Administrator);
moel@123
    63
      } catch {
moel@123
    64
        return false;
moel@123
    65
      }
moel@123
    66
    }
moel@123
    67
moel@82
    68
    public StartupManager() {
moel@142
    69
      int p = (int)System.Environment.OSVersion.Platform;
moel@142
    70
      if ((p == 4) || (p == 128)) {
moel@142
    71
        scheduler = null;        
moel@142
    72
        isAvailable = false;
moel@142
    73
        return;
moel@142
    74
      }
moel@142
    75
moel@123
    76
      if (IsAdministrator()) {
moel@123
    77
        try {
moel@123
    78
          scheduler = new TaskSchedulerClass();
moel@123
    79
          scheduler.Connect(null, null, null, null);
moel@123
    80
        } catch {
moel@123
    81
          scheduler = null;
moel@123
    82
        }
moel@123
    83
moel@123
    84
        if (scheduler != null) {
moel@123
    85
          try {
moel@139
    86
            // check if the taskscheduler is running
moel@139
    87
            IRunningTaskCollection collection = scheduler.GetRunningTasks(0);            
moel@139
    88
moel@123
    89
            ITaskFolder folder = scheduler.GetFolder("\\Open Hardware Monitor");
moel@123
    90
            IRegisteredTask task = folder.GetTask("Startup");
moel@129
    91
            startup = (task != null) && 
moel@129
    92
              (task.Definition.Triggers.Count > 0) &&
moel@129
    93
              (task.Definition.Triggers[1].Type == 
moel@129
    94
                TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON) &&
moel@129
    95
              (task.Definition.Actions.Count > 0) &&
moel@129
    96
              (task.Definition.Actions[1].Type ==
moel@129
    97
                TASK_ACTION_TYPE.TASK_ACTION_EXEC) &&
moel@129
    98
              (task.Definition.Actions[1] as IExecAction != null) &&
moel@129
    99
              ((task.Definition.Actions[1] as IExecAction).Path ==
moel@129
   100
                Application.ExecutablePath);
moel@129
   101
              
moel@123
   102
          } catch (IOException) {
moel@123
   103
            startup = false;
moel@123
   104
          } catch (UnauthorizedAccessException) {
moel@123
   105
            scheduler = null;
moel@139
   106
          } catch (COMException) {
moel@139
   107
            scheduler = null;
moel@123
   108
          }
moel@123
   109
        } 
moel@123
   110
      } else {
moel@82
   111
        scheduler = null;
moel@82
   112
      }
moel@142
   113
moel@120
   114
      if (scheduler == null) {
moel@142
   115
        try {
moel@142
   116
          using (RegistryKey key =
moel@142
   117
            Registry.CurrentUser.OpenSubKey(REGISTRY_RUN)) {
moel@142
   118
            startup = false;
moel@142
   119
            if (key != null) {
moel@142
   120
              string value = (string)key.GetValue("OpenHardwareMonitor");
moel@142
   121
              if (value != null)
moel@142
   122
                startup = value == Application.ExecutablePath;
moel@142
   123
            }            
moel@142
   124
          }
moel@142
   125
          isAvailable = true;
moel@142
   126
        } catch (SecurityException) {
moel@142
   127
          isAvailable = false;
moel@82
   128
        }
moel@142
   129
      } else {
moel@142
   130
        isAvailable = true;
moel@82
   131
      }
moel@82
   132
    }
moel@82
   133
moel@82
   134
    private void CreateSchedulerTask() {
moel@82
   135
      ITaskDefinition definition = scheduler.NewTask(0);
moel@82
   136
      definition.RegistrationInfo.Description =
moel@82
   137
        "This task starts the Open Hardware Monitor on Windows startup.";
moel@82
   138
      definition.Principal.RunLevel =
moel@82
   139
        TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST;
moel@82
   140
      definition.Settings.DisallowStartIfOnBatteries = false;
moel@82
   141
      definition.Settings.StopIfGoingOnBatteries = false;
moel@82
   142
      definition.Settings.ExecutionTimeLimit = "PT0S";
moel@82
   143
moel@82
   144
      ILogonTrigger trigger = (ILogonTrigger)definition.Triggers.Create(
moel@82
   145
        TASK_TRIGGER_TYPE2.TASK_TRIGGER_LOGON);
moel@82
   146
moel@82
   147
      IExecAction action = (IExecAction)definition.Actions.Create(
moel@82
   148
        TASK_ACTION_TYPE.TASK_ACTION_EXEC);
moel@82
   149
      action.Path = Application.ExecutablePath;
moel@82
   150
      action.WorkingDirectory =
moel@82
   151
        Path.GetDirectoryName(Application.ExecutablePath);
moel@82
   152
moel@82
   153
      ITaskFolder root = scheduler.GetFolder("\\");
moel@82
   154
      ITaskFolder folder;
moel@82
   155
      try {
moel@82
   156
        folder = root.GetFolder("Open Hardware Monitor");
moel@104
   157
      } catch (IOException) {
moel@82
   158
        folder = root.CreateFolder("Open Hardware Monitor", "");
moel@82
   159
      }
moel@82
   160
      folder.RegisterTaskDefinition("Startup", definition,
moel@82
   161
        (int)TASK_CREATION.TASK_CREATE_OR_UPDATE, null, null,
moel@82
   162
        TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, "");
moel@82
   163
    }
moel@82
   164
moel@82
   165
    private void DeleteSchedulerTask() {
moel@82
   166
      ITaskFolder root = scheduler.GetFolder("\\");
moel@82
   167
      try {
moel@82
   168
        ITaskFolder folder = root.GetFolder("Open Hardware Monitor");
moel@82
   169
        folder.DeleteTask("Startup", 0);
moel@104
   170
      } catch (IOException) { }
moel@82
   171
      try {
moel@82
   172
        root.DeleteFolder("Open Hardware Monitor", 0);
moel@104
   173
      } catch (IOException) { }
moel@82
   174
    }
moel@82
   175
moel@82
   176
    private void CreateRegistryRun() {
moel@185
   177
      RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);     
moel@82
   178
      key.SetValue("OpenHardwareMonitor", Application.ExecutablePath);
moel@82
   179
    }
moel@82
   180
moel@82
   181
    private void DeleteRegistryRun() {
moel@82
   182
      RegistryKey key = Registry.CurrentUser.CreateSubKey(REGISTRY_RUN);
moel@82
   183
      key.DeleteValue("OpenHardwareMonitor");
moel@82
   184
    }
moel@82
   185
moel@142
   186
    public bool IsAvailable {
moel@142
   187
      get { return isAvailable; }
moel@142
   188
    }
moel@142
   189
moel@82
   190
    public bool Startup {
moel@82
   191
      get {
moel@82
   192
        return startup;
moel@82
   193
      }
moel@82
   194
      set {
moel@185
   195
        if (startup != value) {          
moel@142
   196
          if (isAvailable) {
moel@142
   197
            if (scheduler != null) {
moel@185
   198
              if (value)
moel@142
   199
                CreateSchedulerTask();
moel@142
   200
              else
moel@142
   201
                DeleteSchedulerTask();
moel@185
   202
              startup = value;
moel@142
   203
            } else {
moel@185
   204
              try {
moel@185
   205
                if (value)
moel@185
   206
                  CreateRegistryRun();
moel@185
   207
                else
moel@185
   208
                  DeleteRegistryRun();
moel@185
   209
                startup = value;
moel@185
   210
              } catch (UnauthorizedAccessException) {
moel@185
   211
                throw new InvalidOperationException();
moel@185
   212
              }
moel@142
   213
            }
moel@185
   214
          } else {
moel@185
   215
            throw new InvalidOperationException();
moel@82
   216
          }
moel@82
   217
        }
moel@82
   218
      }
moel@82
   219
    }
moel@82
   220
  }
moel@82
   221
moel@82
   222
}