# service 库模块帮助文档

<details>  <summary>说明</summary>  <p>
发布为 EXE 以后，在桌面上直接双击运行就会显示控制台。  
在控制台窗口按 <kbd>Y</kbd> 注册系统服务，按 <kbd>N</kbd> 卸载系统服务。
操作系统开机就会自动启动注册成功的后台服务。  

服务进程不能在用户桌面上直接显示界面，  
新系统在 ~~服务管理器中勾选 【允许与桌面交互】~~ 是无效的。  
但可以通过 service.msgbox,service.msgboxErr,service.msgboxTest 等函数向用户桌面发送对话框。

记录运行时数据或错误信息的一些方法：
- 使用 fsys.log 读写日志文件
- 简单写数据到文件可以使用 io.file.write 或 string.save 函数
- 可使用 JSON.save  函数将对象以 JSON 格式输出到文件。
</p></details>

## service 成员列表 <a id="service" href="#service">&#x23;</a>

NT 服务操作  
部分操作需要管理权限

### service.activeSessionId（) <a id="service.activeSessionId（)" href="#service.activeSessionId（)">&#x23;</a>
返回操作系统活动用户会话ID,  
更多会话控制请参考标准库 win.ts

### service.create(启动路径,服务名,显示全名,服务描述) <a id="service.create" href="#service.create">&#x23;</a>
创建服务,  
参数@1可为空,默认使用当前应用程序路径,  
其他可选参数未列出请查看函数源码

### service.delete("服务名") <a id="service.delete" href="#service.delete">&#x23;</a>
删除服务  
注意删除服务前最好关闭服务管理器

