# Clarion Service example - XP to Win 11 - All Service Features

**URL:** <https://clarionhub.com/t/clarion-service-example-xp-to-win-11-all-service-features/8760>\
**Category:** code\
**Tags:** winapi, github\
**Created:** [November 5, 2025, 9:29pm UTC](https://clarionhub.com/t/clarion-service-example-xp-to-win-11-all-service-features/8760 "2025-11-05T21:29:59Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![RchdR](https://clarionhub.com/letter_avatar_proxy/v4/letter/r/d78d45/32.png) [@RchdR](https://clarionhub.com/u/RchdR)\
**Post date:** [November 5, 2025, 9:30pm UTC](https://clarionhub.com/t/clarion-service-example-xp-to-win-11-all-service-features/8760/1 "2025-11-05T21:30:00Z")

</div>

> **[GitHub - Intelligent-Silicon/ClarionService: Example of a Clarion Service Control Manager...](https://github.com/Intelligent-Silicon/ClarionService)**
>
> Example of a Clarion Service Control Manager HandlerEx

Comments and criticism always welcome. 😁

Edit.  
Only thing I cant get to work which causes the app/service to hang on Win11 25H2 is SERVICE\_CONTROL\_USERMODEREBOOT.

> **[Whats New in Services for Windows 8 - Win32 apps](https://learn.microsoft.com/en-us/windows/win32/services/what-s-new-in-services-for-windows-8)**
>
> Windows 8 and Windows Server 2012 include the following new capabilities for services.

Cant find anything in the MS docs and the LLM's have no suggestion either.

And its not a C6/C11 thing, because just compiled in C11 with the SERVICE\_CONTROL\_USERMODEREBOOT code enabled and it still hangs.

Edit2.  
I dont know if this is pertinent, but the Windows Rust rewrite has highlighted an issue with SERVICE\_CONTROL\_USERMODEREBOOT and `SERVICE_CONTROL_TIMECHANGE` so I dont know if there is anything going on behind the scenes with the Win32 API's.

At this stage I havent even explored the extra notifications that services can handle now, but if the Rust team in MS are having problems, this might explain mine.

Windows Rust comment

> <https://github.com/mullvad/windows-service-rs/pull/30#issuecomment-514955673>
>
> Found some pointer-related issues regard to the \`Send\` trait in the previous com…mits. Managed to fix them now.
> 
> Some limitations:
> 
> \- Turns out the \`SERVICE\_CONTROL\_DEVICEEVENT\` is some bit of complicated. So I drop the support for it currently. 
> \- Due to some missing parts from the \`winapi\` crate, \`SERVICE\_CONTROL\_TIMECHANGE\` control lacks its \`SERVICE\_TIMECHANGE\_INFO\` event data
> \- \`SERVICE\_CONTROL\_USERMODEREBOOT\` is also not supported for the same reason

Anyway, there's now code for Clarion to run an as upto date Service as is possible and it shows it can all be done in source without the need for the window's accept loop, and some clues on how to turn you clarion app into a COM object.

Edit3.  
If you enable the code, this is what you will see in DebugView. Note the GetLastError 13, invalid structure when the SERVICE\_CONTROL\_USERMODEREBOOT is used.

```auto
[12428] ServiceMain : SetServiceStatusControlsAccepted()
[12428] SetServiceStatusControlsAccepted : Start
[12428] SetServiceStatusControlsAccepted : pdwControlsAccepted (0)
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted = 0
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (0) = 0
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (1) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_STOP )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (3) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_PAUSE_CONTINUE )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (7) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_SHUTDOWN )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (15) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_PARAMCHANGE )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (31) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_NETBINDCHANGE )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (63) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_HARDWAREPROFILECHANGE )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (127) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_POWEREVENT )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (255) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_SESSIONCHANGE )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (511) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_PRESHUTDOWN )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (1023) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_TIMECHANGE )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (2047) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_TRIGGEREVENT )
[12428] SetServiceStatusControlsAccepted : GSS:dwControlsAccepted (4095) = Bor( GSS:dwControlsAccepted, ISEQ:SetServiceStatus:ControlsAccepted:SERVICE_ACCEPT_USERMODEREBOOT )
[12428] SetServiceStatusControlsAccepted : Start
[12428] ServiceMain : SetServiceStatus()
[12428] SetServiceStatus : Start
[12428] SetServiceStatus : GLO:RVBool (1) = ISWA_SetServiceStatus( GLLA:SetServiceStatus (1988903296), |
[12428] SetServiceStatus : GSCV:ServiceCtrlHandlerHandle (11192000), |
[12428] SetServiceStatus : Address( GSS:ServiceStatus (5700816) )
[12428] SetServiceStatus : GLO:RVBool (0) = ISWA_SetServiceStatus( GLLA:SetServiceStatus (1988903296), |
[12428] SetServiceStatus : GSCV:ServiceCtrlHandlerHandle (11192000), |
[12428] SetServiceStatus : Address( GSS:ServiceStatus (5700816) )
[12428] SetServiceStatus : Glo:LastError (13) = ISWA_GetLastError()
[12428] SetServiceStatus : GSS:dwServiceType (16)
[12428] SetServiceStatus : GSS:dwCurrentState (4)
[12428] SetServiceStatus : GSS:dwControlsAccepted (4095)
[12428] SetServiceStatus : GSS:dwWin32ExitCode (0)
[12428] SetServiceStatus : GSS:dwServiceSpecificExitCode (0)
[12428] SetServiceStatus : GSS:dwCheckPoint (0)
[12428] SetServiceStatus : GSS:dwWaitHint (0)
[12428] SetServiceStatus : End
[12428] ServiceMain : GWOS:RV:WaitObject:SignalEvent (0) = ISWA_WaitForMultipleObjectsEx( GLLA:WaitForMultipleObjectsEx (1985276240), |
[12428] ServiceMain : GWOE:Event:WaitObjectHandlesArrayCnt (18), |
[12428] ServiceMain : Address( GWOE:Event:WaitObjectHandlesArray (8403380) ), |
[12428] ServiceMain : False, |
[12428] ServiceMain : ISEQ:WaitObject:INFINITE (-1), |
[12428] ServiceMain : False )

```

Edit 4

Following on from hankbao's comment above, can confirm this does and does not work.

Change the time manually.  
The service event fires twice.  
The first event has the correct time,  
The second event shows the 1st event NEW date time in both OLD and NEW date time.

Change the Timezone, as if flying abroad, and the service event only fires once.  
The OLD and NEW date time both show the OLD date time.

> **[SERVICE\_TIMECHANGE\_INFO (winsvc.h) - Win32 apps](https://learn.microsoft.com/en-us/windows/win32/api/winsvc/ns-winsvc-service_timechange_info)**
>
> Contains system time change settings.
