0

I am trying to write an installer program in Visual Basic, and I would like the installer to try to get Admin permissions. If the account is an administrator, I want it to just assume them, and if the account does not have admin permissions, I want a prompt such as this to show.

UAC Prompt

If the user can give the permissions, then it will continue on with them, and if it cannot give them, then it will take an alternative, no-admin permissions route, just like the Google Chrome installer. How do I do this? I haven't found anything helpful on Google after an hour of research.

DaveTheMinion
  • 664
  • 3
  • 22
  • 45
  • 1
    "If the account is an administrator, I want it to just assume them" I don't think this is possible. The system will always display the UAC prompt; the difference is that the standard user one includes the request for credentials, as in your screenshot, whilst the admin one doesn't. Also, there isn't an option to say 'Allow the program to run, but without elevation', so it's hard to see how your second requirement can be met too. I hesitate to use the word 'impossible' but MSFT have a lot riding on the impregnability of UAC – peterG Jan 19 '14 at 01:14
  • @peterG I don't care if a UAC prompt is shown. I misworded my question because I have UAC turned off on my computer, so when a program needs Administrator privileges, it just takes them. – DaveTheMinion Jan 19 '14 at 03:31

2 Answers2

1

running out of comment space so . . . A good way to tackle installers like this is to use a set of three programs: the Loader, the installer, and the main program. The Loader is the one driven from the desktop shortcut etc. Its task is to check the vendor's web api etc to see if a new version is available. If not, then it launches the main program. If however, there is a new ver available, then it offers the user the opportunity to download it. If the user agrees, then the loader launches the Installer. The installer is the only one of the three marked as RequireAdmin, and so the UAC prompt only appears when necessary. The installer downloads and installs the new version, uninstallling or overwriting the old one as necessary. We have done something like this and it works well. However, MS ClickOnce also works well and is a lot less coding and all round easier to get right, and I'd advise you to consider this option as well.

EDIT: However, a bit of searching led me to this MSFT link - it may be helpful. I haven't tried this technique myself.

peterG
  • 1,651
  • 3
  • 14
  • 23
1

In Visual Studio, add a new file to your project, select "application manifest" as the file type and then click okay.

You will get an XML document. The first big chunk of the document goes something like this:

 <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
        <!-- UAC Manifest Options
            If you want to change the Windows User Account Control level replace the 
            requestedExecutionLevel node with one of the following.

        <requestedExecutionLevel  level="asInvoker" uiAccess="false" />
        <requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />
        <requestedExecutionLevel  level="highestAvailable" uiAccess="false" />

            Specifying requestedExecutionLevel node will disable file and registry virtualization.
            If you want to utilize File and Registry Virtualization for backward 
            compatibility then delete the requestedExecutionLevel node.
        -->
        <requestedExecutionLevel level="asInvoker" uiAccess="false" />

De-comment the line that says:

<requestedExecutionLevel  level="requireAdministrator" uiAccess="false" />

This will make that application (or a DLL) run the UAC to get administrator privileges.

If you only want a particular component to run elevated, then put that code in a separate DLL file. When your main program first calls that assembly, the UAC will appear, and elevation will be granted.

Nathan M
  • 873
  • 5
  • 18
  • 1
    Good catch - I was assuming the OP already knew how to mark the exe as requireAdmin, which may not be the case. Also, to get to the manifest, you can just click the 'View Windows Settings' button on the Application tab of the project explorer. – peterG Jan 19 '14 at 14:38
  • @peterG I did not know about changing the `requireAdmin` thing, and I further do not know how to make a separate DLL file to default to if the user ignores the UAC prompt. – DaveTheMinion Jan 19 '14 at 17:22
  • @DavidB OK then perhaps I was too hasty in assuming what your question was about. Maybe you could edit it to include more about exactly what you mean by 'Installer Program' and what you want it to do that cannot be done using a VS deployment project, (ISLE in VS2012/3) or ClickOnce etc. Meanwhile, setting RequestedExecutionLevel in the manifest as per Nathan M's answer is how you control whether the exe generates a UAC prompt when run; ClickOnce and the Google Chrome installer avoid the requirement for Admin at install time by installing to the user's profile rather than to program files. – peterG Jan 19 '14 at 18:25
  • Wouldn't that be as simple as having a separate Dll and referencing it? Catch any exception from denied access, and then switch to the other dll? also, if my answer was useful, could I get an up vote? :-) – Nathan M Jan 19 '14 at 18:28
  • @peterG I know that the Google Chrome installer installs in the user's temp folder if permissions are not granted. I am not asking how they installer does it, I am asking how I can do this same thing in Visual Studio. – DaveTheMinion Jan 19 '14 at 18:43
  • 1
    @NathanM That's the thing: I don't know how to do that. As for the upvote, I forgot to give it to you until now. – DaveTheMinion Jan 19 '14 at 18:44
  • 1
    Create two different DLLs with two different permission scopes... reference them both in your project. If the first one fails, either test for an exception in a try block, or maybe do something unconventional like tell yourself about the state of the program with a registry switch if you have to. at any rate, use the other assembly as a fall back ... simply reference both DLLs in your project. – Nathan M Jan 19 '14 at 18:46