### service.each() <a id="service.each" href="#service.each">&#x23;</a>
[返回对象:ntsrvsta2Object](#ntsrvsta2Object)

### service.each(serviceType,serviceState,groupName) <a id="service.each" href="#service.each">&#x23;</a>

```aardio
for( serviceName,displayName,svrStatusProcess in service.each()){
    io.print(serviceName, displayName,svrStatusProcess.state) 
}
```

### service.eachSession（） <a id="service.eachSession（）" href="#service.eachSession（）">&#x23;</a>

```aardio
for id,station,state in service.eachSession(){
	if( state == 0 ) return id;/*遍历操作系统所有登录用户会话，  
id 为会话 ID，station 为会话名，state 为会话状态。  
state 为 0 表示登录激活状态，1 为已连接，4 为断开状态*/
}
```

### service.isExist("服务名") <a id="service.isExist" href="#service.isExist">&#x23;</a>
是否存在指定的服务

### service.isRunning("服务名") <a id="service.isRunning" href="#service.isRunning">&#x23;</a>
服务是否正在运行

### service.isStopped("服务名") <a id="service.isStopped" href="#service.isStopped">&#x23;</a>
服务是否已停止

### service.manager() <a id="service.manager" href="#service.manager">&#x23;</a>
[返回对象:ntsrvmgrObject](#ntsrvmgrObject)

### service.manager(desiredAccess,machineName,databaseName) <a id="service.manager" href="#service.manager">&#x23;</a>
创建管理器

### service.msgbox("文本","标题",等待超时值,样式) <a id="service.msgbox" href="#service.msgbox">&#x23;</a>
弹出对话框。  
返回用户操作 ID，如果不指定超时值则不等待用户操作，并总是返回 32001/*_IDASYNC*/。  
超时值以毫秒为单位，超时为 0 表示一直等待，。不指定超时则不等待用户操作。  
除参数 @1 以外，其他所有参数可选。  
如果参数 @1 是表对象，自动调用 table.tostring 序列化为文本。  
参数 @1 是其他类型则调用 tostring 转为字符串。  

可选参数 @4 可用字符串或数值指定图标样式（参考 _MB_ 前缀常量值，设为 0 去掉图标与提示音），可选字符串值：  
- "error","stop","hand" 错误图标  
- "question" 询问图标，显示是、否、取消按钮，返回值为 `6/*_IDYES*/,7/*_IDNO*/, 2/*_IDCANCEL*/` 之一。  
- "confirm","test" 询问图标，显示确定与取消按钮，返回值为 `1/*_IDOK*/,2/*_IDCANCEL*/` 之一。  
- "warn" 警告图标  
- "info" 信息图标。

### service.msgboxErr("文本","标题") <a id="service.msgboxErr" href="#service.msgboxErr">&#x23;</a>
弹出错误对话框。  
所有者窗口参数可选。  
如果参数 @1 是表对象，则自动调用 table.tostring 序列化为文本。  
其他类型调用 tostring 转为字符串。

### service.msgboxTest("文本","标题") <a id="service.msgboxTest" href="#service.msgboxTest">&#x23;</a>
返回布尔值表示用户是否按了“确定”按钮。  
标题，所有者窗口参数可选

### service.pause("服务名") <a id="service.pause" href="#service.pause">&#x23;</a>
暂停服务,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### service.registerCtrlThread() <a id="service.registerCtrlThread" href="#service.registerCtrlThread">&#x23;</a>
[返回对象:ntsrvsta2Object](#ntsrvsta2Object)

### service.registerCtrlThread(serviceName,handle) <a id="service.registerCtrlThread" href="#service.registerCtrlThread">&#x23;</a>

```aardio
service.registerCtrlThread( serviceName,function(control,eventType,pEventData){  

    }  
)
```

### service.restart("服务名",停止超时,启动超时) <a id="service.restart" href="#service.restart">&#x23;</a>
重新启动服务,成功返回 true ,  
超时以秒为单位，省略则不限时间等待操作完成  
停止超时达到时间后服务未正常停止则强制中断服务进程

### service.resume("服务名") <a id="service.resume" href="#service.resume">&#x23;</a>
暂停状态恢复运行,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### service.serviceName <a id="service.serviceName" href="#service.serviceName">&#x23;</a>
当前服务线程中运行的 NT 服务名，  
主线程应自行指定

### service.sessions() <a id="service.sessions" href="#service.sessions">&#x23;</a>
返回操作系统所有登录用户会话，  
更多会话控制请参考标准库 win.ts

### service.start("服务名") <a id="service.start" href="#service.start">&#x23;</a>
启动服务,  
成功返回 true,  
失败请使用 lasterr 函数获取错误信息

### service.startDispatchThread(服务回调函数表) <a id="service.startDispatchThread" href="#service.startDispatchThread">&#x23;</a>

```aardio
service.service.startDispatchThread(   
    服务名 = function(serviceName,argv){  
        import service;   
        var srvStatus = service.registerCtrlThread(serviceName,function(control,eventType,pEventData){   
            import service;   
            if( control == 0x1/*_SERVICE_CONTROL_STOP*/ ){    
                service.updateStatus({currentState = 0x1/*_SERVICE_STOPPED*/},owner.serviceName);   
            }   
        } )  

        srvStatus.controlsAccepted = 0x1/*_SERVICE_ACCEPT_STOP*/  
        srvStatus.currentState = 0x4/*_SERVICE_RUNNING*/;  
        service.updateStatus(srvStatus,serviceName)  

        /*服务运行代码*/  

        srvStatus.controlsAccepted = 0;  
        srvStatus.currentState = 0x1/*_SERVICE_STOPPED*/  
        service.updateStatus(srvStatus,serviceName)  
    }  
)
```

### service.stop("服务名") <a id="service.stop" href="#service.stop">&#x23;</a>
停止服务,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### service.stop("服务名",true) <a id="service.stop" href="#service.stop">&#x23;</a>
停止服务,如果失败就强制中断服务进程,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### service.terminate("服务名") <a id="service.terminate" href="#service.terminate">&#x23;</a>
强制中断服务进程,  
成功返回 true ,

### service.updateStatus(服务状态表,服务名) <a id="service.updateStatus" href="#service.updateStatus">&#x23;</a>
参数@1应是registerCtrlHandler函数的返回值,  
在CtrlHandler函数中指定部分需要更新的值即可

## ntsrvconfigObject 成员列表 <a id="ntsrvconfigObject" href="#ntsrvconfigObject">&#x23;</a>

### ntsrvconfigObject.binaryPathName <a id="ntsrvconfigObject.binaryPathName" href="#ntsrvconfigObject.binaryPathName">&#x23;</a>
`binaryPathName`

### ntsrvconfigObject.dependencies <a id="ntsrvconfigObject.dependencies" href="#ntsrvconfigObject.dependencies">&#x23;</a>
`dependencies`

### ntsrvconfigObject.displayName <a id="ntsrvconfigObject.displayName" href="#ntsrvconfigObject.displayName">&#x23;</a>
`displayName`

### ntsrvconfigObject.errorControl <a id="ntsrvconfigObject.errorControl" href="#ntsrvconfigObject.errorControl">&#x23;</a>
`errorControl`

### ntsrvconfigObject.loadOrderGroup <a id="ntsrvconfigObject.loadOrderGroup" href="#ntsrvconfigObject.loadOrderGroup">&#x23;</a>
`loadOrderGroup`

### ntsrvconfigObject.serviceStartName <a id="ntsrvconfigObject.serviceStartName" href="#ntsrvconfigObject.serviceStartName">&#x23;</a>
`serviceStartName`

### ntsrvconfigObject.serviceType <a id="ntsrvconfigObject.serviceType" href="#ntsrvconfigObject.serviceType">&#x23;</a>
`serviceType`

### ntsrvconfigObject.startType <a id="ntsrvconfigObject.startType" href="#ntsrvconfigObject.startType">&#x23;</a>
`startType`

### ntsrvconfigObject.tagId <a id="ntsrvconfigObject.tagId" href="#ntsrvconfigObject.tagId">&#x23;</a>
`tagId`

## ntsrvmgrObject 成员列表 <a id="ntsrvmgrObject" href="#ntsrvmgrObject">&#x23;</a>

### ntsrvmgrObject.changeConfig(serviceName,serviceType,startType) <a id="ntsrvmgrObject.changeConfig" href="#ntsrvmgrObject.changeConfig">&#x23;</a>
修改配置,其他可选参数未列出请查看函数源码

### ntsrvmgrObject.changeConfig2("服务名",配置项,配置值) <a id="ntsrvmgrObject.changeConfig2" href="#ntsrvmgrObject.changeConfig2">&#x23;</a>
修改配置  
配置值必须是结构体

### ntsrvmgrObject.changeDescription("服务名","说明") <a id="ntsrvmgrObject.changeDescription" href="#ntsrvmgrObject.changeDescription">&#x23;</a>
修改服务说明

### ntsrvmgrObject.close() <a id="ntsrvmgrObject.close" href="#ntsrvmgrObject.close">&#x23;</a>
关闭

### ntsrvmgrObject.control(serviceName,desiredAccess,control) <a id="ntsrvmgrObject.control" href="#ntsrvmgrObject.control">&#x23;</a>
控制服务

### ntsrvmgrObject.create(启动路径,服务名,显示全名) <a id="ntsrvmgrObject.create" href="#ntsrvmgrObject.create">&#x23;</a>
创建服务,其他可选参数未列出请查看函数源码

### ntsrvmgrObject.delete("服务名") <a id="ntsrvmgrObject.delete" href="#ntsrvmgrObject.delete">&#x23;</a>
删除服务  
注意删除服务前最好关闭服务管理器

### ntsrvmgrObject.eachDependent("服务名") <a id="ntsrvmgrObject.eachDependent" href="#ntsrvmgrObject.eachDependent">&#x23;</a>

```aardio
for(serviceName,displayName,serviceStatus in ntsrvmgrObject.eachDependent("/*指定服务名列出依赖此服务的服务*/") ){

}
```

### ntsrvmgrObject.eachDependent() <a id="ntsrvmgrObject.eachDependent" href="#ntsrvmgrObject.eachDependent">&#x23;</a>
[返回对象:ntsrvsta2Object](#ntsrvsta2Object)

### ntsrvmgrObject.isExist("服务名") <a id="ntsrvmgrObject.isExist" href="#ntsrvmgrObject.isExist">&#x23;</a>
是否存在指定的服务

### ntsrvmgrObject.isRunning("服务名") <a id="ntsrvmgrObject.isRunning" href="#ntsrvmgrObject.isRunning">&#x23;</a>
服务是否正在运行

### ntsrvmgrObject.isStopped("服务名") <a id="ntsrvmgrObject.isStopped" href="#ntsrvmgrObject.isStopped">&#x23;</a>
服务是否已停止

### ntsrvmgrObject.open(serviceName,desiredAccess) <a id="ntsrvmgrObject.open" href="#ntsrvmgrObject.open">&#x23;</a>
打开服务句柄

### ntsrvmgrObject.pause("服务名") <a id="ntsrvmgrObject.pause" href="#ntsrvmgrObject.pause">&#x23;</a>
暂停服务,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### ntsrvmgrObject.queryBinaryPathName("服务名") <a id="ntsrvmgrObject.queryBinaryPathName" href="#ntsrvmgrObject.queryBinaryPathName">&#x23;</a>
返回启动路径以及参数

### ntsrvmgrObject.queryConfig("服务名") <a id="ntsrvmgrObject.queryConfig" href="#ntsrvmgrObject.queryConfig">&#x23;</a>
返回配置

### ntsrvmgrObject.queryConfig() <a id="ntsrvmgrObject.queryConfig" href="#ntsrvmgrObject.queryConfig">&#x23;</a>
[返回对象:ntsrvconfigObject](#ntsrvconfigObject)

### ntsrvmgrObject.queryConfig2("服务名",配置项,配置值) <a id="ntsrvmgrObject.queryConfig2" href="#ntsrvmgrObject.queryConfig2">&#x23;</a>
获取配置  
配置值必须是结构体

### ntsrvmgrObject.queryDescription("服务名") <a id="ntsrvmgrObject.queryDescription" href="#ntsrvmgrObject.queryDescription">&#x23;</a>
返回服务说明

### ntsrvmgrObject.queryStatus("服务名") <a id="ntsrvmgrObject.queryStatus" href="#ntsrvmgrObject.queryStatus">&#x23;</a>
成功返回一个表示服务状态的表对象

### ntsrvmgrObject.queryStatus() <a id="ntsrvmgrObject.queryStatus" href="#ntsrvmgrObject.queryStatus">&#x23;</a>
[返回对象:ntsrvsta2Object](#ntsrvsta2Object)

### ntsrvmgrObject.resume("服务名") <a id="ntsrvmgrObject.resume" href="#ntsrvmgrObject.resume">&#x23;</a>
暂停状态恢复运行,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### ntsrvmgrObject.start("服务名") <a id="ntsrvmgrObject.start" href="#ntsrvmgrObject.start">&#x23;</a>
启动服务,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### ntsrvmgrObject.startAndWait("服务名",进程权限) <a id="ntsrvmgrObject.startAndWait" href="#ntsrvmgrObject.startAndWait">&#x23;</a>
启动服务并等待服务进程切换到运行状态,  
返回打开的进程对象（process 对象）,可选用参数@2指定进程访问权限

### ntsrvmgrObject.startAndWait() <a id="ntsrvmgrObject.startAndWait" href="#ntsrvmgrObject.startAndWait">&#x23;</a>
[返回对象:processObject](https://www.aardio.com/zh-cn/docs/library-reference/process/_.html#processObject)

### ntsrvmgrObject.startAutomatic("服务名") <a id="ntsrvmgrObject.startAutomatic" href="#ntsrvmgrObject.startAutomatic">&#x23;</a>
设置为自动启动

### ntsrvmgrObject.startDelayed("服务名",是否延时) <a id="ntsrvmgrObject.startDelayed" href="#ntsrvmgrObject.startDelayed">&#x23;</a>
设置为延时启动

### ntsrvmgrObject.startDisabled("服务名") <a id="ntsrvmgrObject.startDisabled" href="#ntsrvmgrObject.startDisabled">&#x23;</a>
设置为禁用

### ntsrvmgrObject.startManual("服务名") <a id="ntsrvmgrObject.startManual" href="#ntsrvmgrObject.startManual">&#x23;</a>
设置为手动启动

### ntsrvmgrObject.stop("服务名") <a id="ntsrvmgrObject.stop" href="#ntsrvmgrObject.stop">&#x23;</a>
停止服务,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### ntsrvmgrObject.stop("服务名",true) <a id="ntsrvmgrObject.stop" href="#ntsrvmgrObject.stop">&#x23;</a>
停止服务,如果失败就强制中断服务进程,  
成功返回 true ,  
失败请使用 lasterr 函数获取错误信息

### ntsrvmgrObject.terminate("服务名") <a id="ntsrvmgrObject.terminate" href="#ntsrvmgrObject.terminate">&#x23;</a>
强制中断服务进程,  
成功返回 true ,

### ntsrvmgrObject.wait("服务名",状态码) <a id="ntsrvmgrObject.wait" href="#ntsrvmgrObject.wait">&#x23;</a>
等待服务切换到指定状态  
状态码不指定时默认为 4/*_SERVICE_RUNNING*/  
成功返回一个表示服务状态的表对象

### ntsrvmgrObject.wait() <a id="ntsrvmgrObject.wait" href="#ntsrvmgrObject.wait">&#x23;</a>
[返回对象:ntsrvsta2Object](#ntsrvsta2Object)

## ntsrvsta2Object 成员列表 <a id="ntsrvsta2Object" href="#ntsrvsta2Object">&#x23;</a>

### ntsrvsta2Object.checkPoint <a id="ntsrvsta2Object.checkPoint" href="#ntsrvsta2Object.checkPoint">&#x23;</a>
`checkPoint`

### ntsrvsta2Object.controlsAccepted <a id="ntsrvsta2Object.controlsAccepted" href="#ntsrvsta2Object.controlsAccepted">&#x23;</a>
`controlsAccepted`

### ntsrvsta2Object.currentState <a id="ntsrvsta2Object.currentState" href="#ntsrvsta2Object.currentState">&#x23;</a>
`currentState`

### ntsrvsta2Object.processId <a id="ntsrvsta2Object.processId" href="#ntsrvsta2Object.processId">&#x23;</a>
`processId`

### ntsrvsta2Object.serviceFlags <a id="ntsrvsta2Object.serviceFlags" href="#ntsrvsta2Object.serviceFlags">&#x23;</a>
`processId`

### ntsrvsta2Object.serviceSpecificExitCode <a id="ntsrvsta2Object.serviceSpecificExitCode" href="#ntsrvsta2Object.serviceSpecificExitCode">&#x23;</a>
`serviceSpecificExitCode`

### ntsrvsta2Object.serviceType <a id="ntsrvsta2Object.serviceType" href="#ntsrvsta2Object.serviceType">&#x23;</a>
`serviceType`

### ntsrvsta2Object.state <a id="ntsrvsta2Object.state" href="#ntsrvsta2Object.state">&#x23;</a>
`state`

### ntsrvsta2Object.waitHint <a id="ntsrvsta2Object.waitHint" href="#ntsrvsta2Object.waitHint">&#x23;</a>
`waitHint`

### ntsrvsta2Object.win32ExitCode <a id="ntsrvsta2Object.win32ExitCode" href="#ntsrvsta2Object.win32ExitCode">&#x23;</a>
`win32ExitCode`

### 自动完成常量
_SERVICE_ACCEPT_HARDWAREPROFILECHANGE=0x20  
_SERVICE_ACCEPT_NETBINDCHANGE=0x10  
_SERVICE_ACCEPT_PARAMCHANGE=8  
_SERVICE_ACCEPT_PAUSE_CONTINUE=2  
_SERVICE_ACCEPT_POWEREVENT=0x40  
_SERVICE_ACCEPT_SESSIONCHANGE=0x80  
_SERVICE_ACCEPT_SHUTDOWN=4  
_SERVICE_ACCEPT_STOP=1  
_SERVICE_ACTIVE=1  
_SERVICE_ADAPTER=4  
_SERVICE_AUTO_START=2  
_SERVICE_BOOT_START=0  
_SERVICE_CHANGE_CONFIG=2  
_SERVICE_CONTINUE_PENDING=5  
_SERVICE_CONTROL_CONTINUE=3  
_SERVICE_CONTROL_HARDWAREPROFILECHANGE=0xC  
_SERVICE_CONTROL_INTERROGATE=4  
_SERVICE_CONTROL_NETBINDADD=7  
_SERVICE_CONTROL_NETBINDDISABLE=0xA  
_SERVICE_CONTROL_NETBINDENABLE=9  
_SERVICE_CONTROL_NETBINDREMOVE=8  
_SERVICE_CONTROL_PARAMCHANGE=6  
_SERVICE_CONTROL_PAUSE=2  
_SERVICE_CONTROL_POWEREVENT=0xD  
_SERVICE_CONTROL_SESSIONCHANGE=0xE  
_SERVICE_CONTROL_SHUTDOWN=5  
_SERVICE_CONTROL_STOP=1  
_SERVICE_DEMAND_START=3  
_SERVICE_DISABLED=4  
_SERVICE_FILE_SYSTEM_DRIVER=2  
_SERVICE_INACTIVE=2  
_SERVICE_INTERROGATE=0x80  
_SERVICE_KERNEL_DRIVER=1  
_SERVICE_PAUSED=7  
_SERVICE_PAUSE_CONTINUE=0x40  
_SERVICE_PAUSE_PENDING=6  
_SERVICE_RECOGNIZER_DRIVER=8  
_SERVICE_RUNNING=4  
_SERVICE_RUNS_IN_SYSTEM_PROCESS=1  
_SERVICE_START_PENDING=2  
_SERVICE_STOPPED=1  
_SERVICE_STOP_PENDING=3  
_SERVICE_SYSTEM_START=1  
_SERVICE_USER_DEFINED_CONTROL=0x100  
_SERVICE_WIN32=0x30  
_SERVICE_WIN32_OWN_PROCESS=0x10  
_SERVICE_WIN32_SHARE_PROCESS=0x20  
