找回密码
 加入
搜索
查看: 4916|回复: 14

[已解决]HOOK API的问题,一运行就系统崩溃,急求解决方案

  [复制链接]
发表于 2009-5-28 13:26:58 | 显示全部楼层 |阅读模式
本帖最后由 passkalilo 于 2009-5-29 21:37 编辑

我想在系统启动屏保或待机之前运行一段自已的代码,可是不知如何实现,查了半天资料,知道要通过API HOOK实现,可是网上关于这个的都是其它语言的,不知道AU3具体怎么实现,写了如下一段代码,一运行系统就崩溃了:
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <StructureConstants.au3>

Opt('MustDeclareVars', 1)

Global $hHook, $hSuspend

_Main()

Func _Main()
        Local $hmod
        $hSuspend = DllCallbackRegister("SetSuspendState", "int", "int;int;int")
        $hmod = _WinAPI_GetModuleHandle(0)
        $hHook = _WinAPI_SetWindowsHookEx($WH_CALLWNDPROC, DllCallbackGetPtr($hSuspend), $hmod)

        While 1
                Sleep(10)
        WEnd
EndFunc   ;==>_Main

;===========================================================
; callback function
;===========================================================
Func SetSuspendState($nCode, $wParam, $lParam)
    ToolTip($nCode&$wParam&$lParam)
        Return _WinAPI_CallNextHookEx($hHook, $nCode, $wParam, $lParam)
EndFunc   ;==>_KeyProc

Func OnAutoItExit()
        _WinAPI_UnhookWindowsHookEx($hHook)
        DllCallbackFree($hSuspend)
EndFunc   ;==>OnAutoItExit
以上程序,一运行系统就会崩溃,怎么回事?

会的说句话,不会的帮顶一个,谢谢了

评分

参与人数 1金钱 +10 收起 理由
afan + 10

查看全部评分

 楼主| 发表于 2009-5-28 16:21:11 | 显示全部楼层
参考资料
SetSuspendState 函数
The SetSuspendState function suspends the system by shutting power down. Depending on the Hibernate parameter, the system either enters a suspend (sleep) state or hibernation (S4).  
定义
BOOLEAN SetSuspendState(BOOL Hibernate, BOOL ForceCritical, BOOL DisableWakeEvent);  
参数
  Hibernate
    [in] If this parameter is TRUE, the system hibernates. If the parameter is FALSE, the system is suspended.
  ForceCritical
    [in] If this parameter is TRUE, the system suspends operation immediately; if it is FALSE, the system broadcasts a PBT_APMQUERYSUSPEND event to each application to request permission to suspend operation.
  DisableWakeEvent
    [in] If this parameter is TRUE, the system disables all wake events. If the parameter is FALSE, any system wake events remain enabled.
返回值
  If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError.
说明
  An application may use SetSuspendState to transition the system from the working state to the standby (sleep), or optionally, hibernate (S4) state. This function is similar to the SetSystemPowerState function.
系统要求
  Client: Requires Windows XP, Windows 2000 Professional, Windows Me, or Windows 98.
Server: Requires Windows Server 2003 or Windows 2000 Server.
Header: Declared in Powrprof.h.
Library: Link to Powrprof.lib.
DLL: Requires PowrProf.dll.
 楼主| 发表于 2009-5-28 17:09:54 | 显示全部楼层
为什么我无论怎么提问都没人回答?
问题的标题都换好几个了
 楼主| 发表于 2009-5-29 21:34:52 | 显示全部楼层
还是自行解决了,对论坛有点失望
#include "au3_inc\GuiConstantsEx.au3"

$logfile = @ScriptDir&"\mp_standby-hook.log"
$delystdby = 30   ;seconds to delay standby
$mes = ""

