FindWindow始终返回0

josxhn 2012-10-29 07:38:58
代码如下,我建立了一个test.txt文档并打开,然后运行程序,控制台始终返回0,,,,,Google Baidu找了半天都没有解决。

我的系统是win7,IDE是 MonoDevelop


using System;
using System.Runtime.InteropServices;

namespace SendMsgToWindow
{
class MainClass
{
//[DllImport("USER32.DLL")]
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern IntPtr FindWindow (string lpClassName, string lpWindowName);

//静态方法必须在静态方法中调用?
private static void MyFindWindow (string wndName)
{
IntPtr ip = FindWindow (null, wndName);
Console.WriteLine(ip.ToString());
if (ip != IntPtr.Zero) {
//找到句柄后,你就可以做你想做的事了,发送信息你可以用SendKeys;
Console.WriteLine ("yes");
}
}

public static void Main (string[] args)
{
MyFindWindow ("test.txt - 记事本");//
}
}
}

...全文
1152 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Regean 2013-07-18
  • 打赏
  • 举报
回复
12楼正解,VS2010在WIN7下使用FindWindowA获取不到句柄,但是使用FindWindowW可以获取到
josxhn 2012-10-31
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 的回复:]

有两个版本的,分别为FindWindowA和FindWindowW,你的窗口标题中包含中文。试一试下面的声明:

[DllImport("User32.dll", EntryPoint="FindWindowA")]
[/Quote]

谢谢!我试试看!
josxhn 2012-10-30
  • 打赏
  • 举报
回复
真的是太奇怪了,
参数设置成 "Notepad", "test.txt - 记事本" 就无法取得句柄
但是设置成 "Notepad", null 就可以正确取到
而这些参数都是Spy++捕获的
和解啊和解?
Jia_H 2012-10-30
  • 打赏
  • 举报
回复
有两个版本的,分别为FindWindowA和FindWindowW,你的窗口标题中包含中文。试一试下面的声明:

[DllImport("User32.dll", EntryPoint="FindWindowA")]
josxhn 2012-10-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]
你试一下只设置类名,或者只设置窗口名,或2个都设置看。
或者换换其他窗口试一试看呢。有时候和系统关系,出一些奇怪的问题。
[/Quote]

非常感谢!当只设置类名Notepad的时候就得到了正确的句柄。
虽然距离理想解决方案还有一定距离,不过确实能够解决眼下的问题。
Hauk 2012-10-29
  • 打赏
  • 举报
回复


你试一下只设置类名,或者只设置窗口名,或2个都设置看。
或者换换其他窗口试一试看呢。有时候和系统关系,出一些奇怪的问题。
josxhn 2012-10-29
  • 打赏
  • 举报
回复
我想肯定是可以获取到窗体句柄的,否则Spy++ 是如何做到的呢

PS:我用的不是VS自带的SPY++,是款叫做Spy++ Lite V2.4的小软件
josxhn 2012-10-29
  • 打赏
  • 举报
回复
MyFindWindow ("Notepad", "test.txt - 记事本");


按照spy++设置的参数,FindWindow还是返回0
josxhn 2012-10-29
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

用SPY+确定标题对不对
[/Quote]

确定过了,是对的
SocketUpEx 2012-10-29
  • 打赏
  • 举报
回复
用SPY+确定标题对不对
josxhn 2012-10-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

在VISTA/WIN 7下 FindWindow或FindWindowEX无法获取到窗体句柄
http://www.cnblogs.com/wuhenke/archive/2010/06/20/1761534.html
[/Quote]

谢谢如梦给出的资料,仔细学习了一下,核心意思是这一段:

“理论上原因大意为:在VISTA之前的操作系统中(如XP/ WIN SERVER 2003等),所有的服务线程和应用程序都在Session 0里运行,这种方式具有安全风险,Vista/win7之后的操作系统隔离了服务和应用程序,这样服务就可以免于潜在的来自这应用程序代码的攻击。
我理解时,在WIN 7里当不创建窗体的程序进程,会被认为是服务,从而运行于Session 0里。所以,应用程序调用FindWindow方法也就无法获取进程的窗体句柄啦。”

而我所要获取的目标确实是有窗体的进程,所以还是没能解决~

Jia_H 2012-10-29
  • 打赏
  • 举报
回复
你给的参数不对,最安全的方式是用Visual Studio带的工具spy++找到你所需要的Window,看看对应的class和name是什么,对应更改你的调用代码就可以了。

静态方法无需在静态方法中调用,其他方法也可以的。
wuyq11 2012-10-29
  • 打赏
  • 举报
