How to create an executable that asks for administrator rights

8 views
Skip to first unread message

John Smith

unread,
Apr 24, 2021, 9:53:41 AMApr 24
to
I have a Win32 executable that that from time to time downloads and update file
from internet.

The process goes as follows:
(1) when my program, "myprog.exe", is about to exit it downloads "upd.exe" from
internet
(2) Just prior to exiting "myprog.exe" runs using CreateProcess() function on the
"upd.exe" and then exits
(3) "upd.exe" is now running and replaces "myprog.exe" with a never version and
then it exits.

All would go fine but unfortunately Windows UAC prevents "upd.exe" from running.
However if "myprog.exe" is running with Administrator privileges all goes well.
Otherwise "upd.exe" just does not run and and if I run it from command prompt it
show "Access violation" or similar messages.

Is there a way that "upd.exe" would invoke Windows to ask something like "Do you
want upd.exe to execute" as I've seen some programs do?

I've seen posts about embedding a manifest file to the "upd.exe" that would then
make Windows to bring up a "Do you want upd.exe to execute" etc.
Currently I've embedded a manifest file to "upd.exe" but the problem may be that
"myprog.exe" uses CreateProcess() instead of ShellExecute() that may use manifest
prompts.

Some suggest using an SFX program to embed an manifest file but I have not tried
that. Any suggestions?

JJ

unread,
Apr 25, 2021, 12:17:32 AMApr 25
to
If an application is designed to require elevated from the start, i.e. if
it's not designed to behave differently depending whether it was run with
elevated privileges or not (e.g. run in read-only mode if not), then the
application's EXE must have the manifest resource which states that it
requires elevation.

The manifest would be like the one shown in below article section. (long URL
warning)

http://docwiki.embarcadero.com/RADStudio/Sydney/en/Customizing_the_Windows_Application_Manifest_File

Note: the resource must use ANSI based character set. e.g. Windows-1252. It
must not use any UTF character set.

Refer to your IDE/compiler documentation on how to include manifest
resource.

You can also use any resource editor software to manually add the manifest
resource into an EXE file. There can be only one manifest resource per one
EXE file. The resource type should be RT_MANIFEST (0x100), and its ID should
be `1`. In case the resource editor software doesn't support manifest
resource type.

John Smith

unread,
Apr 25, 2021, 1:44:27 AMApr 25
to
I have a manifest file but it does not do anything as far I can see.

JJ

unread,
Apr 26, 2021, 2:50:32 AMApr 26
to
On Sun, 25 Apr 2021 08:44:25 +0300, John Smith wrote:
> I have a manifest file but it does not do anything as far I can see.

The manifest must contain information which uses `requireAdministrator` as
the requested privileges. Like in the first example code on the previously
mentioned article, but replace `asInvoker` with `requireAdministrator`.

John Smith

unread,
Apr 27, 2021, 8:21:30 AMApr 27
to
After a lot of testing and searching I managed to get it to work.

The process goes as follows:
(1) when my program, "myprog.exe", is about to exit it downloads "upd.exe" from
internet. All are 32-bit win32 exes
(2) Just prior to exiting "myprog.exe" runs using plain CreateProcess() (not
ShellExecute) function on the "upd.exe" and then exits
(3) "upd.exe" is now running and replaces "myprog.exe" with a never version and
then it exits.

upd.exe has manifest that works:

<?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>
<requestedExecutionLevel
level="asInvoker"
uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
</application>
</compatibility>
</assembly>


That worked. My previous manifest *that did not work* was:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="Microsoft.Windows.Generic"
type="win32"
/>
<description>Dmsetup ohjelma</description>

<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"
/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>


I just wonder what made the difference?

JJ

unread,
Apr 28, 2021, 2:02:57 AMApr 28
to
That shouldn't work. It's a valid manifest, but it won't make the system to
show the UAC prompt - whether `CreateProcess()` or `ShellExecute()` is used
to run the application.

Also keep in mind that, if the (parent) application process which execute
the (child) application with `requireAdministrator` manifest is already
elevated, the system won't show the UAC prompt again, because by default,
privileges are inherited to child processes.

The `asInvoker` execution level means that the (child) application process
will use the same privileges as the (parent) application process which
execute it. If the parent application is not elevated, then the child
application will not be elevated - no matter which function is used to
execute it.

John Smith

unread,
Apr 28, 2021, 6:21:32 AMApr 28
to
Hello,

You're right. I did have "requireAdministrator" and not "asInvoker"

John Smith

unread,
Apr 28, 2021, 12:29:13 PMApr 28
to
Hello,

after a lot of testing again I found out that having "requireAdministrator" in
the "upd.exe" would cause problems, ie. it won't start at all.

My update system is as follows:

(1) when my program, "myprog.exe", is about to exit it downloads "upd.exe" from
internet. All are 32-bit win32 exes.
"myprog.exe" does have a manifest with "requireAdministrator"
"upd.exe" does have a manifest with "asInvoker" (NOT "requireAdministrator")

(2) Just prior to exiting "myprog.exe" runs using plain CreateProcess() (not
ShellExecute) function ro run the "upd.exe" and then exits.
NOTE! if "upd.exe" has "requireAdministrator" in its manifest Createprocess()
won't run it at all and I get the 740 error. However "asInvoker" in the manifest
works fine.

(3) "upd.exe" is now running. Its has a resource file embedded "udpdater.exe".
"upd.exe" writes the "udpdater.exe" on disk and starts to exit.

(4) "upd.exe" is about to exit but before exiting it runs a
ShellExecute(NULL, "runas","updater.exe","2", NULL, SW_SHOWNORMAL);
"updater.exe" does have a manifest with "requireAdministrator"

(5) An UAC windows pops up asking if I want to run "updater.exe". I click OK and
"updater.exe" is now running. Its has a resource file embedded "myprog.exe".
which it writes the on disk replcaing the old "myprog.exe".


None of the rigmarola & UAC popping up would have been prevented if:
a) The very first "myprog.exe" had used ShellExecute and not CreateProcess.
or
b) The very first "myprog.exe" would have had full Administrator rights
(allthough the manifest does have it) or Windows 8 compatibility mode on.

JJ

unread,
Apr 29, 2021, 5:54:06 AMApr 29
to
Oh, sorry. I was mistaken on the `CreateProcess()` part. With that function,
the system won't show the UAC prompt if needed - regardless of the manifest
presence and its requested execution level, of the child application.

The UAC prompt if needed, will be shown only if `ShellExecute()` is used.
Reply all
Reply to author
Forward
0 new messages