I don't actually think that it matters that the window is part of a UWP app, exactly.
You can restore Mail's main window via the Win32 call ShowWindow(hwnd, SW_RESTORE). However, the trick is you have to find the correct window. In Spy++ you can see that it is some window that has a window class "ApplicationFrameWindow" that is associated with the process with module name "APPLICATIONFRAMEHOST" -- these must be artifacts of UWP's implementation.
In order to find the particular "ApplicationFrameWindow" that is Mail's main window, without relying on something mutable or ephemeral like window text, I found that the correct window is the owner of one of the windows associated with the HxOutlook.exe process. There may be a less convoluted to do this but the following works. This is a native command line application obviously:
#include <Windows.h>
#include <psapi.h>
#include <tchar.h>
#include <vector>
DWORD GetProcessByName(const TCHAR* target_process_name)
{
DWORD processes[1024], bytes_returned;
if (!EnumProcesses(processes, sizeof(processes), &bytes_returned))
return 0;
int n = bytes_returned / sizeof(DWORD);
for (int i = 0; i < n; i++) {
auto pid = processes[i];
TCHAR process_name[MAX_PATH] = TEXT("");
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (process) {
HMODULE module;
DWORD bytes_needed;
if (EnumProcessModules(process, &module, sizeof(module), &bytes_needed)) {
GetModuleBaseName(process, module, process_name, sizeof(process_name) / sizeof(TCHAR));
if (_tcscmp(process_name, target_process_name) == 0)
return pid;
}
}
}
return 0;
}
struct HwndFinder {
std::vector<HWND> windows;
DWORD pid;
HwndFinder(DWORD pid) : pid(pid)
{}
};
BOOL CALLBACK EnumWindowsFindProcessWindow(HWND hwnd, LPARAM lParam)
{
DWORD pid;
HwndFinder* param = reinterpret_cast<HwndFinder*>(lParam);
GetWindowThreadProcessId(hwnd, &pid);
if (pid == param->pid) {
param->windows.push_back(hwnd);
}
return TRUE;
}
std::vector<HWND> GetWindowsFromProcessID(DWORD pid)
{
HwndFinder param(pid);
EnumWindows(EnumWindowsFindProcessWindow, reinterpret_cast<LPARAM>(¶m));
return param.windows;
}
int main()
{
auto mail_process = GetProcessByName(TEXT("HxOutlook.exe"));
auto windows = GetWindowsFromProcessID(mail_process);
for (auto window : windows) {
auto owner = GetWindow(window, GW_OWNER);
if (owner)
ShowWindow(owner, SW_RESTORE);
}
return 0;
}
It's finding the process ID for "HxOutlook.exe", enumerating all the windows in which the WNDPROC for the window runs in a thread owned by that process, and then ShowWindow-ing all windows that own those windows, one of which is the main Mail window.
You could do something like the above via platform invoking, or find a simpler way, or put the code above in a DLL and call into it in C# via DLLImport.