我试图find一个特定的窗口是否已被一个进程打开。 该过程会产生多个窗口,我需要检查所有的窗口。
我不难find这个过程
foreach (Process p in Process.GetProcesses()) { if (p.MainModule.FileName.ToLower().EndsWith("foo.exe")) FindChildWindowWithText(p); //do work
问题是接下来要做什么。 我不能使用Process的MainWindowText ,因为它随着激活的窗口而改变。
然后我试图使用Windows函数EnumChildWindows和GetwindowText ,但我不知道如果我传递一个正确的句柄EnumChildWindows。 EnumChildWindows在通过MainWindowHandle时按预期工作,但当然MainWindowHandle随活动窗口而变化。 所以我通过Process.Handle ,但是当切换应用程序的窗口时,我得到了不同的句柄和不同的结果。 (据我所知,EnumChildWindows不仅返回句柄,而且还包括.NET中的控件 ,如果我能得到窗口的标题也不会有问题)
在Windows上持续集成Git
.NET 4.0 – AccessViolationException和WndProc
跟踪和logging有什么区别?
“这个文件来自另一台计算机,可能被阻止,以保护这台计算机。” – 如何以编程方式在C#.net中删除此属性?
构buildWindows资源pipe理器扩展
也许我正在做这个错误的方式,我需要一个不同的方法 – 我的问题再一次find一个与特定的正则expression式匹配的文本的窗口。 所以我可能需要一个枚举所有窗口的function,在任务栏中可见等等。
谢谢
用于Linux的ASP.NET页面devise器
如何在dotnet核心中运行F#interactive(fsi.exe)? 它是否支持?
在2015年在Linux中运行一个.NET应用程序
应用程序池的.NET版本可以自行更改吗?
.Net程序为用户计算机上的所有图像编制索引的最快方法是什么?
一旦你有进程,你可以枚举过程中的所有Windows,并测试它们中的任何一个匹配你正在寻找的窗口。
您将需要以下P / Invoke声明
[DllImport("user32",SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] private extern static bool EnumThreadWindows(int threadId,EnumWindowsProc callback,IntPtr lParam); [DllImport("user32",SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool EnumChildWindows(IntPtr hwndParent,EnumWindowsProc lpEnumFunc,SetLastError = true,CharSet = CharSet.Auto)] private extern static int GetwindowText(IntPtr hWnd,StringBuilder text,int maxCount);
followng是一对函数的例子,可以用来在特定的过程中找到窗口,我从你的问题中了解到你有Process,问题是枚举窗口。
public static IntPtr FindWindowInProcess(Process process,Func<string,bool> compareTitle) { IntPtr windowHandle = IntPtr.Zero; foreach (Processthread t in process.Threads) { windowHandle = FindWindowInThread(t.Id,compareTitle); if (windowHandle != IntPtr.Zero) { break; } } return windowHandle; } private static IntPtr FindWindowInThread(int threadId,bool> compareTitle) { IntPtr windowHandle = IntPtr.Zero; EnumThreadWindows(threadId,(hWnd,lParam) => { StringBuilder text = new StringBuilder(200); GetwindowText(hWnd,text,200); if (compareTitle(text.ToString())) { windowHandle = hWnd; return false; } return true; },IntPtr.Zero); return windowHandle; }
然后你可以调用FindWindowInProcess函数来查找标题以“ABC”结尾的窗口为例。
IntPtr hWnd = FindWindowInProcess(p,s => s.EndsWith("ABC")); if (hWnd != IntPtr.Zero) { // The window was found.... }
当然,你可以用满足你窗口搜索条件的表达式替换s => s.EndsWith(“ABC”),它可以是一个正则表达式等等。
这里也是FindThreadWindow的一个版本,它也会检查第一级的子窗口。 如果您的窗口在层次结构中更深入,则可以进一步采用这种方法并使其成为递归函数。
private static IntPtr FindWindowInThread(int threadId,200); if (compareTitle(text.ToString())) { windowHandle = hWnd; return false; } else { windowHandle = FindChildWindow(hWnd,compareTitle); if (windowHandle != IntPtr.Zero) { return false; } } return true; },IntPtr.Zero); return windowHandle; } private static IntPtr FindChildWindow(IntPtr hWnd,bool> compareTitle) { IntPtr windowHandle = IntPtr.Zero; EnumChildWindows(hWnd,(hChildWnd,lParam) => { StringBuilder text = new StringBuilder(200); GetwindowText(hChildWnd,200); if (compareTitle(text.ToString())) { windowHandle = hChildWnd; return false; } return true; },IntPtr.Zero); return windowHandle; }
而不是枚举进程和找到窗口,我会枚举窗口(使用EnumWindows ),并找到进程(使用GetGuiThreadInfo )。
几乎类似的(或者是完全一样的?)问题与接受的答案,你可以参考: .NET(C#):获取子窗口,当你只有一个进程句柄或PID?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。