C#从任务栏隐藏应用程序

我一直在努力从应用程序中隐藏任务栏中的另一个应用程序。
我一直在使用SetWindowLong函数来设置/删除扩展样式上的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,但也随机地让其他属性消失等等。
在查看消息时,我还看到DID收到STYLE_CHANGED等消息。

任何帮助,将不胜感激,
勒内

MSDN上记录了确定哪些窗口在任务栏上有按钮的规则。 Raymond Chen给出了以下这些规则的摘要 :

窗口进入任务栏有一些基本规则。 简而言之:

  • 如果设置了WS_EX_APPWINDOW扩展样式,那么它将显示(当可见时)。
  • 如果窗口是顶级无主窗口,则它将显示(当可见时)。
  • 否则它没有显示。

您尝试修改另一个应用程序中的窗口这一事实严重阻碍了您。 您正在删除WS_EX_APPWINDOW扩展样式。 这还不够,因为有问题的窗口将是一个顶层的无主窗口(见第2点)。 创建窗口后,您无法更改窗口的所有者,并且由于窗口由另一个窗口控制,您几乎卡住了。

剩下的唯一选择是删除WS_EX_APPWINDOW扩展样式并将其替换为WS_EX_TOOLWINDOW 。 这确实会使窗口脱离任务栏,但它会改变窗口的外观 :

该窗口旨在用作浮动工具栏。 工具窗口的标题栏比普通标题栏短,窗口标题使用较小的字体绘制。 当用户按下ALT + TAB时,工具窗口不会出现在任务栏或对话框中。 如果工具窗口具有系统菜单,则其图标不会显示在标题栏上。 但是,您可以通过右键单击或键入ALT + SPACE来显示系统菜单。

我是这样做的。

 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文档的更多证据,请查看所有者属性的文档,它说“顶级窗口不能拥有所有者”。 它应该与此完全相反,只有顶级窗户可以拥有一个!

 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位机器。

有关您正在尝试执行的操作的详细信息,请参阅此StackOverflow答案的已接受答案。 请特别注意有关安全性和线程的警告。