分享
 
 
 

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

王朝c#·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

这两天正在网上找工作。昨天一网友问了个问题,说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

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有