找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 3588|回复: 6

[问题求助] PowerShell模拟点击指定标题的命令行窗口上的关闭按钮

[复制链接]
发表于 2025-6-24 10:10:49 | 显示全部楼层 |阅读模式
我想用powershell代码实现, 模拟点击指定标题文本的命令行窗口上的右上角的关闭按钮, 这能实现吗?

用gpt实现了,
  1. Add-Type @"
  2. using System;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. public class Win32 {
  6.     [DllImport("user32.dll", SetLastError=true)]
  7.     public static extern int EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
  8.     public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);

  9.     [DllImport("user32.dll", SetLastError=true)]
  10.     public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

  11.     [DllImport("user32.dll", SetLastError=true)]
  12.     public static extern int GetWindowTextLength(IntPtr hWnd);

  13.     [DllImport("user32.dll", SetLastError=true)]
  14.     public static extern bool IsWindowVisible(IntPtr hWnd);

  15.     [DllImport("user32.dll", SetLastError=true)]
  16.     public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
  17. }
  18. "@

  19. $WM_CLOSE = 0x0010
  20. $target = "__888__"

  21. [Win32+EnumWindowsProc]$callback = {
  22.     param($hWnd, $lParam)
  23.     if ([Win32]::IsWindowVisible($hWnd)) {
  24.         $length = [Win32]::GetWindowTextLength($hWnd)
  25.         if ($length -gt 0) {
  26.             $builder = New-Object System.Text.StringBuilder $length
  27.             [Win32]::GetWindowText($hWnd, $builder, $length + 1) | Out-Null
  28.             $title = $builder.ToString()
  29.             if ($title -eq $target) {
  30.                 [Win32]::PostMessage($hWnd, $WM_CLOSE, 0, 0) | Out-Null
  31.                 Write-Host "已关闭窗口:$title"
  32.             }
  33.         }
  34.     }
  35.     return $true
  36. }

  37. [Win32]::EnumWindows($callback, [IntPtr]::Zero)
复制代码
发表于 2025-6-24 11:15:43 | 显示全部楼层
gpt的代码向窗口传递关闭的消息 比模拟点击高级不少  
__888__应该改为你要关闭的窗口名
 楼主| 发表于 2025-6-24 12:14:34 | 显示全部楼层
回复 2# jyswjjgdwtdtj

对,
现在有个问题, 有时要点多次关闭按钮才可以完全关上, 然后让gpt改就成功不了了, 求路过大佬指导
发表于 2025-6-24 12:26:26 | 显示全部楼层
回复 3# 小白龙
  1. Add-Type @"
  2. using System;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. public class Win32 {
  6.     [DllImport("user32.dll", SetLastError=true)]
  7.     public static extern int EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
  8.     public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
  9.     [DllImport("user32.dll", SetLastError=true)]
  10.     public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
  11.     [DllImport("user32.dll", SetLastError=true)]
  12.     public static extern int GetWindowTextLength(IntPtr hWnd);
  13.     [DllImport("user32.dll", SetLastError=true)]
  14.     public static extern bool IsWindowVisible(IntPtr hWnd);
  15.     [DllImport("user32.dll", SetLastError=true)]
  16.     public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
  17.     [DllImport("user32.dll", SetLastError=true)]
  18.     public static extern bool IsWindow(IntPtr hWnd);
  19. }
  20. "@

  21. $WM_CLOSE = 0x0010
  22. $target = "__888__"

  23. # 函数:检查窗口是否存在
  24. function Test-WindowExists {
  25.     param($windowTitle)
  26.     $exists = $false
  27.     [Win32+EnumWindowsProc]$checkCallback = {
  28.         param($hWnd, $lParam)
  29.         if ([Win32]::IsWindowVisible($hWnd)) {
  30.             $length = [Win32]::GetWindowTextLength($hWnd)
  31.             if ($length -gt 0) {
  32.                 $builder = New-Object System.Text.StringBuilder $length
  33.                 [Win32]::GetWindowText($hWnd, $builder, $length + 1) | Out-Null
  34.                 $title = $builder.ToString()
  35.                 if ($title -eq $windowTitle) {
  36.                     $exists = $true
  37.                     return $false # 停止枚举
  38.                 }
  39.             }
  40.         }
  41.         return $true
  42.     }
  43.     [Win32]::EnumWindows($checkCallback, [IntPtr]::Zero) | Out-Null
  44.     return $exists
  45. }

  46. # 主关闭逻辑
  47. do {
  48.     $windowFound = $false
  49.     [Win32+EnumWindowsProc]$callback = {
  50.         param($hWnd, $lParam)
  51.         if ([Win32]::IsWindowVisible($hWnd)) {
  52.             $length = [Win32]::GetWindowTextLength($hWnd)
  53.             if ($length -gt 0) {
  54.                 $builder = New-Object System.Text.StringBuilder $length
  55.                 [Win32]::GetWindowText($hWnd, $builder, $length + 1) | Out-Null
  56.                 $title = $builder.ToString()
  57.                 if ($title -eq $target) {
  58.                     $windowFound = $true
  59.                     [Win32]::PostMessage($hWnd, $WM_CLOSE, 0, 0) | Out-Null
  60.                     Write-Host "尝试关闭窗口:$title"
  61.                 }
  62.             }
  63.         }
  64.         return $true
  65.     }
  66.     [Win32]::EnumWindows($callback, [IntPtr]::Zero) | Out-Null
  67.    
  68.     if ($windowFound) {
  69.         # 等待一会儿让窗口有机会关闭
  70.         Start-Sleep -Milliseconds 500
  71.     } else {
  72.         Write-Host "未找到目标窗口,退出循环"
  73.         break
  74.     }
  75. } while (Test-WindowExists -windowTitle $target)

  76. Write-Host "操作完成"
