C# 根据进程ID获取进程主窗口句柄
我的进程是个隐藏窗口的进程,所以用Process.MainWindowHandle无法获取到值,总是0。后来我在网上搜到了大家对于此类问题的处理方法,就是用枚举,API的...
我的进程是个隐藏窗口的进程,所以用Process.MainWindowHandle 无法获取到值,总是0。后来我在网上搜到了大家对于此类问题的处理方法,就是用枚举,API的EnumThreadWindows
虽然我能获取到句柄了,但是获取到的不是正确的句柄。这里的NRCServer进程是个exe程序,他的WindowState设置为Minimized,ShowInTaskbar 设置为 false 于是窗口被隐藏。所以我没能获取到它的MainWindowHandle,只有进程Id。并且在NRCServer进程启动的时候,弹出对话框显示了主窗口句柄,但是根据调用API函数获取到的句柄,不是显示的这个。
逐语句调试,发现,在EnumWindowsProc中,其实能获取到至少三个同Id号但是不同句柄的窗口。虽然这三个句柄都不是我的进程的,但是让我疑惑的是,怎么会有三个同Id的?另外,究竟该如何获取到正确的那个句柄?!
谢谢各位大虾,帮忙解答一下! 展开
虽然我能获取到句柄了,但是获取到的不是正确的句柄。这里的NRCServer进程是个exe程序,他的WindowState设置为Minimized,ShowInTaskbar 设置为 false 于是窗口被隐藏。所以我没能获取到它的MainWindowHandle,只有进程Id。并且在NRCServer进程启动的时候,弹出对话框显示了主窗口句柄,但是根据调用API函数获取到的句柄,不是显示的这个。
逐语句调试,发现,在EnumWindowsProc中,其实能获取到至少三个同Id号但是不同句柄的窗口。虽然这三个句柄都不是我的进程的,但是让我疑惑的是,怎么会有三个同Id的?另外,究竟该如何获取到正确的那个句柄?!
谢谢各位大虾,帮忙解答一下! 展开
3个回答
展开全部
以下是一些获取窗口句柄的winapi,希望对你有点作用
/// <summary>
/// 查找一个窗口,返回此窗口的句柄
/// </summary>
/// <param name="lpClassName">要查找的窗口的类名,如果设为null,表示适配所有类</param>
/// <param name="lpWindowName">要查找的窗口的标题文本</param>
/// <returns>返回窗口的句柄,如果没找到,返回0</returns>
[DllImport("user32.DLL", EntryPoint="FindWindowW", SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long FindWindow(string lpClassName,string lpWindowName);
/// <summary>
/// 在窗口列表中寻找与指定条件相符的第一个子窗口
/// </summary>
/// <param name="hwndParent">在其中查找子的父窗口。如设为零,表示使用桌面窗口(通常说的顶级窗口都被认为是桌面的子窗口,所以也会对它们进行查找)</param>
/// <param name="hwndChildAfter">子窗口句柄。查找从在Z序中的下一个子窗口开始。子窗口必须为hwndPareRt窗口的直接子窗口而非后代窗口。如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。</param>
/// <param name="lpszClass">要查找的窗口的类名,如果设为null,表示适配所有类</param>
/// <param name="lpszWindow">要查找的窗口的标题文本</param>
/// <returns>找到的窗口的句柄。如未找到相符窗口,则返回零</returns>
[DllImport("user32.DLL", EntryPoint="FindWindowExW", SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long FindWindowEx(long hwndParent,long hwndChildAfter,string lpszClass,string lpszWindow);
/// <summary>
/// 将指定的窗口带至窗口列表顶部。倘若它部分或全部隐藏于其他窗口下面,则将隐藏的部分完全显示出来。该函数也对弹出式窗口、顶级窗口以及MDI子窗口产生作用
/// </summary>
/// <param name="hwnd">欲带至顶部的那个窗口的句柄</param>
/// <returns>非零表示成功,零表示失败</returns>
[DllImport("user32.DLL", EntryPoint="BringWindowToTopW", SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long BringWindowToTop(long hwnd);
/// <summary>
/// 获得拥有输入焦点的窗口的句柄
/// </summary>
/// <returns>拥有焦点的那个窗口的句柄。如没有窗口拥有输入焦点,则返回零</returns>
[DllImport("user32.DLL", EntryPoint="GetFocus",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long GetFocus();
/// <summary>
/// 搜索内部窗口列表,寻找隶属于指定窗口的头一个窗口的句柄
/// </summary>
/// <param name="hwnd">想在其中搜寻顶级子的窗口。零表示寻找位于桌面的顶级窗口</param>
/// <returns>Z序列中的顶级窗口也是内部窗口列表的第一个窗口</returns>
[DllImport("user32.DLL", EntryPoint="GetTopWindow",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long GetTopWindow(long hwnd );
/// <summary>
/// 获得整个窗口的范围矩形,窗口的边框、标题栏、滚动条及菜单等都在这个矩形内
/// </summary>
/// <param name="hwnd">想获得范围矩形的那个窗口的句柄</param>
/// <param name="lpRect">屏幕坐标中随同窗口装载的矩形</param>
/// <returns>非零表示成功,零表示失败</returns>
[DllImport("user32.DLL", EntryPoint="GetWindowRect",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long GetWindowRect(long hwnd,RECTAPI lpRect);
/// <summary>
/// 返回包含了指定点的窗口的句柄。忽略屏蔽、隐藏以及透明窗口
/// </summary>
/// <param name="xPoint">x点值</param>
/// <param name="yPoint">y点值</param>
/// <returns>包含了指定点的窗口的句柄。如指定的点处没有窗口存在,则返回零</returns>
[DllImport("user32.DLL", EntryPoint="WindowFromPoint",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long WindowFromPoint(long xPoint,long yPoint);
/// <summary>
/// 查找一个窗口,返回此窗口的句柄
/// </summary>
/// <param name="lpClassName">要查找的窗口的类名,如果设为null,表示适配所有类</param>
/// <param name="lpWindowName">要查找的窗口的标题文本</param>
/// <returns>返回窗口的句柄,如果没找到,返回0</returns>
[DllImport("user32.DLL", EntryPoint="FindWindowW", SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long FindWindow(string lpClassName,string lpWindowName);
/// <summary>
/// 在窗口列表中寻找与指定条件相符的第一个子窗口
/// </summary>
/// <param name="hwndParent">在其中查找子的父窗口。如设为零,表示使用桌面窗口(通常说的顶级窗口都被认为是桌面的子窗口,所以也会对它们进行查找)</param>
/// <param name="hwndChildAfter">子窗口句柄。查找从在Z序中的下一个子窗口开始。子窗口必须为hwndPareRt窗口的直接子窗口而非后代窗口。如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。</param>
/// <param name="lpszClass">要查找的窗口的类名,如果设为null,表示适配所有类</param>
/// <param name="lpszWindow">要查找的窗口的标题文本</param>
/// <returns>找到的窗口的句柄。如未找到相符窗口,则返回零</returns>
[DllImport("user32.DLL", EntryPoint="FindWindowExW", SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long FindWindowEx(long hwndParent,long hwndChildAfter,string lpszClass,string lpszWindow);
/// <summary>
/// 将指定的窗口带至窗口列表顶部。倘若它部分或全部隐藏于其他窗口下面,则将隐藏的部分完全显示出来。该函数也对弹出式窗口、顶级窗口以及MDI子窗口产生作用
/// </summary>
/// <param name="hwnd">欲带至顶部的那个窗口的句柄</param>
/// <returns>非零表示成功,零表示失败</returns>
[DllImport("user32.DLL", EntryPoint="BringWindowToTopW", SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long BringWindowToTop(long hwnd);
/// <summary>
/// 获得拥有输入焦点的窗口的句柄
/// </summary>
/// <returns>拥有焦点的那个窗口的句柄。如没有窗口拥有输入焦点,则返回零</returns>
[DllImport("user32.DLL", EntryPoint="GetFocus",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long GetFocus();
/// <summary>
/// 搜索内部窗口列表,寻找隶属于指定窗口的头一个窗口的句柄
/// </summary>
/// <param name="hwnd">想在其中搜寻顶级子的窗口。零表示寻找位于桌面的顶级窗口</param>
/// <returns>Z序列中的顶级窗口也是内部窗口列表的第一个窗口</returns>
[DllImport("user32.DLL", EntryPoint="GetTopWindow",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long GetTopWindow(long hwnd );
/// <summary>
/// 获得整个窗口的范围矩形,窗口的边框、标题栏、滚动条及菜单等都在这个矩形内
/// </summary>
/// <param name="hwnd">想获得范围矩形的那个窗口的句柄</param>
/// <param name="lpRect">屏幕坐标中随同窗口装载的矩形</param>
/// <returns>非零表示成功,零表示失败</returns>
[DllImport("user32.DLL", EntryPoint="GetWindowRect",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long GetWindowRect(long hwnd,RECTAPI lpRect);
/// <summary>
/// 返回包含了指定点的窗口的句柄。忽略屏蔽、隐藏以及透明窗口
/// </summary>
/// <param name="xPoint">x点值</param>
/// <param name="yPoint">y点值</param>
/// <returns>包含了指定点的窗口的句柄。如指定的点处没有窗口存在,则返回零</returns>
[DllImport("user32.DLL", EntryPoint="WindowFromPoint",SetLastError=true,CharSet=CharSet.Unicode, ExactSpelling=true,CallingConvention=CallingConvention.StdCall)]
public static extern long WindowFromPoint(long xPoint,long yPoint);
展开全部
给窗体设置一个Text,比如this.Text=“隐藏窗口”;然后用API直接找名字,一下就能找到了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
不太清楚你是要获取别的进程的句柄还是你自己程序的句柄
你自己程序的话可以用Application访问所有Windows窗口,然后Windows窗口上面有Handle就可以获取了
你自己程序的话可以用Application访问所有Windows窗口,然后Windows窗口上面有Handle就可以获取了
更多追问追答
追问
是我自己的程序。handle我的确可以获取,可是我需要的是主窗口句柄:MainWindowHandle
追答
你的这个主窗口是什么意思?Application有个MainWindow属性
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询