Search code examples
qtuacshellexecute

How to execute an app without elevation?


I want to invoke an updater to check for updates (not to actually do the update but only check if there is any). I would like to do this in the background and silently. If there is an update, I would ask the user for elevated permissions and run the updater with that. The checking involves reading a file in the application's directory and comparing the version found in it with the one on a website.

How can I run it without elevation for checking only? QProcess::start() fails because it needs elevated permission and ShellExecute only works if I add the "runas" verb for the same reason (which I only want if there would be actually writing in that directory i.e. I want to perform an update). I'm guessing I need to add some sort of manifest but I don't know its contents.


Solution

  • So it turns out that I had another bug that caused the non-elevated running branch to run in all cases. The model I described in the post works. To avoid Windows infering the need for elevated permissions, you need to add a manifest resource. (for example, if the name of your application exe contains the word "updater" it will be triggered)

    The contents of the manifest are the following:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
            <security>
                <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                    <requestedExecutionLevel level="asInvoker" uiAccess="false" />
                </requestedPrivileges>
            </security>
        </trustInfo>
    </assembly>
    

    Compiling it to your .exe depends on your compiler and environment, so I'm only showing mine: Qt Creator and mingw-gcc:

    Create an rc file for the resources with the following content:

    1 24 DISCARDABLE manifest.xml
    

    Add this rc file to your .pro like this:

    win32:RC_FILE = resources.rc
    

    After this, ShellExecute without the verb paramter will run without elevation, and using "runas" will run it with elevation.