解决.net开发问题的最终法宝

解决|问题

这两天正在网上找工作。昨天一网友问了个问题,说SendMessage在.net中调用失败。
我看了看他的代码是用VB.net写的。于是我改用C#写了个小的测试程序
using System.Runtime.InteropServices;

[DllImport("user32.dll")]
private static extern long SendMessageW(int hwnd,int wMsg,int wParam,int lParam);

System.Diagnostics.Process[] p;
p=System.Diagnostics.Process.GetProcessesByName("notepad");
int i=p[0].Handle.ToInt32();
SendMessageW(i,16,0,0);

(因为SendMessage分两个版本,一个是SendMessageA一个是SendMessageW,由于NT下内部使用的是SendMessageW,而SendMessageA的调用则是先将参数转换后再调用SendMessageW,所以这里我是用SendMessageW。)
这个程序的功能是查找一个记事本程序,然后向他发送关闭消息。
试验了一下,果然失败了。
开始我怀疑是.net的问题,因为一个网友曾经说过在VB中调用成功的代码在VB.net中调用失败了。于是我是用ILDASM对该程序进行反汇编。反编译后IL代码如下。
.entrypoint
.custom instance void [mscorlib]System.STAThreadAttribute::.ctor() = ( 01 00 00 00 )
// 代码大小 40 (0x28)
.maxstack 4
.locals init ([0] class [System]System.Diagnostics.Process[] p,
[1] int32 i,
[2] native int CS$00000002$00000000)
IL_0000: ldstr "notepad"
IL_0005: call class [System]System.Diagnostics.Process[] [System]System.Diagnostics.Process::GetProcessesByName(string)
IL_000a: stloc.0
IL_000b: ldloc.0
IL_000c: ldc.i4.0
IL_000d: ldelem.ref
IL_000e: callvirt instance native int [System]System.Diagnostics.Process::get_Handle()
IL_0013: stloc.2
IL_0014: ldloca.s CS$00000002$00000000
//这里是SendMessageW调用的部分将p[0].Handle.ToInt32()放入参数1
IL_0016: call instance int32 [mscorlib]System.IntPtr::ToInt32()
IL_001b: stloc.1
IL_001c: ldloc.1
//放入16,参数2
IL_001d: ldc.i4.s 16
//放入0,参数3
IL_001f: ldc.i4.0
//放入0,参数4
IL_0020: ldc.i4.0
IL_0021: call int64 TWin.Class1::SendMessageW(int32,
int32,
int32,
int32)
IL_0026: pop
IL_0027: ret
看不出有什么问题,本来我以为是不是某个值被装箱之类的操作了。一看所有参数都是标准的int32类型,这个可是值啊。
我并没有就此觉悟,反而还是执迷不悟的怀疑是.net出的问题。
于是运行程序,在SendMessageW(i,16,0,0)处设置断点,看看汇编码。(运行时,在代码的旁边有个反汇编的tab,通过它你就可以看到汇编码了)
0000004f push 0
00000051 push 0
00000053 mov ecx,edi
00000055 mov edx,10h
0000005a call dword ptr ds:[009C50F8h]
00000060 nop
在Win32汇编中API函数的调用使用的方法是将参数值压入栈中(后进现出)的原则,所以参数压入顺序为4321。
汇编中的语句
0000004f push 0
00000051 push 0
00000053 mov ecx,edi
00000055 mov edx,10h
都没错。唯一有可能出错的就是
0000005a call dword ptr ds:[009C50F8h]
于是问题很清楚了,.net调用API函数的方法没有错,是传递的参数出了错。用VC++的工具SPY++看看吧,果然发现句柄与p[0].Handle.ToInt32()不符。无意间发现p[0].MainWindowHandle与SPY++的结果相符,忽然间恍然大悟。大骂自己愚蠢分明需要给程序的窗体传送消息,你给那个进程ID传送,人家谁理你啊!
改用p[0].MainWindowHandle实验,记事本被关闭了。虽然犯了傻不过倒是总结了些解决.net出的问题的一些方法,如果你有些问题感到莫名其妙,找不到方法就不如用ILDASM去反编译一下,看看IL代码说不定有帮助,如果还不行,干脆就用看看汇编码,说不定问题就明白了。
告诉他后,他又问了我另一个问题,一个窗体如何得到自己的句柄呢,其实这个很简单,this.Handle.ToInt32()就是自己的句柄了。
结尾打个广告吧,本人软开工作两年想找一份月薪3000元的北京的工作。有意者请与我联系fjl716@163.com

时间: 2024-11-03 00:28:20

解决.net开发问题的最终法宝的相关文章

Node.js配合node-http-proxy解决本地开发ajax跨域问题_node.js

