Show a process by its process name?
From time to time I wrote some code to hide / restore the process window, which I did:
Hide process:
1) Find the process name in running processes.
2) Add MainWindowHandle to a container (in this case a dictionary), this will need to be displayed later.
3) Hide the process using the ShowWindow API function.
To display a process:
1) Find the process name in running processes.
2) Retrieve the saved MainWindowHandle of the specified process from the container.
3) Show the process using the ShowWindow API function.
Why am I using a dictionary to display the process? Well, because the hidden process has a value MainWindowHandle
for Zero 0
, so this is the only way to find the correct handle to use ShowWindow
to recover the process.
But I really don't want to depend on the method Hide
that saves the required HWND before hiding the process, I would like to improve the whole thing by knowing how to perform a hidden operation in VB.NET or C # by only specifying the process name (ex: cmd.exe ) without saving before MainWindowHandle
, is it possible?
I am showing the code (in VB.NET) to give you an idea of what I did for the HideProcess method:
But please note that this code is not completely relevant in the question, my question is how to display a hidden process, only by specifying the process name , to avoid the code written below, which has to get the stored handle to display the process.
' Hide-Unhide Process ' ' Usage Examples : ' ' HideProcess(Process.GetCurrentProcess().MainModule.ModuleName) ' HideProcess("notepad.exe", Recursivity:=False) ' HideProcess("notepad", Recursivity:=True) ' ' UnhideProcess(Process.GetCurrentProcess().MainModule.ModuleName) ' UnhideProcess("notepad.exe", Recursivity:=False) ' UnhideProcess("notepad", Recursivity:=True) Private ProcessHandles As New Dictionary(Of String, IntPtr) <System.Runtime.InteropServices.DllImport("User32")> Private Shared Function ShowWindow(ByVal hwnd As IntPtr, ByVal nCmdShow As Integer) As Integer End Function Private Sub HideProcess(ByVal ProcessName As String, Optional ByVal Recursivity As Boolean = False) If ProcessName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) Then ProcessName = ProcessName.Remove(ProcessName.Length - ".exe".Length) End If Dim Processes() As Process = Process.GetProcessesByName(ProcessName) Select Case Recursivity Case True For Each p As Process In Processes ProcessHandles.Add(String.Format("{0};{1}", ProcessName, CStr(p.Handle)), p.MainWindowHandle) ShowWindow(p.MainWindowHandle, 0) Next p Case Else If Not (Processes.Count = 0) AndAlso Not (Processes(0).MainWindowHandle = 0) Then Dim p As Process = Processes(0) ProcessHandles.Add(String.Format("{0};{1}", ProcessName, CStr(p.Handle)), p.MainWindowHandle) ShowWindow(p.MainWindowHandle, 0) End If End Select End Sub Private Sub UnhideProcess(ByVal ProcessName As String, Optional ByVal Recursivity As Boolean = False) If ProcessName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) Then ProcessName = ProcessName.Remove(ProcessName.Length - ".exe".Length) End If Dim TempHandles As New Dictionary(Of String, IntPtr) For Each Handle As KeyValuePair(Of String, IntPtr) In ProcessHandles TempHandles.Add(Handle.Key, Handle.Value) Next Handle For Each Handle As KeyValuePair(Of String, IntPtr) In TempHandles If Handle.Key.ToLower.Contains(ProcessName.ToLower) Then ShowWindow(Handle.Value, 9) ProcessHandles.Remove(Handle.Key) If Recursivity Then Exit For End If End If Next Handle End Sub
source to share
code:
using System.Diagnostics;
using System.Runtime.InteropServices;
[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 const int SW_RESTORE = 9;
private void UnhideProcess(string processName) //Unhide Process
{
IntPtr handle = IntPtr.Zero;
int prcsId = 0;
//an array of all processes with name "processName"
Process[] localAll = Process.GetProcessesByName(processName);
//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 handle is "handle".
handle = FindWindowEx(IntPtr.Zero, handle, null, null);
GetWindowThreadProcessId(handle, out prcsId); //get ProcessId from "handle"
//if it matches what we are looking
if (prcsId == localAll[0].Id)
{
ShowWindow(handle, SW_RESTORE); //Show Window
return;
}
} while (handle != IntPtr.Zero);
}
If instances with the same name you can use variable eg count and increment it in if statement
int count = 0;
if (prcsId == localAll[count].Id)
{
ShowWindow(handle, SW_RESTORE);
count++;
}
The difference between FindWindowEx () and Process.MainWindowHandle () could be where each function looks for handles. FindWindowEx () looks everywhere, unlike MainWindowHandle. Also, the process handle is denoted as HANDLE, and the window as HWND
source to share
I wrote this solution for vb.net, thanks to @ γηράσκω δ 'αεί πολλά διδασκόμε
<System.Runtime.InteropServices.DllImport("User32")>
Private Shared Function ShowWindow(
ByVal hwnd As IntPtr,
ByVal nCmdShow As Integer
) As Integer
End Function
<System.Runtime.InteropServices.DllImport("User32.dll")>
Private Shared Function FindWindowEx(
ByVal hwndParent As IntPtr,
ByVal hwndChildAfter As IntPtr,
ByVal strClassName As String,
ByVal strWindowName As String
) As IntPtr
End Function
<System.Runtime.InteropServices.DllImport("user32.dll")>
Private Shared Function GetWindowThreadProcessId(
ByVal hWnd As IntPtr,
ByRef ProcessId As Integer
) As Integer
End Function
Public Enum WindowState As Integer
''' <summary>
''' Hides the window and activates another window.
''' </summary>
Hide = 0I
''' <summary>
''' Activates and displays a window.
''' If the window is minimized or maximized, the system restores it to its original size and position.
''' An application should specify this flag when displaying the window for the first time.
''' </summary>
Normal = 1I
''' <summary>
''' Activates the window and displays it as a minimized window.
''' </summary>
ShowMinimized = 2I
''' <summary>
''' Maximizes the specified window.
''' </summary>
Maximize = 3I
''' <summary>
''' Activates the window and displays it as a maximized window.
''' </summary>
ShowMaximized = Maximize
''' <summary>
''' Displays a window in its most recent size and position.
''' This value is similar to <see cref="WindowVisibility.Normal"/>, except the window is not actived.
''' </summary>
ShowNoActivate = 4I
''' <summary>
''' Activates the window and displays it in its current size and position.
''' </summary>
Show = 5I
''' <summary>
''' Minimizes the specified window and activates the next top-level window in the Z order.
''' </summary>
Minimize = 6I
''' <summary>
''' Displays the window as a minimized window.
''' This value is similar to <see cref="WindowVisibility.ShowMinimized"/>, except the window is not activated.
''' </summary>
ShowMinNoActive = 7I
''' <summary>
''' Displays the window in its current size and position.
''' This value is similar to <see cref="WindowVisibility.Show"/>, except the window is not activated.
''' </summary>
ShowNA = 8I
''' <summary>
''' Activates and displays the window.
''' If the window is minimized or maximized, the system restores it to its original size and position.
''' An application should specify this flag when restoring a minimized window.
''' </summary>
Restore = 9I
''' <summary>
''' Sets the show state based on the SW_* value specified in the STARTUPINFO structure
''' passed to the CreateProcess function by the program that started the application.
''' </summary>
ShowDefault = 10I
''' <summary>
''' <b>Windows 2000/XP:</b>
''' Minimizes a window, even if the thread that owns the window is not responding.
''' This flag should only be used when minimizing windows from a different thread.
''' </summary>
ForceMinimize = 11I
End Enum
Private Sub SetWindowState(ByVal ProcessName As String,
ByVal WindowState As WindowState,
Optional ByVal Recursivity As Boolean = False)
If ProcessName.EndsWith(".exe", StringComparison.OrdinalIgnoreCase) Then
ProcessName = ProcessName.Remove(ProcessName.Length - ".exe".Length)
End If
Dim pHandle As IntPtr = IntPtr.Zero
Dim pID As Integer = 0I
Dim Processes As Process() = Process.GetProcessesByName(ProcessName)
' If any process matching the name is found then...
If Processes.Count = 0 Then
Exit Sub
End If
For Each p As Process In Processes
Do Until pID = p.Id ' Check all windows.
' Get child handle of window who handle is "pHandle".
pHandle = FindWindowEx(IntPtr.Zero, pHandle, Nothing, Nothing)
' Get ProcessId from "pHandle".
GetWindowThreadProcessId(pHandle, pID)
' If the ProcessId matches the "pID" then...
If pID = p.Id Then
ShowWindow(pHandle, WindowState)
If Not Recursivity Then
Exit For
End If
End If
Loop
Next p
End Sub
source to share