【问题标题】:Close explorer window created from Java关闭从 Java 创建的资源管理器窗口
【发布时间】:2014-05-07 06:10:19
【问题描述】:

我在 java 中使用

启动一个资源管理器窗口
ProcessBuilder pb = new ProcessBuilder("explorer.exe",folderToOpen);
Process p = pb.start();

在我的 java 程序存在之前,我想关闭这个窗口。 这很重要,因为这个文件夹实际上是一个虚拟文件夹。 该文件夹是使用用于创建内核级虚拟文件系统的 java 库创建的。 当程序存在时,该文件夹不再存在。 Windows 资源管理器没有意识到这一点,并不断显示许多错误消息。 只有当用户关闭虚拟文件夹的资源管理器窗口时,这些错误消息才会停止。

为了更好的用户体验,我需要在退出时自动关闭这个虚拟文件夹。

explorer.exe 的问题在于,它不会在使用的实例中打开新窗口 发送命令。窗口在另一个进程中打开。所以我没有手柄 进程,所以我无法关闭它。

我尝试了 JNA 路由,但这引发了系统错误代码 5(表示访问被拒绝)

final String folderName = Paths.get(super.path).getFileName().toString();
final WinDef.HWND[] windowHandle = new WinDef.HWND[1];
User32.INSTANCE.EnumWindows(new WinUser.WNDENUMPROC() {
 @Override
 public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
 char[]c = new char[255];
 User32.INSTANCE.GetWindowText(hwnd, c, 250);
 String s = new String(c).trim();
 System.out.println(s);
  if (s.equals(folderName)) {
  windowHandle[0] = hwnd;
  User32.INSTANCE.DestroyWindow(hwnd);
  System.out.println(Kernel32.INSTANCE.GetLastError());
  return false;
    }
   return true;
  }
}, Pointer.NULL);

任何建议、cmets、技巧、指南、想法、提示? 谢谢:D

更新: 这似乎可行,但是,风险在于它可能会关闭类似的窗口(名称与我要关闭的窗口相同的窗口)。这将是不好的副作用。

final String folderName = Paths.get(super.path).getFileName().toString();
User32.INSTANCE.EnumWindows(new WinUser.WNDENUMPROC() {
 @Override
 public boolean callback(WinDef.HWND hwnd, Pointer pointer) {
  char[]c = new char[255];
  User32.INSTANCE.GetWindowText(hwnd, c, 250);
  String s = new String(c).trim();
  System.out.println(s);
  if (s.equals(folderName)) {
   User32.INSTANCE.PostMessage(hwnd,User32.WM_CLOSE,null,null);
   System.out.println(Kernel32.INSTANCE.GetLastError());
   return false;
  }
  return true;
 }
}, Pointer.NULL);

有人有更好的主意吗? 再次感谢:D

【问题讨论】:

  • 您是否尝试过使用Process#destroy
  • 请求系统管理员授予您访问权限。
  • @RomanC 我无法询问系统管理员,它可能在我的系统上工作,但我需要在可能没有此权限的用户系统上工作。
  • @MadProgrammer 我试过了,它不起作用。实际打开窗口的过程不同。

标签: java windows winapi jna explorer


【解决方案1】:

使用destroy(),如Process所示。

所以使用p.destroy();

【讨论】:

  • 那行不通。因为我拥有它的进程句柄与打开窗口的进程不同。 Windows 资源管理器是一个有限的实例程序。它控制运行的实例数。我调用来打开窗口的进程导致窗口在另一个资源管理器进程中打开,并且它存在。所以销毁一个已经死掉的进程是没有用的。
猜你喜欢
  • 1970-01-01
  • 2017-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 2020-01-26
相关资源
最近更新 更多