首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过Powershell中的进程获取所有窗口句柄?

如何通过Powershell中的进程获取所有窗口句柄?
EN

Stack Overflow用户
提问于 2014-08-18 17:55:46
回答 1查看 29.8K关注 0票数 10

我有这个剧本

代码语言:javascript
运行
复制
Get-Process | Where-Object {$_.MainWindowTitle -like "*total*"}  

产生这些信息的

代码语言:javascript
运行
复制
Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName                                                                     
-------  ------    -----      ----- -----   ------     -- -----------                                                                     
    362      23    19432      32744   324     3.86   6880 TotalCmd64                                                                      

所以我有进程ID。

*Total*应用程序本身有许多打开的窗口。

问题

我如何迭代(使用powershell)遍历它的所有窗口(这样我就可以获得它们的窗口句柄)?

注:我的目标是什么?

查看(例如) Visual :我正在运行应用程序。

但是应用程序有自己的打开窗口。

我希望子窗口是TOPMOsT。我已经有了制作最上面窗口的脚本。但我需要它的手柄号码。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-25 10:40:59

首先,您应该查看WASP,看看它是否适合您的需要:http://wasp.codeplex.com/

其次,我在这里找到了修改过的代码-- http://social.technet.microsoft.com/Forums/windowsserver/en-US/c3cd3982-ffc5-4c17-98fc-a09c555e121c/get-all-child-window-titles?forum=winserverpowershell

若要创建一个函数,该函数将以MainWindowHandle作为输入,并向您提供一个带有子句柄It的对象(如果有的话,它还将列出任何窗口标题)。

我希望这些方法中的一种能够满足您的需要:)

代码语言:javascript
运行
复制
function Get-ChildWindow{
[CmdletBinding()]
param (
    [Parameter(ValueFromPipeline = $true, ValueFromPipelinebyPropertyName = $true)]
    [ValidateNotNullorEmpty()]
    [System.IntPtr]$MainWindowHandle
)

BEGIN{
    function Get-WindowName($hwnd) {
        $len = [apifuncs]::GetWindowTextLength($hwnd)
        if($len -gt 0){
            $sb = New-Object text.stringbuilder -ArgumentList ($len + 1)
            $rtnlen = [apifuncs]::GetWindowText($hwnd,$sb,$sb.Capacity)
            $sb.tostring()
        }
    }

    if (("APIFuncs" -as [type]) -eq $null){
        Add-Type  @"
        using System;
        using System.Runtime.InteropServices;
        using System.Collections.Generic;
        using System.Text;
        public class APIFuncs
          {
            [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString, int cch);

            [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
            public static extern IntPtr GetForegroundWindow();

            [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
            public static extern Int32 GetWindowThreadProcessId(IntPtr hWnd,out Int32 lpdwProcessId);

            [DllImport("user32.dll", SetLastError=true, CharSet=CharSet.Auto)]
            public static extern Int32 GetWindowTextLength(IntPtr hWnd);

            [DllImport("user32")]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
            public static List<IntPtr> GetChildWindows(IntPtr parent)
            {
               List<IntPtr> result = new List<IntPtr>();
               GCHandle listHandle = GCHandle.Alloc(result);
               try
               {
                   EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                   EnumChildWindows(parent, childProc,GCHandle.ToIntPtr(listHandle));
               }
               finally
               {
                   if (listHandle.IsAllocated)
                       listHandle.Free();
               }
               return result;
           }
            private static bool EnumWindow(IntPtr handle, IntPtr pointer)
           {
               GCHandle gch = GCHandle.FromIntPtr(pointer);
               List<IntPtr> list = gch.Target as List<IntPtr>;
               if (list == null)
               {
                   throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
               }
               list.Add(handle);
               //  You can modify this to check to see if you want to cancel the operation, then return a null here
               return true;
           }
            public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
           }
"@
        }
}

PROCESS{
    foreach ($child in ([apifuncs]::GetChildWindows($MainWindowHandle))){
        Write-Output (,([PSCustomObject] @{
            MainWindowHandle = $MainWindowHandle
            ChildId = $child
            ChildTitle = (Get-WindowName($child))
        }))
    }
}
}

您可以直接从Get进程的结果中调用它,如下所示:

代码语言:javascript
运行
复制
Get-Process | Where-Object {$_.ProcessName -eq 'OUTLOOK'} | Get-ChildWindow
票数 23
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25369285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档