I need your help again :)
What I want to do:
I have a c# program which runs with normal user permissions - those can't be raised - and I want to change the system date (not time) from that program.
[EDIT] To be a bit more specific: I do have administrator credentials which could be embedded to the program (yikes, I know), but I want to avoid an UAC prompt.
When I launch cmd from outside Visual Studio and try to change the date, it fails with "missing client permission" (roughly translated from German). When I launch cmd as administrator, confirm the UAC prompt the same command succeeds.
I am writing from home, so I cant provide running code at the moment. But all my tries did compile and run without error but the date wasn't changed.
What I've tried:
Created a
Processinstance, applied admin credentials toProcessStartInfo, set theFileNametoc:\windows\system32\cmd.exeand the argument to/C date {thedate}. I redirectedStandardOutputandStandardErrorand after executionStandardErrorcontains the same message as stated above: "missing client permission"I've modified this example MSDN: WindowsIdentity.Impersonate using PInvoke with
AdvAPI32.LogonUserto raise permissions andKernel32.SetSystemTimeto change the system time.AdvAPI32.LogonUsersucceeds andWindowsIdentity.GetCurrent().Namereturns the admin name, but callingKernel32.SetSystemTimefails with "missing client permission".I've tried opening the current process
AdvApi32.OpenCurrentProcessand adjusting the permissions usingAdvApi32.AdjustTokenPrivilegesfollowing this example StackOverflow: Change system time programmaticaly using datetimepeaker and the code runs totally fine butKernel32.SetSystemTimefails...
[EDIT] Solution:
I ended up writing a small program with an embedded app.manifest that requests administrator privilegs. This app is called from the main program so this can still be run by a normal user.
It is not possible to change the privileges of the process, once it's started. The original process has to start another process with elevated privileges. This second process can actually be the same .exe file, but with a command parameter that tells the process to do some small stuff and exit immediately.
To start a process with elevated privileges use Process.Start, but with .Verb = "runas", as described in another question. This will of course cause UAC prompt to pop up, if it's enabled on the machine. At least one UAC prompt has to be shown, because UAC prompt is the whole point if this defense mechanism.
If you want to reduce many UAC prompts to just one then you can set the original app to be started as administrator (UAC prompt shows when original process starts) and have just one process. Or have some interprocess communication between original process and elevated process, so that elevated process is started only once and made to finish when original process ends. In the second case UAC prompt shows the first time it's needed.