Ele*_*ios 3 c# vb.net winapi process winforms
前段时间我写了一个代码来隐藏/恢复进程窗口,我所做的是:
隐藏进程:
1) 在正在运行的进程中查找进程名称。
2) 将 MainWindowHandle 添加到容器(在本例中为字典),这对于稍后取消隐藏该过程是必要的。
3) 使用 ShowWindow API 函数隐藏进程。
取消隐藏进程:
1) 在正在运行的进程中查找进程名称。
2)从容器中检索保存的指定进程的MainWindowHandle。
3) 使用 ShowWindow API 函数取消隐藏进程。
为什么我使用字典来取消隐藏进程?嗯,因为 Hidden 进程的MainWindowHandle
值为 Zero 0
,所以这是我发现检索正确句柄以在ShowWindow
函数中使用以恢复进程的唯一方法。
但我真的不想依赖于在隐藏进程之前Hide
保存所需HWND的方法,我想通过知道如何在VB.NET或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
Run Code Online (Sandbox Code Playgroud)
代码:
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's 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);
}
Run Code Online (Sandbox Code Playgroud)
如果有更多同名的实例,您可以使用一个变量,例如count并在if 语句中增加它
int count = 0;
if (prcsId == localAll[count].Id)
{
ShowWindow(handle, SW_RESTORE);
count++;
}
Run Code Online (Sandbox Code Playgroud)
FindWindowEx()和Process.MainWindowHandle()之间的区别可能是每个函数寻找句柄的地方。与MainWindowHandle不同,FindWindowEx()到处寻找。一个进程句柄被称为HANDLE,一个窗口被称为HWND