|
你先听我分析。
前面哪个源码编译32位,无法启动。
后面我重新写了一个简单点的DLL服务框架。编译为64位。
注意重点:两次都没有执行 启动方法()
更近一步:
直接在dllmain函数下面写调试输出函数,任然无法得到消息。
那么这个错误究竟是这么回事呢??
- sc start MyService # 启动服务
- sc stop MyService # 停止服务
- sc delete MyService # 删除服务
复制代码
- # 创建服务
- sc create MyService binPath= "C:\Windows\System32\svchost.exe -k MyServiceGroup" type= share start= auto
- sc config MyService DisplayName= "My Unicode Service"
- # 注册DLL路径到注册表
- reg add "HKLM\SYSTEM\CurrentControlSet\Services\MyService\Parameters" /v ServiceDll /t REG_EXPAND_SZ /d "C:\Windows\System32\MyService.dll" /f
复制代码
- <火山程序 类型 = "通常" 版本 = 1 />
- 包 Voldp.ServiceDLL
- 类 启动类 <公开 基础类 = 程序类>
- {
- 方法 启动方法 <公开 类型 = 整数>
- {
- @ OutputDebugStringW(L"SEREVER START");
- ServiceDLL.MyServiceStart ()
- 返回 (1)
- }
- }
- 类 _SERVICE_STATUS <公开 折叠 折叠2 @别名类型 = 本地结构 @别名 = "SERVICE_STATUS">
- {
- 变量 服务类型 <公开 类型 = 整数 注释 = "0x00000001 SERVICE_KERNEL_DRIVER 该服务是设备驱动程序。"
- 注释 = "0x00000002 SERVICE_FILE_SYSTEM_DRIVER 该服务是文件系统驱动程序。"
- 注释 = "0x00000010 SERVICE_WIN32_OWN_PROCESS 服务在其自己的进程中运行。"
- 注释 = "0x00000020 SERVICE_WIN32_SHARE_PROCESS 该服务与其他服务共享一个进程。"
- 注释 = "0x00000050 SERVICE_USER_OWN_PROCESS 该服务在登录用户帐户下在其自己的进程中运行。"
- 注释 = "0x00000060 SERVICE_USER_SHARE_PROCESS 该服务与登录用户帐户下运行的一个或多个其他服务共享进程。"
- 注释 = "0x00000100 SERVICE_INTERACTIVE_PROCESS 该服务可以与桌面交互。有关详细信息,请参阅 Interactive Services。" 折叠 折叠2
- 编辑时信息 = "AD2C8, 0, 0, 0" @输出名 = "dwServiceType">
- 变量 当前状态 <公开 类型 = 整数 注释 = "0x00000001 SERVICE_STOPPED 服务未运行。"
- 注释 = "0x00000002 SERVICE_START_PENDING 服务正在启动。"
- 注释 = "0x00000003 SERVICE_STOP_PENDING 服务正在停止。"
- 注释 = "0x00000004 SERVICE_RUNNING 服务正在运行。"
- 注释 = "0x00000005 SERVICE_CONTINUE_PENDING 服务即将继续。"
- 注释 = "0x00000006 SERVICE_PAUSE_PENDING 服务即将暂停。"
- 注释 = "0x00000007 SERVICE_PAUSED 服务已暂停。" 折叠2 编辑时信息 = "AD2C8, 0, 0, 0"
- @输出名 = "dwCurrentState">
- 变量 控制代码 <公开 类型 = 整数
- 注释 = "0x00000001 SERVICE_ACCEPT_STOP 服务可以停止。此控制代码允许服务接收 SERVICE_CONTROL_STOP 通知。"
- 注释 = "0x00000002 SERVICE_ACCEPT_PAUSE_CONTINUE 服务可以暂停并继续。此控制代码允许服务接收 SERVICE_CONTROL_PAUSE 和 SERVICE_CONTROL_CONTINUE 通知。"
- 注释 = "0x00000004 SERVICE_ACCEPT_SHUTDOWN 系统关闭时,服务会收到通知。此控制代码允许服务接收 SERVICE_CONTROL_SHUTDOWN 通知。 请注意, ControlService 和 ControlServiceEx 无法发送此通知;只有系统可以发送它。"
- 注释 = "0x00000008 SERVICE_ACCEPT_PARAMCHANGE 该服务可以重新读取其启动参数,而无需停止和重启。此控制代码允许服务接收 SERVICE_CONTROL_PARAMCHANGE 通知。"
- 注释 = "0x00000010 SERVICE_ACCEPT_NETBINDCHANGE 该服务是一个网络组件,可以在不停止和重启的情况下接受其绑定中的更改。此控制代码允许服务接收 SERVICE_CONTROL_NETBINDADD、 SERVICE_CONTROL_NETBINDREMOVE、 SERVICE_CONTROL_NETBINDENABLE和 SERVICE_CONTROL_NETBINDDISABLE 通知。"
- 注释 = "0x00000100 SERVICE_ACCEPT_PRESHUTDOWN 该服务可以执行预执行任务。此控制代码使服务能够接收 SERVICE_CONTROL_PRESHUTDOWN 通知。 请注意, ControlService 和 ControlServiceEx 无法发送此通知;只有系统可以发送它。Windows Server 2003 和 Windows XP: 不支持此值。"
- 注释 = "0x00000020 SERVICE_ACCEPT_HARDWAREPROFILECHANGE 当计算机的硬件配置文件发生更改时,服务会收到通知。 这使系统能够向服务发送 SERVICE_CONTROL_HARDWAREPROFILECHANGE 通知。"
- 注释 = "0x00000040 SERVICE_ACCEPT_POWEREVENT 当计算机的电源状态发生更改时,服务会收到通知。 这使系统能够向服务发送 SERVICE_CONTROL_POWEREVENT 通知。"
- 注释 = "0x00000080 SERVICE_ACCEPT_SESSIONCHANGE 当计算机会话状态发生更改时,服务会收到通知。 这使系统能够向服务发送 SERVICE_CONTROL_SESSIONCHANGE 通知。"
- 注释 = "0x00000200 SERVICE_ACCEPT_TIMECHANGE 系统时间发生更改时,系统会通知服务。 这使系统能够向服务发送 SERVICE_CONTROL_TIMECHANGE 通知。Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支持此控制代码。"
- 注释 = "0x00000400 SERVICE_ACCEPT_TRIGGEREVENT 当发生服务已注册的事件时,服务会收到通知。 这使系统能够向服务发送 SERVICE_CONTROL_TRIGGEREVENT 通知。Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支持此控制代码。"
- 注释 = "0x00000800 SERVICE_ACCEPT_USERMODEREBOOT 当用户启动重新启动时,服务会收到通知。Windows Server 2008 R2、Windows 7、Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支持此控制代码。"
- 折叠2 编辑时信息 = "AD2C8, 0, 0, 0" @输出名 = "dwControlsAccepted">
- 变量 错误代码 <公开 类型 = 整数
- 注释 = "服务用于报告启动或停止时发生的错误的错误代码。 若要返回特定于服务的错误代码,服务必须将此值设置为 ERROR_SERVICE_SPECIFIC_ERROR 以指示 dwServiceSpecificExitCode 成员包含错误代码。 服务在运行时和正常终止时,应将此值设置为 NO_ERROR 。"
- 编辑时信息 = "AD2C8, 0, 0, 0" @输出名 = "dwWin32ExitCode">
- 变量 错误代码2 <公开 类型 = 整数
- 注释 = "服务启动或停止时发生错误时服务返回的特定于服务的错误代码。 除非 dwWin32ExitCode 成员设置为 ERROR_SERVICE_SPECIFIC_ERROR,否则将忽略此值。"
- 编辑时信息 = "AD2C8, 0, 0, 0" @输出名 = "dwServiceSpecificExitCode">
- 变量 检查点值 <公开 类型 = 整数
- 注释 = "服务定期递增的检查点值,以在长时间的启动、停止、暂停或继续操作期间报告其进度。 例如,当服务在启动时完成初始化的每个步骤时,应递增此值。 在服务上调用操作的用户界面程序使用此值在长时间操作期间跟踪服务的进度。 此值无效,当服务没有挂起的启动、停止、暂停或继续操作时,此值应为零。"
- 编辑时信息 = "AD2C8, 0, 0, 0" @输出名 = "dwCheckPoint">
- 变量 等待时间 <公开 类型 = 整数
- 注释 = "挂起的启动、停止、暂停或继续操作所需的估计时间(以毫秒为单位)。 在指定的时间量过去之前,服务应使用递增的 dwCheckPoint 值或 dwCurrentState 中的更改对 SetServiceStatus 函数进行下一次调用。 如果 dwWaitHint 指定的时间量通过,并且 dwCheckPoint 未递增或 dwCurrentState 未更改,则服务控制管理器或服务控制程序可以假定发生了错误,并且服务应停止。 但是,如果服务与其他服务共享进程,则服务控制管理器无法终止服务应用程序,因为它必须终止共享进程的其他服务。"
- 编辑时信息 = "AD2C8, 0, 0, 0" @输出名 = "dwWaitHint">
- #
- }
- 类 _SERVICE_TABLE_ENTRYW <公开 折叠 折叠2 @别名类型 = 本地结构 @别名 = "SERVICE_TABLE_ENTRYW">
- {
- 变量 服务名称 <公开 类型 = 变整数 注释 = "要在此服务进程中运行的服务的名称。"
- 注释 = "如果服务随SERVICE_WIN32_OWN_PROCESS服务类型一起安装,则忽略此成员,但不能为 NULL。 此成员可以是空字符串(“)。"
- 注释 = "如果服务随SERVICE_WIN32_SHARE_PROCESS服务类型一起安装,则此成员指定使用由 lpServiceProc 成员指向的 ServiceMain 函数的服务的名称。"
- 折叠 折叠2 @输出名 = "lpServiceName">
- 变量 服务入口 <公开 类型 = 变整数 注释 = "指向 ServiceMain 函数的指针。" @输出名 = "lpServiceProc">
- #
- }
- 类 ServiceDLL <公开 @视窗.外部头文件 = "<strsafe.h>">
- {
- 常量 SERVICE_BOOT_START <公开 类型 = 整数 值 = 0 注释 = "用于由系统加载器创建的设备驱动程序。只能用于驱动服务程序。" 折叠>
- 常量 SERVICE_SYSTEM_START <公开 类型 = 整数 值 = 1 注释 = "用于由IoInitSystem函数创建的设备驱动程序。">
- 常量 SERVICE_AUTO_START <公开 类型 = 整数 值 = 2 注释 = "系统启动时由服务控制管理器自动启动该服务程序。">
- 常量 SERVICE_DEMAND_START <公开 类型 = 整数 值 = 3 注释 = "由服务控制管理器(SCM)启动的服务。">
- 常量 SERVICE_DISABLED <公开 类型 = 整数 值 = 4 注释 = "表示该服务不可启动。">
- # ==
- 常量 NO_ERROR <公开 类型 = 整数 值 = 0>
- # ==
- 常量 SERVICE_KERNEL_DRIVER <公开 类型 = 整数 值 = @SERVICE_KERNEL_DRIVER 注释 = "该服务是设备驱动程序。" 折叠>
- 常量 SERVICE_FILE_SYSTEM_DRIVER <公开 类型 = 整数 值 = @SERVICE_FILE_SYSTEM_DRIVER 注释 = "该服务是文件系统驱动程序。">
- 常量 SERVICE_WIN32_OWN_PROCESS <公开 类型 = 整数 值 = @SERVICE_WIN32_OWN_PROCESS 注释 = "服务在其自己的进程中运行。">
- 常量 SERVICE_WIN32_SHARE_PROCESS <公开 类型 = 整数 值 = @SERVICE_WIN32_SHARE_PROCESS 注释 = "该服务与其他服务共享一个进程。">
- 常量 SERVICE_USER_OWN_PROCESS <公开 类型 = 整数 值 = @SERVICE_USER_OWN_PROCESS 注释 = "该服务在登录用户帐户下在其自己的进程中运行。">
- 常量 SERVICE_USER_SHARE_PROCESS <公开 类型 = 整数 值 = @SERVICE_USER_SHARE_PROCESS
- 注释 = "该服务与登录用户帐户下运行的一个或多个其他服务共享进程。">
- 常量 SERVICE_INTERACTIVE_PROCESS <公开 类型 = 整数 值 = @SERVICE_INTERACTIVE_PROCESS
- 注释 = "该服务可以与桌面交互。有关详细信息,请参阅 Interactive Services。">
- # ==
- 常量 SERVICE_STOPPED <公开 类型 = 整数 值 = @SERVICE_STOPPED 注释 = "服务未运行。" 折叠>
- 常量 SERVICE_START_PENDING <公开 类型 = 整数 值 = @SERVICE_START_PENDING 注释 = "服务正在启动。">
- 常量 SERVICE_STOP_PENDING <公开 类型 = 整数 值 = @SERVICE_STOP_PENDING 注释 = "服务正在停止。">
- 常量 SERVICE_RUNNING <公开 类型 = 整数 值 = @SERVICE_RUNNING 注释 = "服务正在运行。">
- 常量 SERVICE_CONTINUE_PENDING <公开 类型 = 整数 值 = @SERVICE_CONTINUE_PENDING 注释 = "服务即将继续。">
- 常量 SERVICE_PAUSE_PENDING <公开 类型 = 整数 值 = @SERVICE_PAUSE_PENDING 注释 = "服务即将暂停。">
- 常量 SERVICE_PAUSED <公开 类型 = 整数 值 = @SERVICE_PAUSED 注释 = "服务已暂停。">
- # ==
- 常量 SERVICE_CONTROL_STOP <公开 类型 = 整数 值 = @SERVICE_CONTROL_STOP 注释 = "通知服务它应停止。"
- 注释 = "hService 句柄必须具有SERVICE_STOP访问权限。" 注释 = "将停止请求发送到服务后,不应向服务发送其他控件。" 折叠 折叠2>
- 常量 SERVICE_CONTROL_PAUSE <公开 类型 = 整数 值 = @SERVICE_CONTROL_PAUSE 注释 = "通知服务它应暂停。"
- 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。">
- 常量 SERVICE_CONTROL_CONTINUE <公开 类型 = 整数 值 = @SERVICE_CONTROL_CONTINUE 注释 = "通知暂停的服务应恢复。"
- 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。">
- 常量 SERVICE_CONTROL_INTERROGATE <公开 类型 = 整数 值 = @SERVICE_CONTROL_INTERROGATE
- 注释 = "通知服务它应将其当前状态信息报告给服务控制管理器。" 注释 = "hService 句柄必须具有SERVICE_INTERROGATE访问权限。"
- 注释 = "请注意,此控件通常并不有用,因为 SCM 知道服务的当前状态。">
- 常量 SERVICE_CONTROL_SHUTDOWN <公开 类型 = 整数 值 = @SERVICE_CONTROL_SHUTDOWN 注释 = "通知服务系统正在关闭,以便该服务可以执行清理任务。"
- 注释 = "请注意,注册 SERVICE_CONTROL_PRESHUTDOWN 通知的服务无法收到此通知,因为它们已停止。"
- 注释 = "如果服务接受此控制代码,则它必须在执行清理任务后停止并返回 NO_ERROR。" 注释 = "SCM 发送此控制代码后,不会向服务发送其他控制代码。" 注释 = ""
- 注释 = "有关详细信息,请参阅本主题的“备注”部分。">
- 常量 SERVICE_CONTROL_PARAMCHANGE <公开 类型 = 整数 值 = @SERVICE_CONTROL_PARAMCHANGE 注释 = "通知服务其启动参数已更改。"
- 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。">
- 常量 SERVICE_CONTROL_NETBINDADD <公开 类型 = 整数 值 = @SERVICE_CONTROL_NETBINDADD 注释 = "通知网络服务有用于绑定的新组件。"
- 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。" 注释 = "但是,此控制代码已弃用;请改用即插即用功能。">
- 常量 SERVICE_CONTROL_NETBINDREMOVE <公开 类型 = 整数 值 = @SERVICE_CONTROL_NETBINDREMOVE
- 注释 = "通知网络服务已删除用于绑定的组件。" 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。"
- 注释 = "但是,此控制代码已弃用;请改用即插即用功能。">
- 常量 SERVICE_CONTROL_NETBINDENABLE <公开 类型 = 整数 值 = @SERVICE_CONTROL_NETBINDENABLE 注释 = "通知网络服务已启用禁用的绑定。"
- 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。" 注释 = "但是,此控制代码已弃用;请改用即插即用功能。">
- 常量 SERVICE_CONTROL_NETBINDDISABLE <公开 类型 = 整数 值 = @SERVICE_CONTROL_NETBINDDISABLE
- 注释 = "通知网络服务其其中一个绑定已被禁用。" 注释 = "hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。"
- 注释 = "但是,此控制代码已弃用;请改用即插即用功能。">
- 常量 SERVICE_CONTROL_DEVICEEVENT <公开 类型 = 整数 值 = @SERVICE_CONTROL_DEVICEEVENT 注释 = "通知服务设备事件。"
- 注释 = "(服务必须已注册才能使用 RegisterDeviceNotification 函数接收这些通知。)" 注释 = "dwEventType 和 lpEventData 参数包含其他信息。">
- 常量 SERVICE_CONTROL_HARDWAREPROFILECHANGE <公开 类型 = 整数 值 = @SERVICE_CONTROL_HARDWAREPROFILECHANGE
- 注释 = "通知服务计算机的硬件配置文件已更改。" 注释 = "dwEventType 参数包含其他信息。">
- 常量 SERVICE_CONTROL_POWEREVENT <公开 类型 = 整数 值 = @SERVICE_CONTROL_POWEREVENT 注释 = "通知服务系统电源事件。"
- 注释 = "dwEventType 参数包含其他信息。" 注释 = "如果 dwEventType是PBT_POWERSETTINGCHANGE, 则 lpEventData 参数还包含其他信息。">
- 常量 SERVICE_CONTROL_SESSIONCHANGE <公开 类型 = 整数 值 = @SERVICE_CONTROL_SESSIONCHANGE 注释 = "通知服务会话更改事件。"
- 注释 = "请注意,仅当服务在登录尝试之前已完全加载时,才会收到用户登录的通知。" 注释 = "dwEventType 和 lpEventData 参数包含其他信息。">
- 常量 SERVICE_CONTROL_PRESHUTDOWN <公开 类型 = 整数 值 = @SERVICE_CONTROL_PRESHUTDOWN 注释 = "通知服务系统将关闭。"
- 注释 = "在系统关闭时,需要额外时间来执行超出严格时间限制的清理任务的服务可以使用此通知。"
- 注释 = "服务控制管理器将此通知发送给已注册此通知的应用程序,然后再将 SERVICE_CONTROL_SHUTDOWN 通知发送到已注册该通知的应用程序。"
- 注释 = "处理此通知的服务会阻止系统关闭,直到服务停止或通过 SERVICE_PRESHUTDOWN_INFO 指定的预超时间隔过期。"
- 注释 = "由于这会影响用户体验,因此只有在下次系统启动时绝对有必要避免数据丢失或长时间恢复时,服务才应使用此功能。" 注释 = ""
- 注释 = "Windows Server 2003 和 Windows XP: 不支持此值。">
- 常量 SERVICE_CONTROL_TIMECHANGE <公开 类型 = 整数 值 = @SERVICE_CONTROL_TIMECHANGE 注释 = "通知服务系统时间已更改。"
- 注释 = "lpEventData 参数包含其他信息。" 注释 = "不使用 dwEventType 参数。" 注释 = "Windows Server 2008"
- 注释 = "Windows Vista" 注释 = "Windows Server 2003" 注释 = "Windows XP" 注释 = "不支持此控制代码。">
- 常量 SERVICE_CONTROL_TRIGGEREVENT <公开 类型 = 整数 值 = @SERVICE_CONTROL_TRIGGEREVENT
- 注释 = "通知已注册服务 触发器事件的服务 该事件已发生。" 注释 = "Windows Server 2008" 注释 = "Windows Vista"
- 注释 = "Windows Server 2003" 注释 = "Windows XP" 注释 = "不支持此控制代码。">
- 常量 SERVICE_CONTROL_USERMODEREBOOT <公开 类型 = 整数 值 = @SERVICE_CONTROL_USERMODEREBOOT 注释 = "通知服务用户已启动重新启动。"
- 注释 = "Windows Server 2008 R2" 注释 = "Windows 7" 注释 = "Windows Server 2008" 注释 = "Windows Vista"
- 注释 = "Windows Server 2003" 注释 = "Windows XP" 注释 = "不支持此控制代码。">
- # ==
- 常量 SERVICE_ACCEPT_STOP <公开 类型 = 整数 值 = @SERVICE_ACCEPT_STOP 注释 = "服务可以停止。"
- 注释 = "此控制代码允许服务接收 SERVICE_CONTROL_STOP 通知。" 折叠 折叠2>
- 常量 SERVICE_ACCEPT_PAUSE_CONTINUE <公开 类型 = 整数 值 = @SERVICE_ACCEPT_PAUSE_CONTINUE 注释 = "服务可以暂停并继续。"
- 注释 = "此控制代码允许服务接收" 注释 = "SERVICE_CONTROL_PAUSE" 注释 = "SERVICE_CONTROL_CONTINUE 通知。">
- 常量 SERVICE_ACCEPT_SHUTDOWN <公开 类型 = 整数 值 = @SERVICE_ACCEPT_SHUTDOWN 注释 = "系统关闭时,服务会收到通知。"
- 注释 = "此控制代码允许服务接收 SERVICE_CONTROL_SHUTDOWN 通知。"
- 注释 = "请注意, ControlService 和 ControlServiceEx 无法发送此通知;" 注释 = "只有系统可以发送它。">
- 常量 SERVICE_ACCEPT_PARAMCHANGE <公开 类型 = 整数 值 = @SERVICE_ACCEPT_PARAMCHANGE
- 注释 = "该服务可以重新读取其启动参数,而无需停止和重启。" 注释 = "此控制代码允许服务接收 SERVICE_CONTROL_PARAMCHANGE 通知。">
- 常量 SERVICE_ACCEPT_NETBINDCHANGE <公开 类型 = 整数 值 = @SERVICE_ACCEPT_NETBINDCHANGE 注释 = "该服务是一个网络组件,"
- 注释 = "可以在不停止和重启的情况下接受其绑定中的更改。" 注释 = "此控制代码允许服务接收" 注释 = "SERVICE_CONTROL_NETBINDADD"
- 注释 = "SERVICE_CONTROL_NETBINDREMOVE" 注释 = "SERVICE_CONTROL_NETBINDENABLE"
- 注释 = "SERVICE_CONTROL_NETBINDDISABLE 通知。">
- 常量 SERVICE_ACCEPT_PRESHUTDOWN <公开 类型 = 整数 值 = @SERVICE_ACCEPT_PRESHUTDOWN 注释 = "该服务可以执行预执行任务。"
- 注释 = "此控制代码使服务能够接收" 注释 = "SERVICE_CONTROL_PRESHUTDOWN 通知。"
- 注释 = "请注意, ControlService 和 ControlServiceEx 无法发送此通知;" 注释 = "只有系统可以发送它。"
- 注释 = "Windows Server 2003 和 Windows XP: 不支持此值。">
- # --
- 常量 SERVICE_ACCEPT_HARDWAREPROFILECHANGE <公开 类型 = 整数 值 = @SERVICE_ACCEPT_HARDWAREPROFILECHANGE
- 注释 = "当计算机的硬件配置文件发生更改时,服务会收到通知。" 注释 = "这使系统能够向服务发送 SERVICE_CONTROL_HARDWAREPROFILECHANGE 通知。" 折叠 折叠2>
- 常量 SERVICE_ACCEPT_POWEREVENT <公开 类型 = 整数 值 = @SERVICE_ACCEPT_POWEREVENT 注释 = "当计算机的电源状态发生更改时,服务会收到通知。"
- 注释 = "这使系统能够向服务发送 SERVICE_CONTROL_POWEREVENT 通知。">
- 常量 SERVICE_ACCEPT_SESSIONCHANGE <公开 类型 = 整数 值 = @SERVICE_ACCEPT_SESSIONCHANGE
- 注释 = "当计算机会话状态发生更改时,服务会收到通知。" 注释 = "这使系统能够向服务发送 SERVICE_CONTROL_SESSIONCHANGE 通知。">
- 常量 SERVICE_ACCEPT_TIMECHANGE <公开 类型 = 整数 值 = @SERVICE_ACCEPT_TIMECHANGE 注释 = "系统时间发生更改时,系统会通知服务。"
- 注释 = "这使系统能够向服务发送 SERVICE_CONTROL_TIMECHANGE 通知。"
- 注释 = "Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支持此控制代码。">
- 常量 SERVICE_ACCEPT_TRIGGEREVENT <公开 类型 = 整数 值 = @SERVICE_ACCEPT_TRIGGEREVENT
- 注释 = "当发生服务已注册的事件时,服务会收到通知。" 注释 = "这使系统能够向服务发送 SERVICE_CONTROL_TRIGGEREVENT 通知。"
- 注释 = "Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 不支持此控制代码。">
- 常量 SERVICE_ACCEPT_USERMODEREBOOT <公开 类型 = 整数 值 = @SERVICE_ACCEPT_USERMODEREBOOT
- 注释 = "当用户启动重新启动时,服务会收到通知。" 注释 = "Windows Server 2008 R2" 注释 = "Windows 7" 注释 = "Windows Server 2008"
- 注释 = "Windows Vista" 注释 = "Windows Server 2003" 注释 = "Windows XP" 注释 = "不支持此控制代码。">
- 变量 g_StatusHandle <公开 静态 类型 = 变整数>
- 变量 g_ServiceStatus <公开 静态 类型 = _SERVICE_STATUS>
- #
- 方法 MyServiceStart <公开 静态 @视窗.输出 = 真 @输出名 = "MyServiceStart">
- {
- @ SERVICE_TABLE_ENTRYW DispatchTable[] = {
- @ { (LPWSTR)L"MyUnicodeService", (LPSERVICE_MAIN_FUNCTIONW)@<ServiceMain> },
- @ { nullptr, nullptr }
- @ };
- @ StartServiceCtrlDispatcherW(DispatchTable);
- }
- #
- 方法 ServiceMain <公开 静态 @禁止流程检查 = 真 @视窗.输出 = 真 @输出名 = "ServiceMain">
- 参数 argc <类型 = 整数>
- 参数 argv <类型 = 变整数>
- {
- @ // 注册服务控制处理函数
- @ @<g_StatusHandle> = (INT_P)RegisterServiceCtrlHandlerW(L"MyUnicodeService", (LPHANDLER_FUNCTION)@<ServiceCtrlHandler>);
- @ if (!@<g_StatusHandle>) {
- @ return;
- @ }
- @
- @ // 初始化服务状态
- @ @<g_ServiceStatus>.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- @ @<g_ServiceStatus>.dwCurrentState = SERVICE_START_PENDING;
- @ @<g_ServiceStatus>.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- @ @<g_ServiceStatus>.dwWin32ExitCode = NO_ERROR;
- @ SetServiceStatus((SERVICE_STATUS_HANDLE)@<g_StatusHandle>, &@<g_ServiceStatus>);
- @
- @ // 报告运行状态
- @ @<g_ServiceStatus>.dwCurrentState = SERVICE_RUNNING;
- @ SetServiceStatus((SERVICE_STATUS_HANDLE)@<g_StatusHandle>, &@<g_ServiceStatus>);
- @
- @ // 创建工作线程
- @ HANDLE hThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)@<_Service_Worker_Thread>, nullptr, 0, nullptr);
- // @ WaitForSingleObject(hThread, INFINITE);
- @
- // @ // 清理
- // @ CloseHandle(g_ServiceStopEvent);
- // @ @<g_ServiceStatus>.dwCurrentState = SERVICE_STOPPED;
- // @ SetServiceStatus((SERVICE_STATUS_HANDLE)g_StatusHandle, &@<g_ServiceStatus>);
- }
- 方法 ServiceCtrlHandler <公开 静态 @输出名 = "ServiceCtrlHandler">
- 参数 dwCtrl <类型 = 整数>
- {
- 分支判断 (dwCtrl)
- {
- 分支 (SERVICE_CONTROL_STOP)
- {
- 如果 (g_ServiceStatus.当前状态 != SERVICE_RUNNING)
- {
- 返回
- }
- g_ServiceStatus.当前状态 = SERVICE_STOP_PENDING
- @ SetServiceStatus((SERVICE_STATUS_HANDLE)@<g_StatusHandle>, &@<g_ServiceStatus>);
- }
- }
- }
- 方法 _Service_Worker_Thread <公开 静态>
- {
- 判断循环 (真)
- {
- 延时 (1000)
- @ SYSTEMTIME st;
- @ GetLocalTime(&st);
- @ wchar_t msg[100];
- @ StringCchPrintfW(msg, _countof(msg),L"Service is running: %02d:%02d:%02d", st.wHour, st.wMinute, st.wSecond);
- @ OutputDebugStringW(msg);
- }
- }
- #
- #
- #
- #
- #
- }
复制代码
|
|