从任务栏中隐藏应用程序
Posted
技术标签:
【中文标题】从任务栏中隐藏应用程序【英文标题】:Hiding an application from the taskbar 【发布时间】:2012-01-04 19:51:47 【问题描述】:我一直在努力从我的应用程序的任务栏中隐藏另一个应用程序。
我一直在使用SetWindowLong 函数来设置/删除extended style 上的WS_EX_APPWINDOW
。
我已尝试单独设置和删除该属性以及获取当前的WindowLong
,并将其删除/添加到该属性,如下所示:
SetWindowLong(pMainWindow, GWL_EXSTYLE, GetWindowLong(pMainWindow) & WS_EX_APPWINDOW);
并尝试像这样删除它:
SetWindowLong(pMainWindow, GWL_EXSTYLE, GetWindowLong(pMainWindow) & ~WS_EX_APPWINDOW);
还尝试了这两种方法,但没有先让窗口变长。这是我的完整代码:
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
[DllImport("User32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
[DllImport("User32.dll")]
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
private const int SW_HIDE = 0x00;
private const int SW_SHOW = 0x05;
private const int WS_EX_APPWINDOW = 0x40000;
private const int GWL_EXSTYLE = -0x14;
private void HideWindowFromTaskbar(IntPtr pMainWindow)
SetWindowLong(pMainWindow, GWL_EXSTYLE, ~WS_EX_APPWINDOW);
ShowWindow(pMainWindow, SW_HIDE);
ShowWindow(pMainWindow, SW_SHOW);
private void ButtonHide_Click(object sender, RoutedEventArgs e)
HideWindowFromTaskbar(Process.GetProcessesByName("notepad")[0].MainWindowHandle);
我注意到 Spy++ 在查看属性时发生了变化。我有一堆不同的结果,比如添加了WS_EX_APPWINDOW
,但也随机有其他属性消失,等等。
在查看消息时,我还看到它确实收到了类似STYLE_CHANGED
的消息。
【问题讨论】:
你用 SW_HIDE 试过 SetWindowPlacement 了吗? 我没有,但这不只是隐藏了整个窗口吗?我只想删除它的任务栏栏/项目。 没试过这个,但它看起来可能适合你:alanbondo.wordpress.com/2008/06/22/… “我一直在努力从任务栏中隐藏另一个应用程序”正如我所说,我想隐藏一个不同的应用程序,否则这会起作用。 【参考方案1】:确定哪些窗口在任务栏上有按钮的规则记录在MSDN 上。 Raymond Chen 给出了这些规则的以下summary:
有一些关于哪些窗口进入任务栏的基本规则。在 简短:
如果设置了 WS_EX_APPWINDOW 扩展样式,那么它将显示(可见时)。 如果窗口是顶层无主窗口,那么它将显示(可见时)。 否则不显示。
您正在尝试修改另一个应用程序中的窗口这一事实严重阻碍了您。您正在删除 WS_EX_APPWINDOW
扩展样式。这还不够,因为有问题的窗口将是一个***的无主窗口(参见要点 2)。一旦创建了窗口,您就无法更改它的所有者,并且由于该窗口是由另一个进程控制的,因此您几乎被卡住了。
剩下的唯一选择是删除 WS_EX_APPWINDOW
扩展样式并将其替换为 WS_EX_TOOLWINDOW
。这确实会使窗口离开任务栏,但它会改变appearance of the window:
该窗口旨在用作浮动工具栏。一个工具窗口 有一个比普通标题栏短的标题栏,并且 窗口标题使用较小的字体绘制。工具窗口不 出现在任务栏或用户访问时出现的对话框中 按 ALT+TAB。如果一个工具窗口有一个系统菜单,它的图标不是 显示在标题栏上。但是,您可以显示系统菜单 通过右键单击或键入 ALT+SPACE。
【讨论】:
P.S.我想知道当您在自己的应用程序上将 ShowInTaskbar 设置为 false 时它是如何工作的。 我认为它重新创建了所有者更改的窗口 啊哈!有趣的!也许我需要通过发送这样的消息来通知窗口类似的事情。 没有机会。另一个应用程序创建窗口并确定所有权。 也许我在这里误解了,但是您可以在创建窗口后更改它的所有者,即使它是另一个进程中的窗口 - 试试吧,它可以工作。这将从任务栏/ alt+tab 中删除窗口。【参考方案2】:这是我的做法。
1. Create a window (hwndOwner) with WS_POPUP style and WS_EX_TOOLWINDOW
2. Call SetWindowLong(hwnd, GWL_HWNDPARENT, hwndOwner)
3. Call SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | ~WS_EX_APPWINDOW)
这将从任务栏和 alt 选项卡中删除目标窗口。这至少适用于自 WS2000 以来的每个操作系统。
现在,David Heffernan 指出 MSDN 文档说您不能这样做。嗯,我不知道它为什么这么说,但它不准确。您可以这样做,INFACT .NET Framework 会这样做,只需使用 .NET Reflector 检查 System.Windows.Forms.Form.Owner 属性的代码 - 它使用 SetWindowLong 随时转移所有权!
对于不正确的 MSDN 文档的更多证据,只需查看 Owner property 的文档,它说“***窗口不能拥有所有者”。它应该与此完全相反,只有***窗口才能拥有所有者!
【讨论】:
@MathiasLykkegaardLorenzen 你能详细说明一下,究竟是什么不正确?【参考方案3】:private const int SW_HIDE = 0x00;
private const int SW_SHOW = 0x05;
private const int WS_EX_APPWINDOW = 0x40000;
private const int GWL_EXSTYLE = -0x14;
private const int WS_EX_TOOLWINDOW = 0x0080;
private static void HideAppinTaskBar()
var Handle = FindWindowByCaption(IntPtr.Zero, "Untitled - Notepad");
ShowWindow(Handle, SW_HIDE);
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) | WS_EX_TOOLWINDOW);
ShowWindow(Handle, SW_SHOW);
这对我有用 - 用记事本测试过。 WinXp 32 位机。
【讨论】:
使其成为工具窗口还有其他含义。理想情况下,您需要拥有该窗口才能使其脱离任务栏。 我同意不理想 - 我从这里提出的一个德尔福问题移植了这个。 谢谢,它至少在我正在寻找的地方附近,但我仍在寻找更好的方法。【参考方案4】:这适用于 WinUI3 和 .NET 6.0 上的 PInvoke.User32 nuget 包:
改编自 Alex 的回答。
private void HideAppFromTaskBar(MainWindow window)
//Get the Window's HWND
var windowNative = window.As<IWindowNative>();
var windowHandle = windowNative.WindowHandle;
User32.ShowWindow(windowHandle, User32.WindowShowStyle.SW_HIDE);
var flags = (User32.SetWindowLongFlags)User32.GetWindowLong(windowHandle, User32.WindowLongIndexFlags.GWL_EXSTYLE);
User32.SetWindowLong(windowHandle, User32.WindowLongIndexFlags.GWL_EXSTYLE, flags | User32.SetWindowLongFlags.WS_EX_TOOLWINDOW);
User32.ShowWindow(windowHandle, User32.WindowShowStyle.SW_SHOW);
【讨论】:
以上是关于从任务栏中隐藏应用程序的主要内容,如果未能解决你的问题,请参考以下文章