简体   繁体   中英

C# Windows Service Opening File For User

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM