返回列表 发帖

[讨论] 从程序中生成exe文件 和 拦截键盘输入

这篇文章要讨论的是在一个VB程序中如何产生出另一个Exe文件。要实现这个目的,必须符合以下几个条件:

    第一、编写这样的程序时,具备欲生成的Exe文件
    第二、事先知道欲生成的Exe文件大小

  其实这两个条件可以说不是条件,但确实很重要。为了叙说方便,将发行的程序称作APP-1.Exe,要生成的文件叫APP-2.Exe,以下是具体步骤:

    第一步,准备好APP-2.Exe,这里我使用VB写了一个什么都不做程序,编译成APP-2.Exe。
    第二步,右键单击单击APP-2.Exe,选择属性,记下文件大小。注意,应记下以字节为单位的具体数字,而不是多少k。

    这样就具备了前边说的两个条件。

    第三步,新建工程APP1,新建资源文件加入工程,在资源文件编辑器中添加自定义资源(CUSTOM),资源号使用默认的101。值得注意的是,每个资源号对应的资源项对资源大小的要求是有限制的,我记得时64K,因此如果APP-2.Exe的大小如果大于这个数的话,就要麻烦一些。如果是这样,我们的写另一个程序,把APP-2.Exe一个字节一个字节的读出来,每64K生成一个文件,然后再把这些文件分别写道资源文件的101、102......资源项中,代码也要作相应的修改。

    第四步,为APP-1.Exe编写代码,使其读取资源文件的数据,生成APP-1.Exe。

  代码如下:

  1.   Private Const FILESIZEOFAPP2 = 20480    '我生成的APP-2.Exe大小是20480Byte
  2.   Private Sub cmdOK_Click()    '单击按钮cmdOK运行代码
  3.     Dim APP2() As Byte    'APP2是个Btye类型和数组
  4.     Dim Counter As Long
  5.     APP2 = LoadResData(101, "CUSTOM")    '将自定义资源中101号资源读入数组
  6.     '注意,微软的帮助中对加载定义资源的说明有误,硬是资源标识为"CUSTOM"而非数字
  7.     If Dir(App.Path & "APP-2.Exe") <> "" Then    '第一次按cmdOK有效
  8.       MsgBox App.Path & "APP-2.Exe 已经存在!"
  9.       Exit Sub
  10.     End If
  11.     Open App.Path & "APP-2.exe" For Binary As #1    '以二进制方式写(生成)APP-2.Exe到APP-1.Exe所在的目录
  12.       For Counter = 0 To FILESIZEOFAPP2 - 1    '注意因为从0 Byte开始因此以文件大小 - 1Byte 为终
  13.         Put #1, , APP2(Counter)
  14.       Next Counter
  15.     Close #1
  16.     Shell App.Path & "APP-2.Exe", vbNormalFocus 注释:运行刚生成的APP-2.Exe
  17.     Unload Me
  18.   End Sub

  19. ....................................................................................................................................................

  20. 拦截键盘输入

  21.   这是使用Keyboard Hook 的范例,它的解释请查VB5 Call WinAPI技巧或Hook的简介
  22. '以下在.Bas
  23. Option Explicit

  24. Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
  25. Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
  26. Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long

  27. Public hnexthookproc As Long
  28. Public Const HC_ACTION = 0
  29. Public Const WH_KEYBOARD = 2

  30. Public Sub UnHookKBD()
  31. If hnexthookproc <> 0 Then
  32. UnhookWindowsHookEx hnexthookproc
  33. hnexthookproc = 0
  34. End If
  35. End Sub
  36. Public Function EnableKBDHook()
  37. If hnexthookproc <> 0 Then
  38. Exit Function
  39. End If
  40. hnexthookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf _
  41. MyKBHFunc, App.hInstance, 0)
  42. If hnexthookproc <> 0 Then
  43. EnableKBDHook = hnexthookproc
  44. End If
  45. End Function
  46. Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
  47. '这三个参数是固定的,不能动,而MyKBHFunc这个名称只要和
  48. 'SetWindowsHookex()中 AddressOf後的名称一样便可,不一定叫什麽
  49. 'wParam 是传入按了哪个key的virtual-key code

  50. '如果您将以下的两行unmark则所有键盘的输入皆没有作用
  51. 'MyKBHFunc = 1 '吃掉信息
  52. 'Exit Function

  53. MyKBHFunc = 0 '信息要处理
  54. If iCode < 0 Then
  55. MyKBHFunc = CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
  56. Exit Function
  57. End If
  58. If wParam = vbKeySnapshot Then '侦测 有没有按到PrintScreen键
  59. MyKBHFunc = 1 '在这个Hook便吃掉这个信息
  60. Debug.Print "haha"
  61. Else
  62. Call CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
  63. End If
  64. End Function

  65. '以下在Form
  66. Private Sub Form_Load()
  67. Call EnableKBDHook
  68. End Sub

  69. Private Sub Form_Unload(Cancel As Integer)
  70. Call UnHookKBD
  71. End Sub
复制代码
天行健,君子以自强不息
地势坤,君子以厚德载物
黑色海岸线欢迎您

QQ群:7212260
致力于探索WEB技术精髓:http://www.bitechcn.com
点这里加我!

现在不太想读程序了.有点头疼哦.

TOP

返回列表 回复 发帖