Discussion:
How to create an executable that asks for administrator rights
(too old to reply)
John Smith
2021-04-24 13:53:36 UTC
Permalink
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
2021-04-25 04:15:57 UTC
Permalink
Post by John Smith
I have a Win32 executable that that from time to time downloads and update file
from internet.
(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?
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
2021-04-25 05:44:25 UTC
Permalink
I have a manifest file but it does not do anything as far I can see.
Post by JJ
Post by John Smith
I have a Win32 executable that that from time to time downloads and update file
from internet.
(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?
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.
JJ
2021-04-26 06:48:51 UTC
Permalink
Post by John Smith
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
2021-04-27 12:21:29 UTC
Permalink
Post by JJ
Post by John Smith
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`.
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
2021-04-28 06:01:16 UTC
Permalink
Post by John Smith
After a lot of testing and searching I managed to get it to work.
(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.
<?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 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
2021-04-28 10:21:31 UTC
Permalink
Hello,

You're right. I did have "requireAdministrator" and not "asInvoker"
Post by JJ
Post by John Smith
After a lot of testing and searching I managed to get it to work.
(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.
<?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 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
2021-04-28 16:29:12 UTC
Permalink
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.
Post by John Smith
Hello,
You're right. I did have "requireAdministrator" and not "asInvoker"
Post by JJ
Post by John Smith
After a lot of testing and searching I managed to get it to work.
(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.
<?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 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.
JJ
2021-04-29 09:52:19 UTC
Permalink
Post by John Smith
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.
(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".
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.
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.
Loading...