Global $WM_POWERBROADCAST         = 536
Global $PBT_APMQUERYSUSPEND       = 0x0000
Global $PBT_APMQUERYSTANDBY       = 0x0001
Global $PBT_APMQUERYSUSPENDFAILED = 0x0002
Global $PBT_APMQUERYSTANDBYFAILED = 0x0003
Global $PBT_APMSUSPEND            = 0x0004
Global $PBT_APMSTANDBY            = 0x0005
Global $PBT_APMRESUMECRITICAL     = 0x0006
Global $PBT_APMRESUMESUSPEND      = 0x0007
Global $PBT_APMRESUMESTANDBY      = 0x0008
Global $PBT_APMBATTERYLOW         = 0x0009
Global $PBT_APMPOWERSTATUSCHANGE  = 0x000A
Global $PBT_APMOEMEVENT           = 0x000B
Global $PBT_APMRESUMEAUTOMATIC    = 0x0012
Global $PBTF_APMRESUMEFROMFAILURE = 0x00000001
Global $ES_DISPLAY_REQUIRED       = 0x00000002; zero the display's idle timer
Global $ES_SYSTEM_REQUIRED        = 0x00000001; zero the system's idle timer
Global $ES_CONTINUOUS             = 0x80000000; keep the display or system on (doesn't work?)

$hGUI = GUICreate("Standby", 1,1,1,1,-1)
GUIRegisterMsg($WM_POWERBROADCAST, "Standby")  ;hook into win32 pm API
GUISetState(@SW_MINIMIZE,$hGUI)

$g_szVersion = "MP_StandBy-Hook"
If WinExists($g_szVersion) Then Exit ; It's already running
AutoItWinSetTitle($g_szVersion)
WriteToLog($g_szVersion&" started...")

While 1
    $GUIMsg = GUIGetMsg()
    Switch $GUIMsg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
    Sleep (60000) ; Sleep for a minute
WEnd

Func Standby($hWnd, $Msg, $wParam, $lParam)
    Switch $wParam
        Case $PBT_APMQUERYSUSPEND         ; gets called first on standby request 
            WriteToLog("PBT_APMQUERYSUSPEND received...")
            For $i=$delystdby to 1 Step -1
                DllCall("kernel32.dll","int","SetThreadExecutionState","int", $ES_SYSTEM_REQUIRED)
                WriteToLog("Delaying Standby: "&$i&" s.")
                Sleep(1000)
            Next

        Case $PBT_APMSUSPEND              ; gets called second on standby request 
            WriteToLog("PBT_APMSUSPEND received...")
            WriteToLog("Entering Standby...")

        Case $PBT_APMRESUMEAUTOMATIC      ; gets called first after resume
            WriteToLog("PBT_APMRESUMEAUTOMATIC received...")
            WriteToLog("Resuming from Standby..."

        Case $PBT_APMRESUMESUSPEND        ; gets called second after resume
            WriteToLog("PBT_APMRESUMESUSPEND received...")
            WriteToLog("Checking MediaPortal...")
            Sleep(5000)
            If Not ProcessExists("mediaportal.exe") Then
                Run("c:\_mp\mediaportal.exe","c:\_mp")
            EndIf
            Sleep(5000)
            WriteToLog("Running RTC updater...")
            ShellExecute("timeupdate.au3","","c:\_tvtools")
            Sleep(5000)
            WriteToLog("Faking user interaction...")
            $pos = MouseGetPos()
            MouseMove($pos[0]+50, $pos[1]+50)
            MouseMove($pos[0]-50, $pos[1]-50)
            MouseMove($pos[0], $pos[1])

        Case $PBT_APMQUERYSTANDBY
            WriteToLog("PBT_APMQUERYSTANDBY received...")
        Case $PBT_APMQUERYSUSPENDFAILED
            WriteToLog("PBT_APMQUERYSUSPENDFAILED received...")
        Case $PBT_APMQUERYSTANDBYFAILED
            WriteToLog("PBT_APMQUERYSTANDBYFAILED received...")
        Case $PBT_APMRESUMECRITICAL
            WriteToLog("PBT_APMRESUMECRITICAL received...")
        Case $PBT_APMRESUMESTANDBY
            WriteToLog("PBT_APMRESUMESTANDBY received...")
        Case $PBT_APMSTANDBY
            WriteToLog("PBT_APMSTANDBY received...")
        Case $PBT_APMPOWERSTATUSCHANGE
            WriteToLog("PBT_APMPOWERSTATUSCHANGE received...")
        Case $PBT_APMOEMEVENT
            WriteToLog("PBT_APMOEMEVENT received...")
        Case Else
            WriteToLog("Some unknown standby related message received... WTF?")
    EndSwitch
EndFunc

Func WriteToLog($mes)
    $file=FileOpen($logfile,1)
    FileWrite($logfile,@MDAY&@MON&@YEAR&"-"&@HOUR&@MIN&@SEC&": "&$mes&@CRLF)
    FileClose($logfile)
Endfunc

评分

参与人数 1金钱 +10 贡献 +5 收起 理由
lynfr8 + 10 + 5 原创内容,感谢你对论坛的支持;希望继续发 ...

查看全部评分

 楼主| 发表于 2009-5-29 21:36:12 | 显示全部楼层
Global Const $WM_POWERBROADCAST    = 0x0218
Global Const $PBT_APMQUERYSUSPEND  = 0x0000
Global Const $BROADCAST_QUERY_DENY = 0x424D5144

HotKeySet("{Pause}", "_Exit")

$hGUI = GUICreate("Test GUI")

$TestButton = GUICtrlCreateButton("Test", 60, 37, 75, 23)

GUIRegisterMsg($WM_POWERBROADCAST, "WM_POWERBROADCAST")

While 1
    Sleep(100)
WEnd

Func WM_POWERBROADCAST($hWnd, $Msg, $wParam, $lParam)
    Switch $wParam
        Case $PBT_APMQUERYSUSPEND
            Return $BROADCAST_QUERY_DENY
    EndSwitch
EndFunc

Func _Exit()
    Exit
EndFunc
发表于 2009-6-6 20:53:47 | 显示全部楼层
我想帮你解决可是我没那个能力  不要对论坛失望 最起码有人努力就好   看你技术应该不错  多帮帮大家 等大家都强了你在出问题 最坏 也能帮你多想几个办法啊
发表于 2009-6-27 01:38:27 | 显示全部楼层
不要对论坛失望
术业有专攻,每个人擅长的领域不一样
而你钻研出来的东西一定会带动更多人去研究这个应用领域
所以
千万别因为这样的小问题而选择失望
而是更多的分享更多的共同进步
 楼主| 发表于 2009-6-28 02:36:47 | 显示全部楼层
本帖最后由 passkalilo 于 2009-6-28 02:40 编辑

说的很好,论坛正是因为有你们这样一些愿意分享的人所以才更有希望,只有更多的分享才会有更多的进步,我也在论坛学到了不少东西,应该感谢论坛众多的热心人
发表于 2009-8-17 00:08:01 | 显示全部楼层
楼主能不能解释下啊,想学习一下,看不懂啊
发表于 2010-4-10 19:04:20 | 显示全部楼层
收藏了代码,以后备用
发表于 2010-6-4 21:54:03 | 显示全部楼层
学到了!!!!!!!!!!!!!
发表于 2010-6-11 10:19:57 | 显示全部楼层
这段有什么用/
发表于 2010-9-12 09:57:22 | 显示全部楼层
不要对论坛失望
术业有专攻,每个人擅长的领域不一样
而你钻研出来的东西一定会带动更多人去研究这个应用领域
所以
千万别因为这样的小问题而选择失望
而是更多的分享更多的共同进步

楼主能否加上注释啊
发表于 2010-9-12 13:44:38 | 显示全部楼层
Global $WM_POWERBROADCAST         = 536

Global $PBT_APMQUERYSUSPEND       = 0x0000

Global $PBT_APMQUERYSTANDBY       = 0x0001

Global $PBT_APMQUERYSUSPENDFAILED = 0x0002

Global $PBT_APMQUERYSTANDBYFAILED = 0x0003

Global $PBT_APMSUSPEND            = 0x0004

Global $PBT_APMSTANDBY            = 0x0005

Global $PBT_APMRESUMECRITICAL     = 0x0006

Global $PBT_APMRESUMESUSPEND      = 0x0007

Global $PBT_APMRESUMESTANDBY      = 0x0008

Global $PBT_APMBATTERYLOW         = 0x0009

Global $PBT_APMPOWERSTATUSCHANGE  = 0x000A

Global $PBT_APMOEMEVENT           = 0x000B

Global $PBT_APMRESUMEAUTOMATIC    = 0x0012

Global $PBTF_APMRESUMEFROMFAILURE = 0x00000001

Global $ES_DISPLAY_REQUIRED       = 0x00000002; zero the display's idle timer

Global $ES_SYSTEM_REQUIRED        = 0x00000001; zero the system's idle timer

Global $ES_CONTINUOUS             = 0x80000000; keep the display or system on (doesn't work?)
这些常量都不知道是干吗的
留待以后看吧  
或者楼主给注释下
发表于 2013-4-15 22:33:51 | 显示全部楼层
本帖最后由 yingde 于 2013-4-15 22:34 编辑

我现在也在学习API HOOK,想通过WH_CALLWNDPROC钩子——WM_DEVICECHANGE消息——检测U盘的插入、拔出。代码也像LZ原来的,也是一运行系统就崩溃了。由于是新手,研究了近2个星期也没有结果。后来用GUIRegisterMsg方式实现同样的目的(像4楼的代码),然后又回头研究WH_CALLWNDPROC,才发现问题出在原代码的第15行:
$hHook = _WinAPI_SetWindowsHookEx($WH_CALLWNDPROC, DllCallbackGetPtr($hSuspend), $hmod)
改为:
$hHook = _WinAPI_SetWindowsHookEx($WH_CALLWNDPROC, DllCallbackGetPtr($hSuspend), $hmod,_WinAPI_GetCurrentThreadId())
修改后能正常运行,但自己不确定是否是问题所在,望高手继续指正。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-11-17 23:24 , Processed in 0.086861 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表