如何获得在Taskmanager的主进程下生成的顶级窗口的子窗口进程ID的列表?

时间:2018-09-29 23:31:20

标签: c# powershell child-process

我正在使用两种不同的软件,其中一种是用Java编写的,我的目标是使用我尝试创建的Powershell脚本来串联控制它们,从而使我能够从最小化的状态中恢复,从每个窗口中选择窗口父进程产生的应用程序。我已经研究过使用诸如AutoIT之类的UI自动化软件,但是从我发现这些程序无法轻松访问/识别Java中的Windows /控件。因此,我已经使用Powershell / C#来实现我的目标,这意味着识别/访问Windows。为了清楚起见,我试图捕获/识别任务栏中的窗口,并在任务管理器中以命名的描述显示这些窗口,这些描述从“进程”选项卡下正在运行的应用程序的主要列表中缩进一层。能够使用在任务管理器中应用于“名称”的正则表达式过滤器来控制这些子窗口就足够了。对于这两个程序,任务管理器没有显示PID或“进程名称”,尽管进行了所有搜索,但我仍然找不到能够实现此目标的任何内容,但是我缺乏编码技能对此没有帮助。从我的搜索来看,FindWindowEx将不起作用,因为它仅在子窗口上运行,而我尝试访问的窗口是顶层的重叠窗口。以下是我在Get Application's Window Handles中尝试过的一种方法,但是显然我在Powershell中尝试执行它的方式做错了:

Add-Type -TypeDefinition $Source -Language CSharp

$Source = @"
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EnumChildWindows(IntPtr hwndParent, EnumWindowsProc lpEnumFunc, IntPtr lParam);

private 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;
"@
New-Object -TypeName GetChildWindowHandle(Title)

我还尝试使用以下方法从Get Application's Window Handles中尝试了以下代码:

Add-Type -TypeDefinition $Source -Language CSharp

$Source = @"

        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        IntPtr hWnd = (IntPtr)FindWindow(windowName, null);

struct SearchData
        {
            public string WindowText;
            public IntPtr ParentHandle;
            public IntPtr ResultHandle;
        }

        delegate bool EnumWindowsCallback(IntPtr currentWindowHandle, ref SearchData searchData);

        [DllImport("user32.dll")] static extern bool EnumWindows(EnumWindowsCallback callback, ref SearchData searchData);

        [DllImport("user32.dll")] static extern IntPtr GetParent(IntPtr childHandle);

        [DllImport("user32.dll")] static extern void GetWindowText(IntPtr handle, StringBuilder resultWindowText, int maxTextCapacity);


        static bool Callback(IntPtr currentWindowHandle, ref SearchData searchData)
        {
            bool continueEnumeration = true;

            IntPtr currentWindowParentHandle = GetParent(currentWindowHandle);

            if (currentWindowParentHandle == searchData.ParentHandle)
            {
                var windowText = new StringBuilder(1024);
                GetWindowText(currentWindowHandle, windowText, windowText.Capacity);

                if (windowText.ToString() == searchData.WindowText)
                {
                    searchData.ResultHandle = currentWindowHandle;
                    continueEnumeration = false;
                }
            }

            return continueEnumeration;
        }


        IntPtr GetChildWindowHandle(string windowText, IntPtr parentHandle)
        {
            var searchData = new SearchData{ParentHandle=parentHandle, WindowText=windowText};

            EnumWindows(Callback, ref searchData);

            return searchData.ResultHandle;
        }
"@
New-Object -TypeName FindWindow(Title)

我进行过其他尝试,但使用MainWindowHandle却无济于事,因为我需要操纵子进程窗口以及Wscript.shell的AppActivate,这再次使我无法访问各个子窗口,而且似乎不可靠。我意识到这个问题可能归结为如何在Powershell中使用C#代码,但是我不确定,也不知道我是否在正确的道路上实现标题所示的目标。没有关于继续进行的想法,因此,我感谢任何人都可以提供的任何帮助。

0 个答案:

没有答案