- 主题
- 0
- 积分
- 854
- 贝壳
- 854 个
- 性别
- 男
- 来自
- 贵州遵义
- 注册时间
- 2005-3-26
- 最后登录
- 2011-2-26
|
[讨论] 从程序中生成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。
代码如下:
- Private Const FILESIZEOFAPP2 = 20480 '我生成的APP-2.Exe大小是20480Byte
- Private Sub cmdOK_Click() '单击按钮cmdOK运行代码
- Dim APP2() As Byte 'APP2是个Btye类型和数组
- Dim Counter As Long
- APP2 = LoadResData(101, "CUSTOM") '将自定义资源中101号资源读入数组
- '注意,微软的帮助中对加载定义资源的说明有误,硬是资源标识为"CUSTOM"而非数字
- If Dir(App.Path & "APP-2.Exe") <> "" Then '第一次按cmdOK有效
- MsgBox App.Path & "APP-2.Exe 已经存在!"
- Exit Sub
- End If
- Open App.Path & "APP-2.exe" For Binary As #1 '以二进制方式写(生成)APP-2.Exe到APP-1.Exe所在的目录
- For Counter = 0 To FILESIZEOFAPP2 - 1 '注意因为从0 Byte开始因此以文件大小 - 1Byte 为终
- Put #1, , APP2(Counter)
- Next Counter
- Close #1
- Shell App.Path & "APP-2.Exe", vbNormalFocus 注释:运行刚生成的APP-2.Exe
- Unload Me
- End Sub
- ....................................................................................................................................................
- 拦截键盘输入
- 这是使用Keyboard Hook 的范例,它的解释请查VB5 Call WinAPI技巧或Hook的简介
- '以下在.Bas
- Option Explicit
- 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
- Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
- Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
- Public hnexthookproc As Long
- Public Const HC_ACTION = 0
- Public Const WH_KEYBOARD = 2
- Public Sub UnHookKBD()
- If hnexthookproc <> 0 Then
- UnhookWindowsHookEx hnexthookproc
- hnexthookproc = 0
- End If
- End Sub
- Public Function EnableKBDHook()
- If hnexthookproc <> 0 Then
- Exit Function
- End If
- hnexthookproc = SetWindowsHookEx(WH_KEYBOARD, AddressOf _
- MyKBHFunc, App.hInstance, 0)
- If hnexthookproc <> 0 Then
- EnableKBDHook = hnexthookproc
- End If
- End Function
- Public Function MyKBHFunc(ByVal iCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
- '这三个参数是固定的,不能动,而MyKBHFunc这个名称只要和
- 'SetWindowsHookex()中 AddressOf後的名称一样便可,不一定叫什麽
- 'wParam 是传入按了哪个key的virtual-key code
- '如果您将以下的两行unmark则所有键盘的输入皆没有作用
- 'MyKBHFunc = 1 '吃掉信息
- 'Exit Function
- MyKBHFunc = 0 '信息要处理
- If iCode < 0 Then
- MyKBHFunc = CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
- Exit Function
- End If
- If wParam = vbKeySnapshot Then '侦测 有没有按到PrintScreen键
- MyKBHFunc = 1 '在这个Hook便吃掉这个信息
- Debug.Print "haha"
- Else
- Call CallNextHookEx(hnexthookproc, iCode, wParam, lParam)
- End If
- End Function
- '以下在Form
- Private Sub Form_Load()
- Call EnableKBDHook
- End Sub
- Private Sub Form_Unload(Cancel As Integer)
- Call UnHookKBD
- End Sub
复制代码 |
|