Bring UAC window to top using ShellExecuteEx() - c

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?

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

Related

UIAutomation FlaUI - Detect Both Closing and Opening Windows at the Application Level

I have successfully used the solution for detecting opening windows described here: UIAutomation FlaUI - Detect opening windows on application level.
However, I would also like to also detect closing window events in addition to opening window events.
I duplicated the code in order to detect the second event:
AutomationElement root = automation.GetDesktop();
UIA3AutomationEventHandler automationOpenEventHandler = new UIA3AutomationEventHandler(
root.FrameworkAutomationElement,
automation.EventLibrary.Window.WindowOpenedEvent,
HandleOpenEvents);
automation.NativeAutomation.AddAutomationEventHandler(
automation.EventLibrary.Window.WindowOpenedEvent.Id,
root.ToNative(),
(Interop.UIAutomationClient.TreeScope)TreeScope.Descendants,
null,
automationOpenEventHandler);
UIA3AutomationEventHandler automationCloseEventHandler = new UIA3AutomationEventHandler(
root.FrameworkAutomationElement,
automation.EventLibrary.Window.WindowClosedEvent,
HandleCloseEvents);
automation.NativeAutomation.AddAutomationEventHandler(
automation.EventLibrary.Window.WindowClosedEvent.Id,
root.ToNative(),
(Interop.UIAutomationClient.TreeScope)TreeScope.Descendants,
null,
automationCloseEventHandler);
However, only one of the two (I believe the second one declared above) actually works.
Note that if I declare just one of the handlers above, either the open or close, it works fine. I just don't know how to get both going.
Any help would be appreciated!

Detect Win+Tab Task View

On Windows 10, you can press Win+Tab to get a "Task View" view of all your windows. I'm trying to check if this is active at any given time. I have tried using a Low Level Keyboard Hook with WH_KEYBOARD_LL but this only allows me to detect the keypress, not if the switcher is active. I've looked at the Windows DWM API and haven't found anything else either.
I have also tried using EnumWindows() and EnumChildWindows(GetDesktopWindow(), ...) and did not find any difference in the output between having the task view shown and hidden.
Is there any accurate method to detect if this is being shown?
Here's a solution that works very consistently with my version of Windows (1709 build 16299.125) and doesn't require the processor-heavy approach of a call to EnumChildWindows:
bool isTaskView() {
//Get foreground window's name
HWND fgWindow = GetForegroundWindow();
TCHAR windowName[MAX_PATH] = L"";
GetWindowText(fgWindow, windowName, MAX_PATH);
//Compare with magic string name of Task View's window
std::wstring nameStr(windowName);
return nameStr == L"Task View";
}

Add command line option to my WPF application

I want to add command line options to my WPF application but in case command line is sent into my EXE file i don't want the UI open but only command line options.
Is it possible to do something like this ?
public partial class MainWindow : MetroWindow
{
public MainWindow()
{
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
{
this.Hide();
ParseArgs(args);
}
else
{
InitializeComponent();
}
}
private void ParseArgs(string[] args)
{
// bla bla
}
}
You should do this in your app.xaml.
I explain :
You put an application startup method handler(instead of using the startup uri). Here you can parse the cl arguments and then set StartupUri = MainWindow.xaml which will open your window. and if you won't open main window then you don't set startup uri.
This Replacing WPF entry point is what you want to do.
In there you can get the command line arguments and decide if you want to show the main window or not.
If you need to write output that is shown in the command line when the application is run, you need to do something like this :
Right click on the project, "Properties", "Application" tab, change "Output Type" to "Console Application", and then it will also have a console.
However, once you do that then you will have a console window pop up even if you start the application not from a command line. There is no way to have it both ways - either the application is a command line application which can launch a window, or it is a window application which cannot write to the console which started it. It is a limitation in Windows - the bit that decides it is in the PE header.
This question discusses this point in great detail, and offers several hacks to achieve what you want.
You might want to actually search for your problems, because I count at least 5 SO questions dedicated to this (new) topic already.

Focus a window without changing z-order

I have a somewhat hackish utility that sends keystrokes to a window, using SendInput(). That works just fine, however, the target window needs to be a foreground window, so before sending anything, the utility needs to call SetForegroundWindow(). This is annoying from the user's perspective, as the target window flashes to the top (even though the utility immediately switches back to the recent active window, so that the user can continue work).
Is there a way to focus a window, without changing z-order? I realise that it is not a common use case, as it would be extremely frustrating under normal conditions for the user to have a background window active, where they might not even see what they are typing. I tried using both SetFocus() and SetWindowPos() with SWP_NOZORDER, but neither of them actually activates the window.
Note that the window I'm trying to activate is not owned by the calling thread. Also note that I can't use SendMessage() as the keystroke is a CTRL+NUMPAD3 combination and the target window will not react to separate WM_KEYDOWN / WM_KEYUP events, I've tried. It might be relevant that I'm trying to use this on Windows 7.
My code so far is:
HWND h_target = FindWindow(...);
INPUT p_input[2] = {0};
p_input[0].type = INPUT_KEYBOARD;
p_input[0].ki.wVk = VK_CONTROL;
p_input[1].type = INPUT_KEYBOARD;
p_input[1].ki.wVk = VK_NUMPAD3;
// prepare input
HWND h_act = GetForegroundWindow();
// remember this
SetForegroundWindow(h_target); // works
//SetWindowPos(h_target, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); // does not work
// activate the target window first
SendInput(2, p_input, sizeof(INPUT));
// send the keystrokes
p_input[0].ki.dwFlags |= KEYEVENTF_KEYUP;
p_input[1].ki.dwFlags |= KEYEVENTF_KEYUP;
SendInput(2, p_input, sizeof(INPUT));
// don't forget to release the keys
SetForegroundWindow(h_act);
// put the active window back

Open a folder and highlight a particular file with WPF

Is there a way to launch an Explorer window and highlight a file in that folder with WPF ? I've already tried the following :
Process ExplorerWindowProcess = new Process();
ExplorerWindowProcess.StartInfo.FileName = "explorer.exe";
ExplorerWindowProcess.StartInfo.Arguments = ConfigFile.File.FullName;
ExplorerWindowProcess.Start();
... but that opens the file (in my case an XML file) with the default application in Windows Explorer, which I very much don't want. I know that the Aptana tools available for Eclipse allow you the ability to select a file in the Eclipse project browser and show the file in Explorer exactly as I want, but I need a way to implement this in my WPF app.
Explorer Command Line Arguments
http://support.microsoft.com/kb/152457
Explorer [/n] [/e] [(,)/root,<object>] [/select,<object>]
/n Opens a new single-pane window for the default
selection. This is usually the root of the drive Windows
is installed on. If the window is already open, a
duplicate opens.
/e Opens Windows Explorer in its default view.
/root,<object> Opens a window view of the specified object.
/select,<object> Opens a window view with the specified folder, file or
application selected.
You will also want to put quotes around the filename like so:
startInfo.FileName = "explorer.exe";
startInfo.Arguments = "/select,\"" + ConfigFile.File.FullName + "\"";

Resources