Time ago I written a code to hide/restore a process window, what I did is this:
To Hide a process:
1) Find the process name in the running processes.
2) Add the MainWindowHandle to a Container (a Dictionary in this case), this would be necessary to unhide that process later.
3) Hide the process using ShowWindow API function.
To unhide a process:
1) Find the process name in the running processes.
2) Retrieve the saved MainWindowHandle of the specified process from the container.
3) Unhide the process using ShowWindow API function.
Why I use a dictionary to unhide the process?, well, because a Hidden process have a MainWindowHandle
value of Zero 0
, so that is the only way that I found to retrieve the proper handle to use in the ShowWindow
function to restore the process.
But I really don't want to depend on the Hide
method that saves the required HWND before hidding the process, I would like to improve all this by knowing how to perform an unhide operation in VB.NET or C# only by specifying the process name (eg: cmd.exe) without saving before the MainWindowHandle
, this is possible to do?
I show 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 fully relevant in the question, my question is how to unhide a hidden process only by specifying the process name to avoid the code written below that needs to retrieve a saved handle to unhide a 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