Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Service Library Laravel Package

win32service/service-library

A PHP library for building and managing native Windows services. It provides a structured service base class, configuration, and lifecycle helpers on top of the win32service extension, making it simpler to run long-lived PHP daemons as Windows services.

View on GitHub
Deep Wiki
Context7

Getting Started

This library is the ergonomic layer on top of the win32service PECL extension — it gives you a driver class, service state/control wrappers, install/uninstall utilities, and a small CLI so you stop hand-rolling win32_start_service_ctrl_dispatcher() calls. It is Windows-only; you cannot exercise it from WSL or a Linux container.

Minimal path:

  1. Prerequisites — a Windows host (or Windows VM), PHP CLI, and the win32service extension enabled in php.ini. Confirm with php -m | findstr win32service. If it isn't loaded, nothing else works.
  2. composer require win32service/service-library (v1.1.0 or later — the documentation was rewritten in this release, so read the new README/docs before the blog posts you'll find via search).
  3. Look first at the ServiceDriver subclass example in the docs — that is the class you extend and the only place your application logic belongs. Skim the shipped CLI commands (install / uninstall / start / stop / status) second; they're the whole operational surface.
  4. First use case: take an existing long-running Artisan command (queue worker, poller, socket listener) and wrap it in a driver so it runs as a real Windows service — survives logoff, restarts on failure, and appears in services.msc.
  5. Prove it in a console first. Run the same PHP entry script directly (php bin\my-service.php) and watch it loop before you ever install it as a service. Debugging a service through the Event Log is an order of magnitude slower.

Implementation Patterns

Keep the driver thin, delegate to Laravel. The driver callbacks (onStart, onStop, onShutdown, onPreshutdown, pause/continue, interrogate) should bootstrap bootstrap/app.php, resolve the console kernel, and hand off — either Artisan::call('your:command') or the resolved command instance. Don't reimplement application wiring inside the callback.

Long-running loop pattern. Start the work, then loop on status checks with a sleep() tick so the service stays responsive to stop/pause requests. Anything that blocks indefinitely inside onStart makes the service unmanageable and eventually gets it killed by the SCM.

New in v1.1.0 — preshutdown. You can now accept SERVICE_CONTROL_PRESHUTDOWN, which gives you advance notice before the system begins shutting services down in force. Register the preshutdown handler and use it to flush buffers, close DB connections, and cancel in-flight jobs cleanly. It only fires on Vista / Server 2008 or newer, and it is subject to the separate preshutdown timeout — treat it as "finish quickly", not "second chance to do real work".

Install-time configuration as code. Drive install from a config file (service name, display name, description, binPath, dependencies, startup type, recovery/restart actions, service account) checked into the repo. Re-running install/uninstall must be idempotent — treat it as a deployment step, not a one-off manual action.

Logging is not optional. A Windows service has no console and no inherited stdout. Wire a Monolog file or rotating handler before anything else in onStart, with an absolute path and a directory the service account can write to. Everything you'd normally echo goes there.

Reconnect on restart. onStart can run many times over the service's life (recovery actions, reboots). Assume stale state: reconnect DB/cache clients, and use a mutex/lock file so a restart never leaves two worker instances competing for the same queue.

Recovery options are your supervisor. Configure restart-on-failure actions at install time rather than writing your own crash supervisor — that's what the SCM is for. The library's restart/recovery configuration is the integration point.

Operational flow: install → start → status → (deploy) stop → install → start. Script it for your deploy pipeline; don't click through services.msc.

Gotchas and Tips

  • The v1.1.0 function-signature change is a compatibility risk, not a feature. A win32service extension-facing signature was updated; if you're on an older extension build you can get type/signature errors that only appear at service runtime. Pin the extension version in your provisioning docs and test the upgrade on the target host, not just your dev box.
  • Elevation. Install/uninstall requires an elevated shell. start/stop may work unelevated, but don't build a workflow that depends on it.
  • LocalSystem is not you. The default service account has no UNC/network drive access and a different %PATH%, %USERPROFILE%, and working directory than your interactive shell. Absolute paths everywhere; set any required environment variables explicitly in the service config.
  • Quote the bin path. C:\Program Files\PHP\php.exe unquoted in the service binary path is a classic "service installs then immediately fails with error 1053" cause.
  • Stop timeout. The SCM kills a service that doesn't respond within its stop timeout. If onStop drains a queue, cap the drain and emit status checkpoints so the SCM sees progress.
  • Never exit()/die() inside a callback. Let the driver return; an uncaught exception in a callback can leave the SCM with a service stuck in STOP_PENDING until timeout.
  • Debug ladder: run the script in a console → sc query <name> / sc qc <name> for the SCM's view → Windows Event Viewer → application log file. Error 1053, 1064, and 1073 each point at a different one of the above (timeout, bad binPath, already-marked-for-deletion) — check the code before rewriting code.
  • Uninstall sometimes needs a reboot if handles are still open; don't loop on install failing with "marked for deletion".
  • CI reality. Unless you have Windows runners, this code path is untested in CI. Keep the driver a thin shell over platform-agnostic application code so the untested surface stays as small as possible.
  • Extension points: subclassing the driver, the static service utilities for scripted install/uninstall, and the bundled CLI commands (register your own Symfony-style command if the defaults don't fit). The v1.1.0 documentation rewrite is the best map of these — the release was largely docs + test-suite work plus the preshutdown addition, so there's no migration to perform beyond verifying your extension version.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator