-1

I am using Microsoft Visual Studio 2010 and I am writing my code in C/C++.

I have code which automatically starts my installation process. Installation process requires UAC in this case, so I use ShellExecuteEx() API function with runas verb:

hWindow = InstallCreateWindow(NULL);

execInfo.cbSize         = sizeof(execInfo);
execInfo.lpVerb         = _strdup("runas");
execInfo.hwnd           = hWindow;
execInfo.lpFile         = szPath;
execInfo.lpParameters   = szParams;
execInfo.fMask          = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;

Sleep(1000);

SetActiveWindow(hWindow);

if(ShellExecuteEx(&execInfo))
    return execInfo.hProcess;

if(GetLastError() == ERROR_CANCELLED)
{
    // user answered NO to UAC prompt
}

InstallCreateWindow() function creates information window and it also creates separate window message thread. Window is visible, topmost and it responds to messages. I have to create it because I've read that correct hwnd parameter in SHELLEXECUTEINFO structure is required to keep UAC prompt window on top.

But this does not work. Sometimes UAC window runs maximized, but mainly it is minimized and highlighted in the taskbar. Is there a method to bring UAC window to top in any case?

cls
  • 501
  • 1
  • 5
  • 18
  • 2
    If the program that called `ShellExecuteEx` does not have foreground activation, then the UAC dialog cannot take activation, so it has to wait until the use activates it. – Raymond Chen Jan 30 '16 at 01:29
  • 1
    You're leaking the string you `_strdup`. – Jonathan Potter Jan 30 '16 at 01:33
  • @JonathanPotter it is for test, I'll remove it. – cls Jan 30 '16 at 01:33
  • @RaymondChen what does foreground activation means? My window is topmost. Do I need to call `SetForegroundWindow()` on it? – cls Jan 30 '16 at 01:34
  • @RaymondChen, OK, I found your article about foreground activation permission. So, If I call `ShellExecuteEx()` when user clicks (or does some other activity) on my window, I can get UAC window on top? – cls Jan 30 '16 at 01:44
  • It's missing `execInfo.nShow = SW_SHOWNORMAL`, and what's the purpose of `SetActiveWindow(hWindow);` and `Sleep(1000)` – Barmak Shemirani Jan 30 '16 at 01:58
  • @BarmakShemirani UAC window is independent from `SW_SHOWNORMAL`, isn't it? `SetActiveWindow(hWindow)` is for test, `Sleep(1000)` waits until window is initialized :) of course later I'll do it with events. – cls Jan 30 '16 at 02:02
  • @RaymondChen I wrote code which calls `ShellExecuteEx()` when user clicks on a button in my window, and it works now, thank you very much! – cls Jan 30 '16 at 02:12
  • C/C++ isn't a language. – Insane Jan 30 '16 at 12:34
  • @Insane I know. But when I say that I write in C, some people say it is not C because I use `.cpp` file extension and can use C++ features. When I say that I write in C++, they say that could not see any C++ features such as classes and templates. So to avoid misunderstanding I say that I write in C/C++, which means "mainly in pure C, using `.cpp` files". – cls Jan 30 '16 at 15:44
  • 1
    You are writing in C++ – David Heffernan Jan 30 '16 at 16:44
  • 1
    @deselect Mainly in C using C++ is a way of saying C++ without C++ features :P – Insane Jan 30 '16 at 17:11

1 Answers1

1

JUST TO MARK IT AS ANSWERED

If the program that called ShellExecuteEx does not have foreground activation, then the UAC dialog cannot take activation, so it has to wait until the use activates it. Raymond Chen

milevyo
  • 2,165
  • 1
  • 13
  • 18