給点阳光 发表于 2012-5-24 11:37:45

[已解决]读不懂“用纯au3编写的服务程序”,在哪里加上我自己想实现的功能?

本帖最后由 給点阳光 于 2012-5-26 09:52 编辑

服务程序不像普通的用户程序,服务程序需要遵循特定的服务规则。就像用SC命令将Notepad.exe注册为服务再开启一样,会返回“服务没有及时响应(1503)”的错误。
下面的代码没有调用任何第三方,纯AU3实现。以下只是演示了一个合法服务程序的编写,代码不具备任何功能。先编译为exe,再用SC命令将此注册为服务,服务名称用AutoIt3Service,否则下面的代码没有任何意义。用services.msc或sc.exe执行开启、停止等操作,会发现这果真是一个合法服务程序。

#Region ;**** 参数创建于 ACNWrapper_GUI ****
#AutoIt3Wrapper_UseUpx=n
#EndRegion ;**** 参数创建于 ACNWrapper_GUI ****
Const $hAdvApi32Dll = DllOpen("AdvApi32.dll")
Const $hKernel32Dll = DllOpen("Kernel32.dll")

Const $tagSERVICE_TABLE_ENTRY = "ptr ServiceName;ptr ServiceMain"
Const $tagSERVICE_STATUS = "dword ServiceType;dword CurrentState;dword ControlsAccepted;dword Win32ExitCode;dword ServiceSpecificExitCode;dword CheckPoint;dword WaitHint"

Global $hServiceStatus, $tServiceStatus, $pServiceStatus
Global $hServiceMain, $pServiceMain, $tServiceTable, $pServiceTable
Global $hServiceHandlerEx, $pServiceHandlerEx

$hServiceMain = DllCallbackRegister("_ServiceMain", "none", "dword;ptr")
$pServiceMain = DllCallbackGetPtr($hServiceMain)

$hServiceHandlerEx = DllCallbackRegister("_ServiceHandlerEx", "dword", "dword;dword;ptr;ptr")
$pServiceHandlerEx = DllCallbackGetPtr($hServiceHandlerEx)

$pServiceTable = _ServiceHeapAlloc(32)
$tServiceTable = DllStructCreate($tagSERVICE_TABLE_ENTRY, $pServiceTable)
DllStructSetData($tServiceTable, "ServiceName", $pServiceTable + 16)
DllStructSetData($tServiceTable, "ServiceMain", $pServiceMain)

$tServiceName = DllStructCreate("char ServiceName", $pServiceTable + 16)
DllStructSetData($tServiceName, "ServiceName", "AutoIt3Service")

$tServiceStatus = DllStructCreate($tagSERVICE_STATUS)
$pServiceStatus = DllStructGetPtr($tServiceStatus)
DllStructSetData($tServiceStatus, "ServiceType", 16)
DllStructSetData($tServiceStatus, "ControlsAccepted", 3)

_StartServiceCtrlDispatcher($pServiceTable)


Func _StartServiceCtrlDispatcher($pServiceTable)
      Local $iResult
      $iResult = DllCall($hAdvApi32Dll, "int", "StartServiceCtrlDispatcher", "ptr", $pServiceTable)
      Return SetError(_ServiceLastError(), 0, $iResult)
EndFunc      ;==>_StartServiceCtrlDispatcher

Func _SetServiceStatus($hServiceStatus, $pServiceStatus)
      Local $iResult
      $iResult = DllCall($hAdvApi32Dll, "int", "SetServiceStatus", "hWnd", $hServiceStatus, _
                        "ptr", $pServiceStatus)
      Return SetError(_ServiceLastError(), 0, $iResult)
EndFunc      ;==>_SerServiceStatus

Func _RegisterServiceCtrlHandlerEx($sServiceName, $pHandlerEx, $pContext = 0)
      Local $iResult
      $iResult = DllCall($hAdvApi32Dll, "hWnd", "RegisterServiceCtrlHandlerEx", _
                        "str", $sServiceName, "ptr", $pHandlerEx, "ptr", $pContext)
      Return SetError(_ServiceLastError(), 0, $iResult)
EndFunc      ;==>_RegisterServiceCtrlHandlerEx

Func _ServiceHandlerEx($iRequest, $iEventType, $pEventData, $pContext)
      Switch $iRequest
      Case 1
                DllStructSetData($tServiceStatus, "CurrentState", 1)
                _SetServiceStatus($hServiceStatus, $pServiceStatus)
                Return 0
      Case 2
                DllStructSetData($tServiceStatus, "CurrentState", 7)
                _SetServiceStatus($hServiceStatus, $pServiceStatus)
                Return 0
      Case 3
                DllStructSetData($tServiceStatus, "CurrentState", 5)
                _SetServiceStatus($hServiceStatus, $pServiceStatus)
                Sleep(5000)
                DllStructSetData($tServiceStatus, "CurrentState", 4)
                _SetServiceStatus($hServiceStatus, $pServiceStatus)
                Return 0
      Case 4
                _SetServiceStatus($hServiceStatus, $pServiceStatus)
                Return 0
      EndSwitch
