如何查找应用程序的主窗口标题名称在运行In Tray中 [英] How To find main Window Title name of application In running 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屋!