前段时间我写了一段代码来隐藏/恢复进程窗口,我所做的是这样的:
隐藏进程:
1)在正在运行的进程中查找进程名。
2) 将 MainWindowHandle 添加到容器(在本例中为字典),这对于稍后取消隐藏该进程是必要的。
3) 使用ShowWindow API函数隐藏进程。
要取消隐藏进程:
1)在正在运行的进程中查找进程名。
2) 从容器中检索指定进程保存的MainWindowHandle。
3) 使用ShowWindow API函数取消隐藏进程。
为什么我使用字典来取消隐藏进程?因为隐藏进程有一个MainWindowHandle
零值0
,所以这是我发现检索正确句柄以在ShowWindow
功能来恢复进程。
但我真的不想依赖Hide
保存所需的方法HWND在隐藏进程之前,我想通过了解如何执行取消隐藏操作来改进这一切VB.NET or C#仅通过指定进程名称(例如:cmd.exe)之前不保存MainWindowHandle
,这可以吗?
我展示了代码(在 VB.NET 中),让您了解我对 HideProcess 方法做了什么:
但请注意,这段代码与问题并不完全相关,我的问题是如何仅通过指定进程名称来取消隐藏隐藏进程以避免下面编写的代码需要检索已保存的句柄来取消隐藏进程。
' 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