EndFunc      ;==>_ServiceHandlerEx

Func _ServiceHeapAlloc($iSize, $iFlags = 8)
      If $iSize < 1 Then Return SetError(87, 0, 0)

      Local $hHeap, $iResult

      $hHeap = DllCall($hKernel32Dll, "hWnd", "GetProcessHeap")
      $iResult = DllCall($hKernel32Dll, "ptr", "HeapAlloc", "hWnd", $hHeap, _
                        "dword", $iFlags, "dword", $iSize)
      Return $iResult
EndFunc      ;==>_ServiceHeapAlloc

Func _ServiceHeapFree(ByRef $pBuffer)
      If $pBuffer = 0 Then Return SetError(87, 0, 0)

      Local $iResult, $hHeap
      $hHeap = DllCall($hKernel32Dll, "hWnd", "GetProcessHeap")
      $iResult = DllCall($hKernel32Dll, "int", "HeapFree", "hWnd", $hHeap, _
                        "dword", 0, "ptr", $pBuffer)
      If $iResult Then $pBuffer = 0
      Return $iResult
EndFunc      ;==>_ServiceHeapFree

Func _ServiceHeapSize(ByRef $pBuffer)
      If $pBuffer = 0 Then Return SetError(87, 0, 0)

      Local $iResult, $hHeap
      $hHeap = DllCall($hKernel32Dll, "hWnd", "GetProcessHeap")
      $iResult = DllCall($hKernel32Dll, "int", "HeapSize", "hWnd", $hHeap, _
                        "dword", 0, "ptr", $pBuffer)
      Return $iResult
EndFunc      ;==>_ServiceHeapFree

Func _ServiceLastError()
      Local $iResult
      $iResult = DllCall($hKernel32Dll, "dword", "GetLastError")
      Return $iResult
EndFunc      ;==>_ServiceLastError

Func _ServiceMain($iNumberofArgs, $pArgs)
      $hServiceStatus = _RegisterServiceCtrlHandlerEx("AutoIt3Service", $pServiceHandlerEx)

      DllStructSetData($tServiceStatus, "CurrentState", 4)
      _SetServiceStatus($hServiceStatus, $pServiceStatus)
EndFunc      ;==>_ServiceMain



原来论坛已有人提过这样的问题,http://www.autoitx.com/forum.php?mod=viewthread&tid=18059&highlight=%B4%BFau3%2B%B7%FE%CE%F1%B3%CC%D0%F2

cfs43210 发表于 2012-5-24 11:59:15

gi me rrrwq d wdt wftc

netegg 发表于 2012-5-24 15:58:42

回复 1# 給点阳光
lz确定这代码是全的?

haijie1223 发表于 2012-5-24 16:24:36

谁知道你想在哪里加,你想干什么?

給点阳光 发表于 2012-5-25 10:38:28

回复給点阳光
lz确定这代码是全的?
netegg 发表于 2012-5-24 15:58 http://www.autoitx.com/images/common/back.gif

代码肯定正确,编译后的文件可以设为服务,我试过,只是这段程序并不实现具体功能,我希望可以改造一下,将自己想实现的功能加进去。

xms77 发表于 2012-5-25 12:40:28

回复 5# 給点阳光
那你到底要加入什么功能呢?还保密啊?

502762378 发表于 2012-5-25 17:55:09

P版为人解答过这个问题,你搜论坛了吗?

魔导 发表于 2012-5-25 19:03:08

回复 4# haijie1223


    果断锤死!{:1_283:}

haijie1223 发表于 2012-5-25 20:51:35

回复 8# 魔导


    难得你还记得这句话。。。

給点阳光 发表于 2012-5-26 09:46:41

P版为人解答过这个问题,你搜论坛了吗?
502762378 发表于 2012-5-25 17:55 http://www.autoitx.com/images/common/back.gif

好像是有,可惜我阅读权限不够。{:face (131):}

ooxxgod 发表于 2012-7-3 16:23:38

看下P版示例也搞不成

lovecity 发表于 2012-7-4 16:54:21

看下P版示例也搞不成
页: [1]
查看完整版本: [已解决]读不懂“用纯au3编写的服务程序”,在哪里加上我自己想实现的功能?