When visible the MainWindowHandle is non-zero, after the Window is hidden the handle gets set to 0. I haven't found a way yet to get the required handle - maybe a work around would be to maintain a list of the windows you have hidden.
List<int> HiddenWindows = new List<int>();
private void btnHide_Click(object sender, RoutedEventArgs e)
{
Process[] processRunning = Process.GetProcessesByName(FileName);
foreach (Process pr in processRunning)
{
int hWnd = pr.MainWindowHandle.ToInt32();
if (hWnd == 0)
continue;
ShowWindow(hWnd, SW_HIDE);
HiddenWindows.Add(hWnd);
}
}
private void btnShow_Click(object sender, RoutedEventArgs e)
{
foreach (int hWnd in HiddenWindows)
{
ShowWindow(hWnd, SW_SHOW);
}
HiddenWindows.Clear();
}
NOTE - rather than iterate through all processes returned by GetProcesses - you can use GetProcessesByName just to get the processes you are interested in.
There is an answer here based on other User32 functions - but seems quite complex : Unhide process by its process name?
A quick test with a WPF application showed multiple Window handles found using the code in the linked solution - the answer is to remove the return after the call to ShowWindow. I have added a modified version below to reopen multiple application instances if required.
private const int SW_SHOW = 5;
private String FileName = "notepad";
[DllImport("User32")]
private static extern int ShowWindow(IntPtr hwnd, int nCmdShow);
[DllImport("User32.dll")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string strClassName, string strWindowName);
[DllImport("user32.dll")]
private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int ProcessId);
private void btnShow2_Click(object sender, RoutedEventArgs e)
{
//an array of all processes with name "processName"
Process[] localAll = Process.GetProcessesByName(FileName);
foreach (var pr in localAll)
{
IntPtr hWnd = IntPtr.Zero;
int prcsId = 0;
//check all open windows (not only the process we are looking) begining from the
//child of the desktop, handle = IntPtr.Zero initialy.
do
{
//get child handle of window who's handle is "handle".
hWnd = FindWindowEx(IntPtr.Zero, hWnd, null, null);
GetWindowThreadProcessId(hWnd, out prcsId); //get ProcessId from "handle"
//if it matches what we are looking
//Note there maybe multiple Windows found - so try all of them
if (prcsId == pr.Id)
ShowWindow(hWnd, SW_SHOW); //Show Window
} while (hWnd != IntPtr.Zero);
}
}
NOTE that I have modified the ShowWindow definition to use an IntPtr as the type for the Window handle - this is the preferred type to use & it is the actual type of MainWindowHandle. In your hide method just change the code to
be
IntPtr hWnd = pr.MainWindowHandle;
or the entire loop to
foreach (Process pr in processRunning)
{
ShowWindow(pr.MainWindowHandle, SW_HIDE);
}