Can I speed up UAC/elevation in WiX? - installation

When a normal user runs a WiX installer which requires elevation, there appears to be a delay of 30 seconds or more between the user clicks the "Install" button and the UAC prompt comes up. This happens even though the install button is marked with the UAC shield, suggesting the installer "knows" that elevation will be required.
Is there a way to IMMEDIATELY throw up the UAC when the user 1) runs the installer or 2) clicks that "Install" button?

The length of time for the UAC prompt to come up depends on the size of the exe. (Try it yourself by right-click run as admin various exes of various sizes.) Therefore I have heard it suggested that you make a teeny launcher exe that will bring the prompt up quickly, and have it launch everything else. Anything launched from an elevated process is elevated.
Be sure to name your launcher well, for the 1% of users who actually read the UAC prompts.

How big is your MSI file? I don't know for a fact, but I think splitting your files into a separate .cab file and possibly digitally signing it might make the validation of the MSI file go faster.
Otherwise, there really isn't anything you can do about it to my knowledge. I hope someone proves me wrong. :-)

Related

Avoid UAC prompt

I've a app embeded with manifest *.exe.manifest. When I launch executable it shows UAC prompt every time. How can I avoid this? I have element requireAdministrator with attrubute level equal to requireAdministrator. Is that possible at all?
You are seeing the UAC elevation prompt because you asked for it. The operative word here is require. If the user isn't currently running elevated then that's always going to invoke the elevation prompt.
If you don't want that to happen then you do have to replace requireAdministrator with asInvoker. With the side-effect that your program won't run with the elevated privileges or course. And no, you cannot elevate silently, that would defeat the point of UAC. The point of UAC is not to stop you from doing something, it is to let the user know.

Is there a way to install software that prompts for privilege escalation(UAC) programmatically?

Basically I either need to Click the UAC button with my program(which i don't believe is possible) or somehow make it so I don't need to click the button to install the software. I will also need to click buttons during the install with my program but I know how to do that. I am only concerned with the UAC things.
One way or the other, the user is going to have to click that button to give you permission to proceed. That's the whole point of UAC, if there were a way to work around it, it would serve absolutely no purpose.
You can either ask for permission sooner (at the beginning of your installation) or later (at the point in the installation when the privileges are first actually required), but you have to do it one of those times.
The standard course of action is to embed a manifest in your application that indicates you require administrative privileges. The applicable line looks like this:
<requestedExecutionLevel level="requireAdministrator" />
Alternatively, you could choose to rely on UAC's "Installer Detection" functionality:
The first application compatibility technology that is part of UAC is called Installer Detection. Because most installers write binaries to the Program Files directory, they overwhelmingly need administrator privileges. Installer Detection is designed to scan the name and the resources of the EXE to determine whether an application is an installer. For example, an executable would be marked as an installer if the executable name or description contained the strings "install" or "setup". So an application named setup.exe, without an application manifest, would trigger a UAC elevation if launched by a token without administrator privileges.
Clicking buttons during your install isn't a very good idea, either. If this is an installer that you're writing, code in some "silent install" flags that you can specify when executing the installer app. If this is a third-party installer that you're using, check the documentation; chances are such flags already exist. The point of these flags is that interactive UI is not displayed at all during setup, meaning that no one has to bother clicking any buttons (which is very hard to get right).
you can install your program in the user's home directory or any other directories which is writable without administrator privilege.
if you're writing an installer wrapper, you can ask for UAC on the wrapper and the wrapper can start the real installer(s) with administrator privilege. Most installers also provides command line options for unattended installations, so you might want to check those instead of scripting button clicks.
You can't click button on UAC consent dialog.
Your other options depend on what you really try to achieve. So give us more details on the your task: there could be better design choices than clicking installer buttons from an application.
To avoid UAC, you can install a service which will start the installation. But user has to consent when you install the service.

Is it possible to cancel a silent install on Windows

We have an installer wizard (written in .NET) which configures and kicks off a series of standard Windows installers. The installers are run silently. Right now, clicking "Cancel" on the wizard's dialog stops further installers from running, but does not stop whatever installer is running silently in the background.
Is there a way to send a installer running silently the equivalent of pressing the Cancel button on a non-silent install? (I could kill the installer process, but I expect that that will leave a half-installed (and probably non-uninstallable) mess behind.)
I'm not sure if you're creating new instances of these installers within your own installation wizard so I don't know how applicable this solution is going to be, but if you do have access to the actual (derived) System.Installer objects that correspond to the installers, calling the overridden System.Installer.Rollback() method of those objects should achieve the desired result. Let me know if this doesn't work and I can try helping you further.

Sharing data between users with the Windows 7 registry

I have a program that was written on XP. What I've found out is that it doesn't work properly on Win7 because HLKM is no longer writable by non-admins.
Essentially, when you register the program, the licensing information is supposed to go into the registry. That information is valid for everyone on the computer, not just the one user, so I don't want to put it in HKCU. But any copy of the program needs to be able to edit that registry (even if it's a non-admin running it), because there are certain situations when it's going to go get updated license information from my web server (for example, if the registry data is lost or damaged, or if your current license is expired and it needs to see if we've applied an extension).
It's not horrible if it goes out to the web server for every unique user who starts up the program, but it causes some annoying issues, so I'd rather it continue to work the way it did in XP. Is there a way to store data in the registry and still have it shared under Win7, or am I going to have to start looking at storing an INI file on the drive?
Here is how I would architect it: your setup runs elevated and sets up the key. Then if their licensing gets corrupted or whatnot, you enable a button or menu item that has text like "fix license" or "update license". You put a shield on that button or menu item. When they click it, you launch a separate exe using ShellExecute. That exe has a manifest that requires elevation. It can then write to the protected area of the registry. The rest of the app can have a manifest with asInvoker.
If you want it to be completely invisible, either the whole app must always run elevated (annoying) or sometimes the app will just launch another exe that asks for elevation without warning - in which case the smart users will say no. A little less invisibility is a good thing imo.
Could you get the installer to make your particular area of the registry to be writeable by everyone? The installer will need to be run with elevated privileges anyway, I'd expect - so this would seem an ideal approach.

