Our setup has an embedded manifest that triggers the UAC before the application starts. (The applications runs as an admin user). However, if the setup needs to install the .NET Framework, we have to continue the setup after a reboot. For this reason, we have to create a registry key in the current user's RunOnce.
Unfortunatly, HKEY_CURRENT_USER points to the Administra开发者_Python百科tor's registry. We need to find out the user that is currently logged in and started the installation. (Th normal USER clicked the setup.exe, an ADMIN entered his details in the UAC prompt. We need to find out who the USER was)
I've tried all the usual methods (Environment.UserName, WindowsIdentity.GetCurrent())
Thanks!
You can use the LsaEnumerateLogonSessions function to retreive what you need. However, it is a winapi C function call. If you need a managed version of it, I belive you can look at the source code for Cassia, which uses this function in its terminal services API. The call should be the same. You can also look here.
Also you can use the NetWkstaUserEnum WINAPI function. You can find a managed wrapper for it here
With Cassia library this code works fine:
ITerminalServicesManager manager = new TerminalServicesManager();
ITerminalServicesSession session = manager.CurrentSession;
string userInfo = session.DomainName + "\\" + session.UserName;
NTAccount account = session.UserAccount;
Run your initial setup.exe as a small executable that puts up a splash screen while invoking your real setup program as a child process. The small EXE is not run as admin and can pass the logged in user name to the child process. The child process invokes UAC and runs in the admin context but already has the logged in username as a command line parameter.
It is not possible to retrieve the original user if your application is ran as Administrator:
If a user launches Setup by right-clicking its EXE file and selecting "Run as administrator", then this flag, unfortunately, will have no effect, because Setup has no opportunity to run any code with the original user credentials. The same is true if Setup is launched from an already-elevated process. Note, however, that this is not an Inno Setup-specific limitation; Windows Installer-based installers cannot return to the original user credentials either in such cases.
Source : InnoSetup Help
As said by Matthew in comments, you should not run your application as Administrator but only trigger UAC when needed in your code.
This returns the name of the logged in Windows User by stripping out the domain:
using System.Security.Principal; // here is the security namespace you need
...
string userName = WindowsIdentity.GetCurrent().Name.Replace("\\", "|");
string[] split = userName.Split(new Char[] { '|' });
lblDebug.Text = (split.Count() > 1) ? split[1] : userName;
精彩评论