如何查找应用程序的主窗口标题名称在运行In Tray中 [英] How To find main Window Title name of application In running In Tray

查看:102
本文介绍了如何查找应用程序的主窗口标题名称在运行In Tray中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何查找应用程序的主窗口标题名称在运行在托盘或任务栏中

How To Find main Window Title name of application In running In Tray Or Taskbar

推荐答案

您似乎想要获取所有正在运行的应用程序的列表你的机器,所以你可以通过主窗口标题查找一个,对吗?



这是我在网上找到的一个课程,并修改了一下:



It seems like you want to get a list of all the running applications on your machine so you can look for one by main window title, right?

Here's a class I found somewhere online, and modified a bit:

Imports System.Runtime.InteropServices

Public Class clsEnumWindows
    <unmanagedfunctionpointerattribute(callingconvention.stdcall)> _
    Public Delegate Function EnumWindowsProc(ByVal hwnd As System.IntPtr, ByVal lparam As System.IntPtr) As Boolean

    <dllimportattribute("user32.dll",> _
    Public Shared Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, <marshalasattribute(unmanagedtype.sysint)> ByVal lParam As IntPtr) As <marshalasattribute(unmanagedtype.bool)> Boolean
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function IsWindowVisible(<inattribute()> ByVal hWnd As System.IntPtr) As <marshalasattribute(unmanagedtype.bool)> Boolean
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetWindowText(<inattribute()> ByVal hWnd As System.IntPtr, <outattribute(),> ByVal lpString As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetWindowTextLength(<inattribute()> ByVal hWnd As System.IntPtr) As Integer
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetWindowThreadProcessId(<inattribute()> ByVal hWnd As System.IntPtr, <outattribute()> ByRef lpdwProcessId As Integer) As UInteger
    End Function

    <dllimportattribute("user32.dll",> _
    Public Shared Function GetClassName(<inattribute()> ByVal hWnd As System.IntPtr, <outattribute(),> ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    End Function

    Public Shared Function GetWindows() As List(Of ManagedWindow)
        Dim WindowList As New List(Of ManagedWindow)
        Dim ListHandle As GCHandle = GCHandle.Alloc(WindowList)
        Try
            clsEnumWindows.EnumWindows(New clsEnumWindows.EnumWindowsProc(AddressOf EnumWindowsCallBack), GCHandle.ToIntPtr(ListHandle))
        Finally
            ListHandle.Free()
        End Try
        Return WindowList
    End Function

    Private Shared Function EnumWindowsCallBack(ByVal handle As IntPtr, ByVal lParam As IntPtr) As Boolean
        If clsEnumWindows.IsWindowVisible(handle) Then
            Dim TitleBuilder As New System.Text.StringBuilder(clsEnumWindows.GetWindowTextLength(handle) + 1)
            Dim WndList As List(Of ManagedWindow) = DirectCast(GCHandle.FromIntPtr(lParam).Target, List(Of ManagedWindow))
            clsEnumWindows.GetWindowText(handle, TitleBuilder, TitleBuilder.Capacity)
            Dim ProcessID As Integer = -1
            clsEnumWindows.GetWindowThreadProcessId(handle, ProcessID)
            Dim ClassNameBuilder As New System.Text.StringBuilder(255)
            clsEnumWindows.GetClassName(handle, ClassNameBuilder, ClassNameBuilder.Capacity)
            WndList.Add(New ManagedWindow(handle, TitleBuilder.ToString, Process.GetProcessById(ProcessID), ClassNameBuilder.ToString))
        End If
        Return True 'Tells the EnumWindows API to keep going and call this function again for the next window
    End Function

    Public Class ManagedWindow
        Private _Title As String = String.Empty

        Public Property Title() As String
            Get
                Return _Title
            End Get
            Set(ByVal value As String)
                _Title = value
            End Set
        End Property

        Private _Handle As IntPtr

        Public Property Handle() As IntPtr
            Get
                Return _Handle
            End Get
            Set(ByVal value As IntPtr)
                _Handle = value
            End Set
        End Property

        Private _OwningProcess As Process

        Public Property OwningProcess() As Process
            Get
                Return _OwningProcess
            End Get
            Set(ByVal value As Process)
                _OwningProcess = value
            End Set
        End Property

        Private _ClassName As String = String.Empty

        Public Property ClassName() As String
            Get
                Return _ClassName
            End Get
            Set(ByVal value As String)
                _ClassName = value
            End Set
        End Property

        Public Sub New()
        End Sub

        Public Sub New(ByVal Hwnd As IntPtr, ByVal TitleText As String, ByVal Owner As Process, ByVal NativeClassName As String)
            _Handle = Hwnd
            _Title = TitleText
            _OwningProcess = Owner
            _ClassName = NativeClassName
        End Sub

        Public Overrides Function ToString() As String
            If OwningProcess Is Nothing Then
                Return Handle.ToString & " —- " & ClassName & " —- " & Title
            Else
                Return Handle.ToString & " —- " & ClassName & " —- " & Title & " —- " & OwningProcess.ProcessName
            End If
        End Function

    End Class

End Class





要了解它是如何工作的,请创建一个新的vb.net Windows窗体应用程序。添加此类,在form1上放置一个列表框,并将此代码放在Form1_Load中:





To see how it works, create a new vb.net windows forms application. Add this class, drop a listbox on form1, and put this code in Form1_Load:

Dim windows As List(Of clsEnumWindows.ManagedWindow) = clsEnumWindows.GetWindows

For Each window As clsEnumWindows.ManagedWindow In windows
   Me.ListBox1.Items.Add(window.Title)
Next





然后运行它。我希望看一下这个简单的代码示例(form_load中的东西),这个类的用法很明确。



- Pete



Then run it. I hope looking at that simple code example (the stuff in form_load), this class's usage is clear.

- Pete


我绝对清楚你的最终目标是什么,但是运行这个片段,看看:

I ti snot absolutely clear what your final goal is, but run this snippet, and see:
foreach(var p in Process.GetProcesses()){
    Console.WriteLine("Process: {0} ID: {1}, Main window title: {2}", p.ProcessName, p.Id, p.MainWindowTitle);
}





[更新:列出所有窗口标题,基于以下链接]





[Update: listing all window titles, based on the link below]

delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

[DllImport("user32.dll")]
static extern bool EnumThreadWindows(int dwThreadId, EnumThreadDelegate lpfn,
    IntPtr lParam);

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, 
    StringBuilder lParam);

private const uint WM_GETTEXT = 0x000D;

static IEnumerable<IntPtr> EnumerateProcessWindowHandles(int processId)
{
    var handles = new List<IntPtr>();

    foreach (ProcessThread thread in Process.GetProcessById(processId).Threads)
        EnumThreadWindows(thread.Id, 
            (hWnd, lParam) => { handles.Add(hWnd); return true; }, IntPtr.Zero);

    return handles;
}

[STAThread]
void Main()
{
	foreach(var p in Process.GetProcesses()){
		Console.WriteLine(">> Process: {0} ID: {1}, Main window title: {2}\nWindows:", p.ProcessName, p.Id, p.MainWindowTitle);
	    foreach (var handle in EnumerateProcessWindowHandles(p.Id))
		{
			StringBuilder message = new StringBuilder(1000);
			SendMessage(handle, WM_GETTEXT, message.Capacity, message);
			Console.WriteLine(message.ToString());
		}
		Console.WriteLine("<<\n\n");
	}
}


如果您只想获取机器上所有正在运行的进程的列表,那么您可以找到一个应用程序在系统中运行,它甚至更简单。使用此:



If you just want to get a list of ALL the running processes on the machine so you can find an application running in the systray, it's even simpler. Use this:

For Each proc As Process In Process.GetProcesses
   ListBox1.Items.Add(proc.ProcessName)
Next





我测试过这一刻,发现我自己的两个在系统中运行的应用程序。



- Pete



I tested this a moment ago, and found two of my own apps that are running in the systray.

- Pete


这篇关于如何查找应用程序的主窗口标题名称在运行In Tray中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