国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > .NET > 正文

解決.net開發問題的最終法寶

2024-07-10 12:57:22
字體:
來源:轉載
供稿:網友
這兩天正在網上找工作。昨天一網友問了個問題,說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元的北京的工作。有意者請與我聯系[email protected]
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 德安县| 桂平市| 乌兰察布市| 陕西省| 类乌齐县| 哈巴河县| 和政县| 湘潭市| 高平市| 紫金县| 策勒县| 贺州市| 普宁市| 鹤山市| 石渠县| 兴仁县| 巫山县| 丹阳市| 湟源县| 湘潭县| 定南县| 深水埗区| 米易县| 甘肃省| 博野县| 南和县| 监利县| 云龙县| 民和| 文水县| 淮南市| 珲春市| 苍山县| 襄城县| 白银市| 开封市| 阿拉尔市| 剑阁县| 麟游县| 庄浪县| 会同县|