7

I want to start another program which runs as user from a program running as administrator.

The problem is that the second program needs to use outlook, which is not possible if the program runs as admin. The main program needs to run as admin.

I did already come up with this two solutions:

Process.Start("cmd.exe", @"/C runas.exe /savecred /user:" + Environment.UserDomainName + "\\" + Environment.UserName + " " + "\"SomeProgram.exe" + "\"");

or

Process.Start("explorer.exe", "SomeProgram.exe");

But i have a problem with both solutions. The first one asks the user for the password (only the first time after windows was restarted). The second one probalby won`t work in the future, because as far as i found out it is considered as a bug and probably fixed with an future update.

So I would like to know is there any other solution, where the user does not need to enter his password?

This seems to work for me:

Process.Start("cmd.exe", @"/C runas.exe /TrustLevel:0x20000  " + "\"SomeProgram.exe" + "\"");
FKorni
  • 295
  • 3
  • 11
  • 1
    Raymond Chen did a good job of describing this in [How can I launch an unelevated process from my elevated process and vice versa?](http://blogs.msdn.com/b/oldnewthing/archive/2013/11/18/10468726.aspx) (which also covers all kinds of details such as when elevation used different account credentials to those being used for the rest of the session) – Damien_The_Unbeliever Jul 27 '15 at 07:04
  • But isn't that just an other way to use the exploer.exe to do the job? Anyway i found another solution, I did add it to the original post. – FKorni Jul 27 '15 at 08:24
  • Does your solution deal correctly with de-elevating from Alice's admin account to Bob's user account (using the examples from Raymonds link)? – Damien_The_Unbeliever Jul 27 '15 at 08:32
  • The `runas /trustlevel` thing leaves the process in a weird state and should probably be avoided. See http://stackoverflow.com/q/30970433/886887 – Harry Johnston Jul 27 '15 at 21:59
  • One workaround is to have a parent program that runs as the user, which launches the admin process and, later, the user process. But Raymond's solution is probably sound; yes, it uses Explorer, but it does so *legitimately*. – Harry Johnston Jul 27 '15 at 22:02
  • I currently can't test it on a Win 8 machine, so I am not sure how my solutions works there with outlook. On Win 7 it seems to do the right job. If it is not working under Win 8 i need do adopt it anyway. – FKorni Jul 28 '15 at 14:01

2 Answers2

1

Process class has StartInfo property that is an instance of ProcessStartInfo class. This class exposes UserName, Domain and Password members to specify the user you want to run the process.

Process myProcess = new Process();
myProcess.StartInfo.FileName = fileName;
myProcess.StartInfo.UserName = userName;
myProcess.StartInfo.Domain = domain;
myProcess.StartInfo.Password = password;
myProcess.Start();
Matteo Umili
  • 3,114
  • 1
  • 13
  • 26
  • 1
    That would mean that i need to know the user password, which isn't the case. The program is used by many different users, so this isn't an option for me. – FKorni Jul 27 '15 at 07:17
  • @FKorni I don't think that you can impersonate another user without even knowing the credentials – Matteo Umili Jul 27 '15 at 07:26
  • Well the main program requests admin rights with the manifest, but the second program than should just run with the normal user of the current session. – FKorni Jul 27 '15 at 07:37
  • @FKorni Admin doesn't have god rights, you can't impersonate another user without the correct credentials – Matteo Umili Jul 27 '15 at 08:06
  • @FKorni if the user that has to run the process is the one that is logged on, you can follow the link given by Damien_The_Unbeliever – Matteo Umili Jul 27 '15 at 08:17
  • I did come up with another solution, which seems to work for me. I did edit my first post. – FKorni Jul 27 '15 at 08:23
0

I was having the same issue and was not able to get the current logged user. NB: querying wmi is not a solution as many users may be logged in at that time so my solution is to do the reverse. Launch my app as current user and if the current user is not admin, I request to run as admin.

if (IsAdministrator())
{
    // run whatever you want as elevated user
}
else
{
    //launch the same app as admin
    ExecuteAsAdmin(PATHH_TO_THE_SAME_APP.EXE);
    //execute whatever you want as current user.
}



public static void ExecuteAsAdmin(string fileName)
{
    Process proc = new Process();
    proc.StartInfo.FileName = fileName;
    proc.StartInfo.UseShellExecute = true;
    proc.StartInfo.Verb = "runas";

    proc.Start();
    proc.WaitForExit();
}

public static bool IsAdministrator()
{
    var identity = WindowsIdentity.GetCurrent();
    var principal = new WindowsPrincipal(identity);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
Dharman
  • 21,838
  • 18
  • 57
  • 107