文档库 最新最全的文档下载
当前位置:文档库 › 用纯AU3编写服务程序

用纯AU3编写服务程序

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

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[16]", $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[0])
EndFunc ;==>_StartServiceCtrlDispatcher

Func _SetServiceStatus($hServiceStatus, $pServiceStatus)
Local $iResult
$iResult = DllCall($hAdvApi32Dll, "int", "SetServiceStatus", "hWnd", $hServiceStatus, _
"ptr", $pServiceStatus)
Return SetError(_ServiceLastError(), 0, $iResult[0])
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[0])
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[0], _
"dword", $iFlags, "dword", $iSize)
Return $iResult[0]
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[0], _
"dword", 0, "ptr", $pBuffer)
If $iResult[0] Then $pBuffer = 0
Return $iResult[0]
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[0], _
"dword", 0, "ptr", $pBuffer)
Return $iResult[0]
EndFunc ;==>_ServiceHeapFree

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

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

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

相关文档