UAC and elevation prompt pattern

I've read several questions regarding UAC and privilege elevation but I've not found a satisfactory/comprehensive answer.
I have this scenario: on Windows 6 or above, when the user opens a configuration window I have to show the shield (BCM_SETSHIELD) on the OK button only if privilege elevation will be required to complete the task. -- I do know that in the Windows UI the shield is always visualized for "administrative tasks", even if UAC is disabled, but the customer had this specific request.
I have draft this condition in order to show the icon:
The user has not administrative rightsOR
The current process has TOKEN_ELEVATION_TYPE == TokenElevationTypeLimited
The condition #1 is simple: if the user hasn't administrative rights elevation is always required regardless of UAC. The #2 implies that the user has administrative rights, and any other value of TOKEN_ELEVATION_TYPE means that elevation is not needed.
Is really that simple? I am missing something? And - there's a documented or well-known pattern regarding this topic?
You are right. Most people just put the shield on if the button will be running elevated, but the right thing to do is to put the shield on if the button will cause elevation (ie suppress it if you are already elevated, since everything you launch will remain elevated unless you go to some trouble to launch a non elevated process, and suppress it if UAC is off.)
The good news is that if someone in the Administrators group runs (under UAC) an application non-elevated, you'll get back false when you ask if they are an admin or not. So I think you might be ok with just that one test.
I see that there is a lot of confusion about this topic and the answer from Kate here is not correct and incomplete.
Since Vista an Admin may be logged in but his processes do not run elevated automatically. An Admin has a so called "Split Token". This means that there may be processes running for the SAME admin user, and some of them run elevated and other do NOT run elevated. When an Admin runs a not elevated process, some of the privileges of his token have been removed. It is not anymore as in XP where ALL processes run either elevated or not elevated.
Install Process Explorer from www.sysinternals.com and enable the column "Integrity Level". If you see there "Medium" this process does not run elevated. If you see there "High" the process runs elevated. If the process runs with Integrity level "High" no UAC prompt is required to start another process elevated.
When UAC is completely turned off, ALL processes run "High", so no elevation is required never. UAC can be turned off under
HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System
setting the key "EnableLUA". Changing this setting requires reboot.
But there is another point that was not yet mentioned here.
In Control panel it is possible to configure "Elevate without prompting". And in this case an Admin user can start an elevated process from another not elevated process and NO UAC prompt will show up.
This setting is stored under the same registry path in the key "ConsentPromptBehaviorAdmin" for admin users.
For all non-admin users there is the key "ConsentPromptBehaviorUser" but this changes only the bahavior, but elevation cannot be turned off. Non-admins will always get an UAC prompt. (if UAC is not completely off)
How do you know if your process runs elevated:
Call OpenProcess(), then OpenProcessToken(), then GetTokenInformation(TokenElevation).
And to get the Integrity Level call GetTokenInformation(TokenIntegrityLevel) and then GetSidSubAuthority()
So if you want to show your icon only if elevation is really required you must check if your process runs elevated and additionally check these registry keys and you must know if the user is an admin or not. This involes several lines of code and I would consider to show this icon always when elevation may be required to keep it simple.
Please note that the API IsUserAnAdmin() is deprecated. It must not be used anymore since Vista. Checking if a user belongs to the administrators group is much more code now.

Resources