以前不信,现在真的遇到了。
.net开发的C/S结构程序,用Spy++看类名竟然会变化。
相同的EXE,在不同机器上运行,比如说一个文本框,有的时候看到的类名是WindowsForms10.EDIT.app.0.33c0d9d
有的机器上看到的是WindowsForms10.EDIT.app3本来是枚举窗口上的这些子窗体,并用类名作为一个判断条件来确定目标输入框并获取句柄的,但现在类名会变,这个判断就不好使了。谁能解释一下变化的原理,原因,都跟什么有关?以及对策?
另外还有什么语言写出来的程序,类名是变化的?听说MFC写出来的也是变的?
谢谢了。

解决方案 »

  1.   

    fangsp,你就从来没回答过任何问题?你不闹心吗?
    你最好记住我,以后永远都不要回复我发的帖子。
      

  2.   

    感谢,学习了,我也刚好想用下Spy++,
    希望能具体的讲下
      

  3.   

    to jiangsheng:
    1、希望能具体再讲讲原理
    2、如果一个窗口既没有标题,类名又是变化的,那我怎么识别呢?我是想通过Hook监视目标窗口出现的。当Hook到WM_WINDOWPOSCHANGED消息时,我先通过窗口类名判断,然后在通过窗口标题判断。
      

  4.   

    1 没有原理
    2 你的方法是错误的,进程间通信有很多种方法,去搜索Interprocess communication
      

  5.   

    这个细节,如 jiangsheng 所说,没有原理,可能有规律。.net 的运行时根据当时的某些条件,会决断出一个适合的类名。而要去探究这种决断过程,可能比较困难,而且实用意义也不大,因为是实现的细节,所以后续版本还有可能会变化。你的窗口识别问题,确实会受到这个事实的困扰,那也只好另外想办法了,比如判断窗口标题、判断创建可执行程序的 exe 文件名等。
      

  6.   

    抱歉,我用错 词了。应该说是道理,而不是原理。看了http://msdn.microsoft.com/zh-cn/library/ms996405.aspx
    有点可以借鉴的资料。
    但同样还是有不能识别的情况,就是如果目标窗体不是Windows Form的话,用wm_getcontrolname可能是无效的。
      

  7.   

    对微软的一些机制了解的太少,所以我一直弄不明白为什么会有这个变化。
    期望有对微软.net内幕机制了解的人说明白。
      

  8.   

    前两天在微软的网站上看到这个managedspy
    您看看不知道是否对您有用
      

  9.   


    Delphi 里面WM_GETCONTROLNAME消息定义在哪个单元里?我怎么找不到呢?
      

  10.   

    这个消息需要注册才能得到其准确的值,如下:
    WM_GETCONTROLNAME := RegisterWindowMessage("WM_GETCONTROLNAME");
      

  11.   

    我之前也尝试那么做了
    var controlName : String;
       msgId : longint;
    begin
      if EditHWND.Text <>'' then
      begin
           SetLength(controlName, MAX_PATH);
           msgId := RegisterWindowMessage('WM_GETCONTROLNAME');
           //       ShowMessage(IntToStr(msgId));
           SendMessage(StrToInt(EditHWND.Text),msgId , 0, Integer(PChar(controlName)));
          SetLength(controlName, StrLen(PCHAR(controlName)));
          ShowMessage(controlName);//为什么获取到的是文件路径呢?
      end;
    end;没取到控件名,却得到的是文件路径
      

  12.   

    你是取别的进程 Form 的类名吧?你仔细看一下你上面提到的那个链接就会知道,跨进程的时候这个消息需要特殊处理的。因为你提供的缓冲区在你自己的进程中,消息发过去,目标进程内的窗口怎么会把内容填充到你的进程内呢?
      

  13.   

    用 OpenProcess 把目标进程打开,用 VirtualAllocEx 在目标进程中分配一块内存,然后用这块内存来接收 WM_GETCONTROLNAME 消息的返回结果,再用 ReadProcessMemory 读回来,最后别忘了用 VirtualFreeEx 把内存释放,并用 CloseHandle 把进程句柄关闭。应该够详细了吧。
      

  14.   

    有一点还是没想明白,我用dll Hook。这样我的Dll就会加载到目标程序的进程中,两者公用一个进程空间,那么我在我的Dll里接收 WM_GETCONTROLNAME消息结果, 应该是能取到啊。但现在发现取到的都是空字符串。