回复
在VISTA/WIN 7下 FindWindow或FindWindowEX无法获取到窗体句柄
http://www.cnblogs.com/wuhenke/archive/2010/06/20/1761534.html
函数功能 在窗口列表中寻找与指定条件相符的第一个子窗口 。 该函数获得一个窗口的句柄,该窗口的类名和窗口名与给定的字符串相匹配。这个函数查找子窗口,从排在给定的子窗口后面的下一个子窗口开始。在查找时不区分大小写。 参数; (1)hwndParent:要查找的子窗口所在的父窗口的句柄(如果设置了hwndParent,则表示从这个hwndParent指向的父窗口中搜索子窗口)。 如果hwndParent为 0 ,则函数以桌面窗口为父窗口,查找桌面窗口的所有子窗口。 Windows NT5.0 and later:如果hwndParent是HWND_MESSAGE,函数仅查找所有消息窗口。 (2)hwndChildAfter :子窗口句柄。查找从在Z序中的下一个子窗口开始。子窗口必须为hwndParent窗口的直接子窗口而非后代窗口。如果HwndChildAfter为NULL,查找从hwndParent的第一个子窗口开始。如果hwndParent 和 hwndChildAfter同时为NULL,则函数查找所有的顶层窗口及消息窗口。 (3)lpszClass:指向一个指定了类名的空结束字符串,或一个标识类名字符串的成员的指针。如果该参数为一个成员,则它必须为前次调用theGlobaIAddAtom函数产生的全局成员。该成员为16位,必须位于lpClassName的低16位,高位必须为0。 (4)lpszWindow:指向一个指定了窗口名(窗口标题)的空结束字符串。如果该参数为 NULL,则为所有窗口全匹配。 返回值 Long,找到的窗口的句柄。如未找到相符窗口,则返回零。会设置GetLastError 如果函数成功,返回值为具有指定类名和窗口名的窗口句柄。如果函数失败,返回值为NULL。 若想获得更多错误信息,请调用GetLastError函数。
VC获得进程ID获得主线程ID获得窗口句柄获得主窗口获得进程名 1.窗口类名 窗口句柄 窗口标题 窗口句柄 HWND FindWindow( LPCTSTR lpClassName, //窗口类名 可用 VC或者VS自带的Spy++查看 LPCTSTR lpWindowName //窗口标题 ); 举例: 以 记事本为例, 记事本 窗口类名 为:NotePad, 窗口标题 视按具体情况而定,假设为"新建 文本文档.txt - 记事本" 窗口类名 窗口句柄 TCHAR lpClassName[]=TEXT("NotePad"); HWND hWnd=::FindWindow(lpClassName,NULL); if(hWnd && IsWindow(hWnd)) ::ShowWindow(hWnd,SW_HIDE); 窗口标题 窗口句柄 TCHAR lpWindowName[]=TEXT("新建 文本文档.txt - 记事本"); HWND hWnd=::FindWindow(NULL,lpWindowName); if(hWnd && IsWindow(hWnd)) ::ShowWindow(hWnd,SW_HIDE); 2.窗口句柄 进程ID 窗口句柄 主线程ID 要使用到的函数: DWORD GetWindowThreadProcessId( HWND hWnd, //目标窗口句柄 LPDWORD lpdwProcessId //返回目标窗口对应进程ID ); 例子: DWORD dwProcId=0;//存放返回的进程ID DWORD dwThreadId=0;//存放返回的主线程ID HWND hWnd=XXXX;//这里省略,可能用任务方式得到一个窗口的句柄.比如用1中的方法. dwThreadId=GetWindowThreadProcessId(hWnd,&dwProcId);//同时得到进程ID和主线程ID. 3.窗口HAND CWnd 用CWnd::FromHandle(HWND hWnd)函数.很多类都有这个函数. 4.进程名 进程ID (注:进程名,即在"任务管理器"中看到的名字) 用CCheckObject类(详细实现源文件); 例子: 以记事本为例,进程名为 NOTEPAD.EXE (不一定是大写哦,得到任务管理器是显示而定); CCheckObject ch; TCHAR Name[]=TEXT("NOTEPAD.EXE"); DWORD dwProcId=ch.GetProcessId(Name); 5. 进程名 主线程ID 例子: CCheckObject ch; TCHAR Name[]=TEXT("NOTEPAD.EXE"); DWORD dwThreadId=ch.GetThreadId(Name); 6. 进程名 主窗口句柄 CCheckObject ch; TCHAR Name[]=TEXT("NOTEPAD.EXE"); HWND hWnd=ch.GetTargetWindowHanle(Name); 7. 其它说明 从CCheckObject类和上面的源码中,不难写出从 进程ID 主线程ID 进程ID 主窗口句柄 主线程ID--->主窗口句柄 等等其它类似转换. 对于主窗口,特点如下: A. 不能用进程ID,要用线程ID,因为一个进程可能有多个线程,每个线程都可能会有主窗口. B. 主窗口不会有WS_CHILD属性 C. 主窗口没有父窗口 D. 主窗口一般都有子窗口(这个不是一定的,但是具有普遍性)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