1

It's my first time creating windows service, and I am trying to open an Executable File for currently Logged In User, while the service is running as Local Service, or Local System, but what I am encountering is that Executable runs as SYSTEM user but doesn't show it to the User by that I mean that the process is Running under SYSTEM user without showing a Window for the Logged In User.

If my windows service is running as Local Service, then it doesn't appear that Executable File is able to RUN. No signs of life in the Task Manager.

I have tried looking up my problem and tried these solutions:

  1. Process.Start("FileName");
  2. File.Open("FileName", FileMode.Open); Didn't do anything! (No signs of life in task manager)
  3. ProcessStartInfo("FileName") with Verb = "run as"; Didn't change anything (Running as SYSTEM)
  4. Tried shell command from Command Prompt: Process.Start("run as (Forgot the whole command line I typed)"); Didn't do anything! (No signs of life in task manager)
  5. ProcessStartInfo("FileName") with Username = "User" without Password; Didn't do anything! (No signs of life in task manager)

I do think that solution 4 and 5 didn't work because Password is required, but according to Microsoft Post about Local System it says that SYSTEM doesn't need a Password to access a User (Impersonation), but I dont understand what Impersonation really is, it seems to do something with Win API Natives.

What I think is that the Executable File Window is actually shown to the SYSTEM when Executable is running. Not to the currently logged in User.

Now:

  1. Is there a Solution to my problem without WinAPI Natives?
  2. If Natives are necessary, could you also try to explain it to me? When posting the code? I only understand Handles of WinAPI that's all I really do understand.
  3. Could this be possible on Local System running service? As my service is focused to do System Management? Instead of Local Service.
  4. Is it possible to do all of this in C# Programming Language?

PS: The project I am working on is a System Management Toolkit for my company. For future projects.
PS2: If you need any more Information tell me and I will check this post Frequently.
PS3: Sorry for my English, if you see any grammar mistakes.

SamaNoov
  • 42
  • 10
  • **PS4**: My Operating System is Windows 10 – herobrinebrother zoro Sep 24 '16 at 16:45
  • Possible duplicate of http://stackoverflow.com/questions/38274533/impersonate-user-in-windows-service – Ben Cottrell Sep 24 '16 at 17:01
  • StartInfo and File.Open() do not start processes, maybe a bit of googling would help you there. – Niklas Sep 24 '16 at 17:24
  • I did do a lot of googling but I am unable to find the solution to my problem yet, and I do know that StartInfo suppose to be in Process.Start. If I'll find the solution to my problem I will post it as soon as possible. – herobrinebrother zoro Sep 24 '16 at 17:48
  • Please describe in more detail what you are really trying to achieve. Do you want to start an application? Do you want to open a file with the application mapped to the filetype? It is unclear to me what your goal is. – Mare Infinitus Sep 24 '16 at 19:14
  • Opening would be executing it, like opening up **notepad, regedit, task manager, explorer**. Yes, I want to **start** an application. I think I am getting closer to my **Solution** too, it has something to do with **Task Scheduler API**. Still collecting information. – herobrinebrother zoro Sep 24 '16 at 19:22
  • Alright so I know what I need to do to achieve this without natives or complex coding. Very simple, as **SYSTEM** User I have privileges to access anything, so what we need to do is create a **Task** in **Task Scheduler**, and tell our **Task** to **Start/Open/Execute** any file we want on specific **User**, it can even be **SYSTEM** User if we want to. Then when we have created our **Task** we need to simply run it **Manually** or let a **Trigger** do that for us. Done, when the task is running then our task will see what we want to **Start/Open/Execute** and it will do that for us. – herobrinebrother zoro Sep 25 '16 at 11:20
  • On specified **User** in our **Task**. I am not going to explain much but **Task Scheduler API** is the way to do it, if you want things simple. If you are wondering but what if the **User** has a **Password? Then the **Password** will be completely **Ignored**, because the **Task** was created with high enough privileges to well lets just say **Impersonate** our specified **User**. Again I am not going to explain much, just look it up, but that's the way to do it! I am going to write some code and then post the answer with all explanations that are required. – herobrinebrother zoro Sep 25 '16 at 11:28
  • Quick update: I did everything and it was a complete **success** in just about 30 lines of code without accessing any **internals/natives**. **Very simple**. Answer will be posted shortly! **People that had the same issue will be able to use this solution to solve their problem the simplest way possible!** – herobrinebrother zoro Sep 25 '16 at 14:18

1 Answers1

1

Solution code:

using (TaskService taskService = new TaskService())
            {
                TaskDefinition taskDefinition = taskService.NewTask();
                taskDefinition.RegistrationInfo.Description = "Does something";
                taskDefinition.RegistrationInfo.Author = "SYSTEM";

                taskDefinition.Principal.DisplayName = "Testing Display Task Name C#";
                taskDefinition.Principal.RunLevel = TaskRunLevel.Highest;
                taskDefinition.Principal.GroupId = "Administrators";
                taskDefinition.Principal.UserId = "ACCOUNT";
                taskDefinition.Principal.LogonType = TaskLogonType.InteractiveToken;

                taskDefinition.Settings.AllowDemandStart = true;
                taskDefinition.Settings.AllowHardTerminate = true;
                taskDefinition.Settings.DisallowStartIfOnBatteries = false;
                taskDefinition.Settings.DisallowStartOnRemoteAppSession = true;
                taskDefinition.Settings.Hidden = false;
                taskDefinition.Settings.RestartCount = 0;
                taskDefinition.Settings.RunOnlyIfIdle = false;
                taskDefinition.Settings.RunOnlyIfNetworkAvailable = false;
                taskDefinition.Settings.StartWhenAvailable = true;
                taskDefinition.Settings.StopIfGoingOnBatteries = false;
                taskDefinition.Settings.Volatile = false;
                taskDefinition.Settings.WakeToRun = false;

                taskDefinition.Actions.Add(new ExecAction("notepad.exe"));

                const string taskName = "Testing TASK";
                taskService.RootFolder.RegisterTaskDefinition(taskName, taskDefinition);

                taskService.FindTask("Testing TASK").Run();

            }

The solution is Task Scheduler API, I don't want to explain much but this is very simple.

To do this what you need is to access Task Scheduler API but most of the code is Unmanaged(c++) and we don't want that. We want C# Managed Task Scheduler API, to do this we need to download this Nuget Package: LINK.

This will give us access to Task Scheduler API in C# with very good Managed and Documented code. If you dont know what Task Scheduler API is then look it up its very easy to understand.

Then we write our Task and we Run it, its going to Start/Open/Execute specified Application on specified User with UAC without prompt if required. Done its that simple! NO NATIVES REQUIRED!

Now for more detailed explanation lets take our example solution code from the top of the answer. At RegisterInfo.Author we specify which User is creating this Task, in this case we write SYSTEM because our service is Local System. Then at Principal.GroupID we write which Group our User that we want to execute the file is on. In my case the User lets say is a Administrator that means its going to be in Administrators group. Then finally at Principal.UserId we write instead of ACCOUNT which user in Administrators Group we want to Start/Open/Execute the file on lets say John. Thats it! if you'll run the code its going to open notepad.exe on that User!. I don't want to explain much if someone want's to can improve my answer but this is the way to do it.

PS: Keep in mind that you need to have atleast Administrator Privileges to create a Task. PS2: For very good Documentation about this C# Managed Task Scheduler API check this LINK.

Thats all! I might Improve this answer later on I dont have much time right now.