CreateProcess UAC Elevation?

BlitzMax Forums/BlitzMax Programming/CreateProcess UAC Elevation?

bookworm99(Posted 2012) [#1]
Hi all,

I'm trying to use CreateProcess to spawn a program which requires a UAC elevation request to launch correctly. However, it's failing silently with no indication of why. The only way to solve this that I've found so far is to run my BlitzMax program as administrator (which is otherwise unnecessary).

Is there any other way around this? Is it possible, for example, to have my BlitzMax program request elevation before launching the process?

Thanks.


col(Posted 2012) [#2]
Hiya,

I believe the answer may be with using a manifest file.

Do you want, or not want, the UAC to ask for permission when the second program is run?

Last edited 2012


bookworm99(Posted 2012) [#3]
It has to ask permission. I think I was a little unclear:

I have two programs, my blitzmax program and another program, written in a different language, which spawns a UAC prompt whenever it is run and will not run without elevation. When I try to launch it via CreateProcess, no UAC prompt appears, and the program never launches. It just dies silently.

I can get around this by making my Blitzmax program launch as administrator - but that is unnecessary, and thus bad security practice. I could create a manifest and all of that, but that isn't the best solution in this case. So what I need to figure out is how to get CreateProcess to let my other program spawn its UAC prompt.

Thanks!


col(Posted 2012) [#4]
Have you tried using

system_ "InsertAppNameHere.exe"

?
to see what happens?

Last edited 2012


bookworm99(Posted 2012) [#5]
Same thing, I'm afraid.


col(Posted 2012) [#6]
Can you try this...



EDIT:- The UAC may only trigger when running the exe file. For me, it doesn't trigger when building the app and running it from inside the IDE, although the second app does run.

Last edited 2012


bookworm99(Posted 2012) [#7]
Fantastic! That's done it. Thank you so much.

If you don't mind my asking, could you explain to me how you came up with it/where I might learn about how you did this?

Thanks again!

Edit: Additionally, is there a way to check whether the program it spawns is open, and then perform certain actions once it's closed? I presume that could be done somewhere around the line "WaitForSingleObject(ShExecInfo.hProcess,INFINITE)"

Last edited 2012

Last edited 2012


col(Posted 2012) [#8]
Yeah sure.

I came up with it by first reproducing your issue.
I made a dummy app ( in BlitzMax ) that used an external manifest file to require UAC elevation when it was run. I then made another app ( the one above ) that would open the first. I could now reproduce your problem of it exiting silently, which it did.

I thought about the situation in reverse, ie most programmers in this scenario want to open an app that requires elevation but without activating the UAC control dialog. So after a little googling, I thought to use the Win32Api directly and I came across the code above, modified it to open the file as 'normal' and voila.

To achieve opening the 2nd app without the UAC popup the parameter 'ShExecInfo.lpVerb = "open"' is usually '.....lpVerb = "runas" to open it as administrator.

Initially I didn't know if it would work out or not, but it did, so all's great.

You can get BlitzMax to access at a lower level than most people care for and also lower than it gives itself credit for :-)


bookworm99(Posted 2012) [#9]
That's awesome. Thanks again for your help (and I was able to solve the other issue about executing code afterwards). I really appreciate it; solved me a lot of headache...


col(Posted 2012) [#10]

Additionally, is there a way to check whether the program it spawns is open, and then perform certain actions once it's closed?



Yes, the If ShellExecuteEx(ShExecInfo) returns true if the second app is successfully opened, false otherwise.

The WaitForSingleObject([...]) will force your 1st app to wait for the second app for a specified period of time in milliseconds or if you use the INFINITE value then it will wait forever for the second app to finish and exit. Code execution will continue from here once this command is satisfied.

If it isn't successfully opened then the else path is taken and the error reason code for the app not running can be retrieved by the return value of GetLastError() and cross-reference the value at the web address.

Have fun :D

Edit:- I should also point out that for completeness and to prevent and a couple of bytes memory leak :P the memory for the string used by .ToCString() needs to be freed when its finished with :-

'Use this when the ShExecInfo instance is no longer needed and before it goes out of scope.
MemFree ShExecInfo.lpVerb
MemFree ShExecInfo.lpFile

'Make sure we have to create a new instance again because of the freed strings.
ShExecInfo = Null


Last edited 2012