@@ -13,21 +13,7 @@ namespace Flow.Launcher.Plugin.ProcessKiller
13
13
{
14
14
internal class ProcessHelper
15
15
{
16
- [ DllImport ( "user32.dll" ) ]
17
- private static extern bool EnumWindows ( EnumWindowsProc enumProc , IntPtr lParam ) ;
18
-
19
- private delegate bool EnumWindowsProc ( IntPtr hWnd , IntPtr lParam ) ;
20
-
21
- [ DllImport ( "user32.dll" , CharSet = CharSet . Unicode ) ]
22
- private static extern int GetWindowText ( IntPtr hWnd , StringBuilder lpString , int nMaxCount ) ;
23
-
24
- [ DllImport ( "user32.dll" ) ]
25
- private static extern bool IsWindowVisible ( IntPtr hWnd ) ;
26
-
27
- [ DllImport ( "user32.dll" ) ]
28
- private static extern uint GetWindowThreadProcessId ( IntPtr hWnd , out uint lpdwProcessId ) ;
29
-
30
- private readonly HashSet < string > _systemProcessList = new HashSet < string > ( )
16
+ private readonly HashSet < string > _systemProcessList = new ( )
31
17
{
32
18
"conhost" ,
33
19
"svchost" ,
@@ -79,22 +65,25 @@ public List<ProcessResult> GetMatchingProcesses(string searchTerm)
79
65
/// <summary>
80
66
/// Returns a dictionary of process IDs and their window titles for processes that have a visible main window with a non-empty title.
81
67
/// </summary>
82
- public Dictionary < int , string > GetProcessesWithNonEmptyWindowTitle ( )
68
+ public static unsafe Dictionary < int , string > GetProcessesWithNonEmptyWindowTitle ( )
83
69
{
84
70
var processDict = new Dictionary < int , string > ( ) ;
85
- EnumWindows ( ( hWnd , lParam ) =>
71
+ PInvoke . EnumWindows ( ( hWnd , lParam ) =>
86
72
{
87
- StringBuilder windowTitle = new StringBuilder ( ) ;
88
- GetWindowText ( hWnd , windowTitle , windowTitle . Capacity ) ;
89
-
90
- if ( ! string . IsNullOrWhiteSpace ( windowTitle . ToString ( ) ) && IsWindowVisible ( hWnd ) )
73
+ var windowTitle = GetWindowTitle ( hWnd ) ;
74
+ if ( ! string . IsNullOrWhiteSpace ( windowTitle ) && PInvoke . IsWindowVisible ( hWnd ) )
91
75
{
92
- GetWindowThreadProcessId ( hWnd , out var processId ) ;
93
- var process = Process . GetProcessById ( ( int ) processId ) ;
76
+ uint processId = 0 ;
77
+ var result = PInvoke . GetWindowThreadProcessId ( hWnd , & processId ) ;
78
+ if ( result == 0u || processId == 0u )
79
+ {
80
+ return false ;
81
+ }
94
82
83
+ var process = Process . GetProcessById ( ( int ) processId ) ;
95
84
if ( ! processDict . ContainsKey ( ( int ) processId ) )
96
85
{
97
- processDict . Add ( ( int ) processId , windowTitle . ToString ( ) ) ;
86
+ processDict . Add ( ( int ) processId , windowTitle ) ;
98
87
}
99
88
}
100
89
@@ -104,6 +93,21 @@ public Dictionary<int, string> GetProcessesWithNonEmptyWindowTitle()
104
93
return processDict ;
105
94
}
106
95
96
+ private static unsafe string GetWindowTitle ( HWND hwnd )
97
+ {
98
+ var capacity = PInvoke . GetWindowTextLength ( hwnd ) + 1 ;
99
+ int length ;
100
+ Span < char > buffer = capacity < 1024 ? stackalloc char [ capacity ] : new char [ capacity ] ;
101
+ fixed ( char * pBuffer = buffer )
102
+ {
103
+ // If the window has no title bar or text, if the title bar is empty,
104
+ // or if the window or control handle is invalid, the return value is zero.
105
+ length = PInvoke . GetWindowText ( hwnd , pBuffer , capacity ) ;
106
+ }
107
+
108
+ return buffer [ ..length ] . ToString ( ) ;
109
+ }
110
+
107
111
/// <summary>
108
112
/// Returns all non-system processes whose file path matches the given processPath
109
113
/// </summary>
0 commit comments