diff --git a/UserElevation.sln b/UserElevation.sln new file mode 100644 index 0000000..6b72c82 --- /dev/null +++ b/UserElevation.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31702.278 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserElevation", "UserElevation\UserElevation.csproj", "{5B064686-9C18-4FF0-A747-7718087A4CA8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {5B064686-9C18-4FF0-A747-7718087A4CA8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B064686-9C18-4FF0-A747-7718087A4CA8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B064686-9C18-4FF0-A747-7718087A4CA8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B064686-9C18-4FF0-A747-7718087A4CA8}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {77115DE0-B874-4FB0-B8DE-38863A5ADCE6} + EndGlobalSection +EndGlobal diff --git a/UserElevation/App.config b/UserElevation/App.config new file mode 100644 index 0000000..193aecc --- /dev/null +++ b/UserElevation/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/UserElevation/Program.cs b/UserElevation/Program.cs new file mode 100644 index 0000000..8a82a44 --- /dev/null +++ b/UserElevation/Program.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Security.Principal; +using System.Text; +using System.Threading.Tasks; + +namespace UserElevation +{ + class Program + { + static void Main(string[] args) + { + TaskSchedulerClient taskScheduler = new TaskSchedulerClient(); + + if (taskScheduler.TryGetTask(out var task)) + { + + if (IsAdministrator()) + { + Process.Start("cmd.exe"); + } + else + { + //taskScheduler.CheckAndRepairTask(ref task); + task.Run(0); + } + } + else + { + if (IsAdministrator()) + taskScheduler.CreatTask(); + else + { + Console.WriteLine("You need to execute this app one time in admin"); + + Console.WriteLine("Press any key to exit"); + Console.ReadLine(); + } + } + } + + // https://stackoverflow.com/questions/3600322/check-if-the-current-user-is-administrator + public static bool IsAdministrator() + { + using (WindowsIdentity identity = WindowsIdentity.GetCurrent()) + { + WindowsPrincipal principal = new WindowsPrincipal(identity); + return principal.IsInRole(WindowsBuiltInRole.Administrator); + } + } + } +} diff --git a/UserElevation/Properties/AssemblyInfo.cs b/UserElevation/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..5dba80a --- /dev/null +++ b/UserElevation/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// Les informations générales relatives à un assembly dépendent de +// l'ensemble d'attributs suivant. Changez les valeurs de ces attributs pour modifier les informations +// associées à un assembly. +[assembly: AssemblyTitle("UserElevation")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UserElevation")] +[assembly: AssemblyCopyright("Copyright © 2021")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// L'affectation de la valeur false à ComVisible rend les types invisibles dans cet assembly +// aux composants COM. Si vous devez accéder à un type dans cet assembly à partir de +// COM, affectez la valeur true à l'attribut ComVisible sur ce type. +[assembly: ComVisible(false)] + +// Le GUID suivant est pour l'ID de la typelib si ce projet est exposé à COM +[assembly: Guid("5b064686-9c18-4ff0-a747-7718087a4ca8")] + +// Les informations de version pour un assembly se composent des quatre valeurs suivantes : +// +// Version principale +// Version secondaire +// Numéro de build +// Révision +// +// Vous pouvez spécifier toutes les valeurs ou indiquer les numéros de build et de révision par défaut +// en utilisant '*', comme indiqué ci-dessous : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/UserElevation/TaskSchedulerClient.cs b/UserElevation/TaskSchedulerClient.cs new file mode 100644 index 0000000..b25ab7b --- /dev/null +++ b/UserElevation/TaskSchedulerClient.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using TaskScheduler; + +namespace UserElevation +{ + class TaskSchedulerClient + { + TaskScheduler.TaskScheduler objScheduler; + //To hold Task Definition + ITaskDefinition objTaskDef; + //To hold Trigger Information + IRegistrationTrigger objTrigger; + //To hold Action Information + IExecAction objAction; + const string taskName = "ElevatedTask"; + + public void CreatTask() + { + try + { + objScheduler = new TaskScheduler.TaskScheduler(); + objScheduler.Connect(); + + //Setting Task Definition + SetTaskDefinition(); + //Setting Task Trigger Information + //SetTriggerInfo(); + //Setting Task Action Information + SetActionInfo(); + + //Getting the roort folder + ITaskFolder root = objScheduler.GetFolder("\\"); + //Registering the task, if the task is already exist then it will be updated + IRegisteredTask regTask = root.RegisterTaskDefinition(taskName, objTaskDef, (int)_TASK_CREATION.TASK_CREATE_OR_UPDATE, null, null, _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, ""); + + //To execute the task immediately calling Run() + IRunningTask runtask = regTask.Run(null); + + Console.WriteLine("Task is created successfully"); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + + //Setting Task Definition + private void SetTaskDefinition() + { + try + { + objTaskDef = objScheduler.NewTask(0); + + objTaskDef.Principal.RunLevel = _TASK_RUNLEVEL.TASK_RUNLEVEL_HIGHEST; + + //Registration Info for task + //Name of the task Author + objTaskDef.RegistrationInfo.Author = "A cat"; + //Description of the task + objTaskDef.RegistrationInfo.Description = taskName; + //Registration date of the task + objTaskDef.RegistrationInfo.Date = DateTime.Today.ToString("yyyy-MM-ddTHH:mm:ss"); //Date format + + //Settings for task + //Thread Priority + objTaskDef.Settings.Priority = 7; + //Enabling the task + objTaskDef.Settings.Enabled = true; + //To hide/show the task + objTaskDef.Settings.Hidden = false; + //Execution Time Lmit for task + //objTaskDef.Settings.ExecutionTimeLimit = "PT10M"; //10 minutes + //Specifying no need of network connection + objTaskDef.Settings.RunOnlyIfNetworkAvailable = false; + + + } + catch (Exception ex) + { + throw ex; + } + } + + //Setting Task Trigger Information + private void SetTriggerInfo() + { + try + { + //Trigger information based on time - TASK_TRIGGER_TIME + objTrigger = (IRegistrationTrigger)objTaskDef.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_REGISTRATION); + //Trigger ID + objTrigger.Id = taskName + "Trigger"; + + //Start Time + + //objTrigger.StartBoundary = "2014-01-09T10:10:00"; //yyyy-MM-ddTHH:mm:ss + //End Time + + //objTrigger.EndBoundary = "2016-01-01T07:30:00"; //yyyy-MM-ddTHH:mm:ss + } + catch (Exception ex) + { + throw ex; + } + } + + //Setting Task Action Information + private void SetActionInfo() + { + try + { + //Action information based on exe- TASK_ACTION_EXEC + objAction = (IExecAction)objTaskDef.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC); + //Action ID + objAction.Id = taskName; + //Set the path of the exe file to execute, Here mspaint will be opened + objAction.Path = System.Reflection.Assembly.GetExecutingAssembly().Location; + } + catch (Exception ex) + { + throw ex; + } + } + + public void CheckAndRepairTask(ref IRegisteredTask task) + { + objTaskDef = task.Definition; + var actionsEnum = objTaskDef.Actions.GetEnumerator(); + + while (actionsEnum.MoveNext()) + { + IExecAction action = actionsEnum.Current as IExecAction; + + if (!File.Exists(action.Path)) + { + + objTaskDef.Actions.Remove(actionsEnum.Current); + SetActionInfo(); + } + + break; + } + } + + public void DeleteTask() + { + try + { + TaskScheduler.TaskScheduler objScheduler = new TaskScheduler.TaskScheduler(); + objScheduler.Connect(); + + ITaskFolder containingFolder = objScheduler.GetFolder("\\"); + //Deleting the task + containingFolder.DeleteTask(taskName, 0); //Give name of the Task + + Console.WriteLine("Task deleted..."); + } + catch (Exception ex) + { + Console.WriteLine(ex.Message); + } + } + + public bool TryGetTask(out IRegisteredTask task) + { + task = null; + TaskScheduler.TaskScheduler objScheduler = new TaskScheduler.TaskScheduler(); + objScheduler.Connect(); + + ITaskFolder containingFolder = objScheduler.GetFolder("\\"); + var tasks = containingFolder.GetTasks(0); + var tasksEnum = tasks.GetEnumerator(); + IRegisteredTask regTask; + + while (tasksEnum.MoveNext() && task == null) + { + regTask = tasksEnum.Current as IRegisteredTask; + + if (regTask.Name == taskName) + task = regTask; + } + + return task != null; + } + } +} diff --git a/UserElevation/UserElevation.csproj b/UserElevation/UserElevation.csproj new file mode 100644 index 0000000..11ecbc7 --- /dev/null +++ b/UserElevation/UserElevation.csproj @@ -0,0 +1,65 @@ + + + + + Debug + AnyCPU + {5B064686-9C18-4FF0-A747-7718087A4CA8} + Exe + UserElevation + UserElevation + v4.8 + 512 + true + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + {E34CB9F1-C7F7-424C-BE29-027DCC09363A} + 1 + 0 + 0 + tlbimp + False + True + + + + \ No newline at end of file