microsoft / microsoft/windows-rs

`windows-services` using the service parameter in the closure passed to run with standard library threads

Open
#3,694 3 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
Rust
Stars
12.8k
Forks
665
Avg merge
7h 9m
Merged PRs (30d)
70

Description

### Summary

I was experimenting with the latest release (0.25.0) of windows-services, but was struggling on how to use the service parameter passed to the callback. Rust rightfully points out I am leaking that parameter when I store the JoinHandle of the thread running my service code (so I can join it later). I saw the [example](https://github.com/microsoft/windows-rs/blob/master/crates/samples/services/thread/src/main.rs#L6-L20) but now I'm wondering if this is possible using the standard library's threads.

the compile error:

```
Compiling example-winsvc v0.1.0 (C:\Users\prussian\source\example-winsvc)
error[E0521]: borrowed data escapes outside of closure
--> src\main.rs:10:21
|
5 | let mut thread = None;
| ---------- `thread` declared here, outside of the closure body
...
8 | .run(|svc, comm| match comm {
| --- `svc` is a reference that is only valid in the closure body
9 | windows_services::Command::Start if thread.is_none() => {
10 | thread = Some(s.spawn(|| {
| ^^^^^^ `svc` escapes the closure body here

For more information about this error, try `rustc --explain E0521`.
error: could not compile `example-winsvc` (bin "example-winsvc") due to 1 previous error
```

### Crate manifest

```TOML
[package]
name = "example-winsvc"
version = "0.1.0"
edition = "2024"

[dependencies]
windows-services = "0.25"
```

### Crate code

```Rust
use windows_services::{Service, State};

fn main() {
std::thread::scope(|s| {
let mut thread = None;
if Service::new()
.can_stop()
.run(|svc, comm| match comm {
windows_services::Command::Start if thread.is_none() => {
thread = Some(s.spawn(|| {
println!("Hello, World!");
svc.set_state(State::Stopped);
}));
}
windows_services::Command::Stop => {
if let Some(jh) = thread.take() {
jh.join();
}
}
_ => (),
})
.is_err()
{
eprintln!("not running as service");
};
});
}
```

Contributor guide

Open the contributing guide

Research direction

Start by reproducing the supplied Rust example with windows-services 0.25 and standard-library scoped threads. Read the linked services/thread example and the Service::run API to determine whether the service parameter can be used by the spawned thread. Done means establishing and documenting a supported approach, or clearly documenting that this usage is not possible.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.