情景: 前后端分离,本地前端开发调用接口会有跨域问题,一般有以下3种解决方法: 1. 后端接口打包到本地运行(缺点:每次后端更新都要去测试服下一个更新包,还要在本地搭建java运行环境,麻烦) 2. CORS跨域:后端接口在返回的时候,在header中加入'Access-Control-Allow-origin':* 之类的(有的时候后端不方便这样处理,前端就蛋疼了) 3. 用nodejs搭建本地http服务器,并且判断访问接口URL时进行转发,完美解决本地开发时候的跨域问题.  用到的技术:

解决NDK开发中Eclipse报错“Unresolved inclusion jni.h”的最终方法

在做NDK开发过程中有时候在eclipse里会遇到其无法处理inclusion导致symbol显示错误,网上有许多方法可以解决类似"Unresolved inclusion jni.h" 错误的方法,包括include path等方法,不过对我都不管用. 最终的解决办法就是初始化eclipse对该project的native support: 在eclipse中关闭指定Project 用其他编辑工具打开该project的.project文件,删除以下内容: ...... <bui

解决JSP开发Web程序中文显示的三种方法

js|web|程序|解决|显示|中文 方法一:最简单也是用的最多的方法 <%@ page language="java" pageEncoding="GBK" %> 或者<%@ page contenttype="text/html;charset=gbk";>这里可以用gb2312或者gbk,只是gbk比gb2312支持跟多的字符. 这个方法用于jsp页面中的中文显示. 方法二:使用过滤器 过滤器使用主要针对表单提交,插

解决JSP开发Web程序中的中文问题

js|web|程序|解决|问题|中文     这段时间经常看到有人问到web开发中怎么中文总是?号.原因其实很简单,因为大家大多用的是tomcat服务器,而tomcat服务器的默认编码为 iso-8859-1(西欧字符).就是因为iso-8859-1(西欧字符)编码造成了我们经常看到?号. 方法一:最简单也是用的最多的方法. <%@ page language="java" pageEncoding="GBK" %> 或者<%@ page cont

解决android开发中常见的问题

 1. 如果你的项目的R文件不见的话,可以试下改版本号在保存,R文件不见一般都是布局文本出错导致. 2. 布局文件不可以有大写字母 3. 抛出如下错误WARNING: Application does not specify an API level requirement!, 是由于没有指定users sdk的缘故,修改AndroidManifest.xml文件. 加入:<uses-sdkandroid:minSdkVersion="8"></uses-sdk>

唯快不破 互联网开发中的制胜法宝

在当下的互联网年代,已不是大鱼吃小鱼的时代,而是快鱼吃慢鱼的时代.正如江湖上的名言"天下武功,唯快不破",在互联网产品的制胜原则也就是一个快字.在各种形态的产品研发中,我们始终贯彻如一的价值观之一就是"快",我们应该如何来理解和诠释"快"?又会从哪些方面来执行贯彻这个原则呢? 快速迭代,快做快发 互联网产品不同于传统软件开发,我们面对的是上亿用户这样一个庞大的使用群体,他们是谁,有什么喜好,有何种习惯,会怎样使用我们的产品,是否喜欢我们的产品--

解决NDK开发中Eclipse报错Unresolved inclusion jni.h的最终解决方法(已测)_Android

在做NDK开发过程中有时候在eclipse里会遇到其无法处理inclusion导致symbol显示错误,网上有许多方法可以解决类似"Unresolved inclusion jni.h" 错误的方法,包括include path等方法,不过对我都不管用. 最终的解决办法就是初始化eclipse对该project的native support: 1. 在eclipse中关闭指定Project 2. 用其他编辑工具打开该project的.project文件,删除以下内容: ...... &

快速解决js开发下拉框中blur与click冲突_javascript技巧

在开发中我们会经常遇到blur和click冲突的情况.下面叙述了开发中常遇到的"下拉框"的问题,并提供了两种解决方案. 一.blur和click事件简述 blur事件:当元素失去焦点时触发blur事件:其为表单事件,blur和focus事件不会冒泡,其他表单事件都可以. click事件:当点击元素时触发click事件:所有元素都有此事件,会产生冒泡. 示例1:blur事件为表单事件 <input type="text" id="tel"&g

解决iOS开发证书&quot;此证书的签发者无效&quot;问题

前言 哎,每次过完节都要有一个坑给自己跳.逃不过这个魔爪. 这不,一过完春节,回来就发现公司证书出现"此证书的签发者无效". 开发证书'此证书的签发者无效'问题-此证书的签发者无效"> 问题原因 经过一番查找,苹果官方给出了回答. Thanks for bringing this to the attention of the community and apologies for the issues you've been having. This issue st