下面是我的代码。在这里您可以看到我使用常量来隐藏/显示窗口。在C#.net中的另一个应用程序中隐藏另一个应用程序。
private const int SW_HIDE = 0;
private const int SW_SHOW = 5;
[DllImport("User32")]
private static extern int ShowWindow(int hwnd, int nCmdShow);
private void btnHide_Click(object sender, EventArgs e){
Process[] processRunning = Process.GetProcesses();
foreach (Process pr in processRunning){
if (pr.ProcessName == FileName){
hWnd = pr.MainWindowHandle.ToInt32();
ShowWindow(hWnd, SW_HIDE);
}
}
}
private void btnShow_Click(object sender, EventArgs e){
Process[] processRunning = Process.GetProcesses();
foreach (Process pr in processRunning){
if (pr.ProcessName == FileName){
hWnd = pr.MainWindowHandle.ToInt32();
ShowWindow(hWnd, SW_SHOW);
}
}
}
答案 0 :(得分:1)
当可见的MainWindowHandle不为零时,在隐藏窗口之后,将句柄设置为0。我还没有找到获取所需句柄的方法-可能的解决方法是维护列表隐藏的窗户。
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();
}
注意-您可以使用GetProcessesByName来获取您感兴趣的进程,而不是遍历GetProcesses返回的所有进程。
这里有一个基于其他User32函数的答案-但看起来很复杂:Unhide process by its process name?
使用WPF应用程序进行的快速测试显示,使用链接的解决方案中的代码找到了多个Window句柄-答案是删除对ShowWindow的调用后的返回值。我在下面添加了修改后的版本,以便在需要时重新打开多个应用程序实例。
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);
}
}
请注意,我已经修改了ShowWindow定义以将IntPtr用作Window句柄的类型-这是首选的类型,并且它是MainWindowHandle的实际类型。在您的hide方法中,只需将代码更改为 是
IntPtr hWnd = pr.MainWindowHandle;
或整个循环
foreach (Process pr in processRunning)
{
ShowWindow(pr.MainWindowHandle, SW_HIDE);
}
答案 1 :(得分:0)
Process.GetProcess()
的工作方式。
隐藏进程的主窗口后,其MainWindowHandle
的下一次迭代将变为IntPtr.Zero
。我猜这与如何检索MainWindowHandle
有关。
解决方案:
hWnd
(例如,在Dictionary<string, int>
中)并调用ShowWindow()
,而无需再次检索进程。