crystal-accomplice
Accomplice
Allows any Crystal language program to easily run as a Windows Service with minimal change, and continue to support running as a console application.
Handles the Windows Service API for you. Adding Windows Service support is as simple as adding the dependency on accomplice to your shard.yml file, and including a require "accomplice" line in your program.
Should you wish to add support for graceful shutdown, doing so requires minimal effort, either:
- Add
at_exithandlers to perform a graceful shutdown tasks, or - Use
Process.on_terminateto register your own interrupt signal handler to perform a graceful shutdown tasks and thenexit.
You can also continue to run your program manually via the console after the above change, without interference with the Windows Service API.
Installation
-
Add the dependency to your
shard.yml:dependencies: accomplice: github: lachlan/crystal-accomplice -
Run
shards install
Usage
- Require
accomplicein your program, and then optionally include logic to gracefully shutdown your program when interrupted:
require "accomplice"
# Accomplice converts Windows Service Control Manager stop/shutdown
# controls to CTRL-C (SIGINT) interrupt signals to request the program
# to stop.
# Accomplice also includes a default interrupt signal handler which
# calls `exit`, allowing `at_exit` handlers to be used to gracefully
# shutdown:
at_exit {
# ...perform graceful shutdown tasks...
}
# OR you can replace the default interrupt signal handler with your
# own by using `Process.on_terminate` with a handler that stops your
# program gracefully and then exits:
Process.on_terminate do |reason|
Log.info { "SHUTDOWN INITIATED BY PROCESS TERMINATION, REASON = #{reason}" }
# ...perform graceful shutdown tasks...
exit
end
# Then run your program's logic as per normal:
loop do
# ...do stuff...
sleep 1.second
end
-
Compile:
shards build -Dpreview_mt -Dexecution_contextA Windows Service necessarily requires at least two (2) threads:
- the service dispatcher thread, and
- at least one other thread to run the actual service logic.
This requires compiling your Crystal program with the following flags:
-Dpreview_mtto enable multithreading, and-Dexecution_contextto enable the new execution contexts.
-
Create Windows service (note: these commands need to be run as an Administrator):
sc create <ServiceName> binpath= <ExecutablePath>
sc config <ServiceName> start= <boot|system|auto|demand|disabled|delayed-auto>
sc config <ServiceName> DisplayName= "<Service Display Name>"
sc description <ServiceName> "<Service Description>"
- Run Windows service
sc start <ServiceName>
...
sc stop <ServiceName>
Contributing
- Fork it (https://github.com/your-github-user/crystal-accomplice/fork)
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
Contributors
- Lachlan Dowding - creator and maintainer
crystal-accomplice
- 0
- 0
- 0
- 0
- 0
- about 5 hours ago
- April 29, 2026
MIT License
Thu, 30 Apr 2026 02:51:12 GMT