复制代码

评分

参与人数 1技术 +1 收起 理由
小白龙 + 1 乐于助人

查看全部评分

 楼主| 发表于 2025-6-24 13:22:32 | 显示全部楼层
回复 4# yakeyun


    多谢, 好像可以了, 稍后我多试试
 楼主| 发表于 2025-6-24 16:48:39 | 显示全部楼层
回复 4# yakeyun

我稍微改了一下代码, 改成了关闭标题文本以 __888__ 开头的窗口,

刚试了一下, 还是不行, 代码执行完, 有很大机率, 窗口仍然没关闭
  1. Add-Type @"
  2. using System;
  3. using System.Text;
  4. using System.Runtime.InteropServices;
  5. public class Win32 {
  6.     [DllImport("user32.dll", SetLastError=true)]
  7.     public static extern int EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
  8.     public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
  9.     [DllImport("user32.dll", SetLastError=true)]
  10.     public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
  11.     [DllImport("user32.dll", SetLastError=true)]
  12.     public static extern int GetWindowTextLength(IntPtr hWnd);
  13.     [DllImport("user32.dll", SetLastError=true)]
  14.     public static extern bool IsWindowVisible(IntPtr hWnd);
  15.     [DllImport("user32.dll", SetLastError=true)]
  16.     public static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
  17.     [DllImport("user32.dll", SetLastError=true)]
  18.     public static extern bool IsWindow(IntPtr hWnd);
  19. }
  20. "@

  21. $WM_CLOSE = 0x0010
  22. $target = "__888__"

  23. # 函数:检查窗口是否存在
  24. function Test-WindowExists {
  25.     param($windowTitle)
  26.     $exists = $false
  27.     [Win32+EnumWindowsProc]$checkCallback = {
  28.         param($hWnd, $lParam)
  29.         if ([Win32]::IsWindowVisible($hWnd)) {
  30.             $length = [Win32]::GetWindowTextLength($hWnd)
  31.             if ($length -gt 0) {
  32.                 $builder = New-Object System.Text.StringBuilder $length
  33.                 [Win32]::GetWindowText($hWnd, $builder, $length + 1) | Out-Null
  34.                 $title = $builder.ToString()
  35.                 if ($title.StartsWith($windowTitle)) {
  36.                     $exists = $true
  37.                     return $false # 停止枚举
  38.                 }
  39.             }
  40.         }
  41.         return $true
  42.     }
  43.     [Win32]::EnumWindows($checkCallback, [IntPtr]::Zero) | Out-Null
  44.     return $exists
  45. }

  46. # 主关闭逻辑
  47. do {
  48.     $windowFound = $false
  49.     [Win32+EnumWindowsProc]$callback = {
  50.         param($hWnd, $lParam)
  51.         if ([Win32]::IsWindowVisible($hWnd)) {
  52.             $length = [Win32]::GetWindowTextLength($hWnd)
  53.             if ($length -gt 0) {
  54.                 $builder = New-Object System.Text.StringBuilder $length
  55.                 [Win32]::GetWindowText($hWnd, $builder, $length + 1) | Out-Null
  56.                 $title = $builder.ToString()
  57.                 if ($title.StartsWith($target)) {
  58.                     $windowFound = $true
  59.                     [Win32]::PostMessage($hWnd, $WM_CLOSE, 0, 0) | Out-Null
  60.                     Write-Host "尝试关闭窗口:$title"
  61.                 }
  62.             }
  63.         }
  64.         return $true
  65.     }
  66.     [Win32]::EnumWindows($callback, [IntPtr]::Zero) | Out-Null
  67.    
  68.     if ($windowFound) {
  69.         # 等待一会儿让窗口有机会关闭
  70.         Start-Sleep -Milliseconds 500
  71.     } else {
  72.         Write-Host "未找到目标窗口,退出循环"
  73.         break
  74.     }
  75. } while (Test-WindowExists -windowTitle $target)
复制代码
发表于 2025-6-24 22:25:28 | 显示全部楼层
根本就不能通用
对于关闭窗口 ,不同程序有不同的决策 ,而且还可能有状态
有的关闭窗口直接退出
有的关闭窗口提示是否退出
有的关闭窗口弹窗新的窗口 ,操作新窗口才能关闭
有的提示或窗口点击是才关闭 ,关闭是取消关闭
有点提示或窗口点击否才关闭 ,关闭是取消关闭
有的根据程序运行状态才关闭
.......
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-17 02:30 , Processed in 0.018673 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表