Skip to content

Commit 2abaeff

Browse files
committed
WinMsg 1.0
0 parents  commit 2abaeff

17 files changed

Lines changed: 321 additions & 0 deletions

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/cmake-build-debug/
2+
/cmake-build-release/

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/.name

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/winmsg.iml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
cmake_minimum_required(VERSION 3.28)
2+
project(winmsg)
3+
4+
set(CMAKE_CXX_STANDARD 17)
5+
6+
set(CMAKE_CXX_FLAGS "-static-libgcc -static-libstdc++ -static")
7+
8+
add_executable(winmsg WIN32 src/main.cpp src/resource.h)
9+
target_sources(winmsg PRIVATE "res/winmsg.rc")

README.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
### WinMsg
2+
3+
This is a very basic Windows GUI application that takes a **message** to display and a **timeout** as the parameters
4+
and does exactly that. The message is displayed in the center of the black **full-screen** window in large white text,
5+
then the app exits automatically.
6+
7+
![Example](doc/screenshot.png)
8+
9+
I wrote it for [Sunshine](https://github.com/LizardByte/Sunshine) / [Moonlight](https://github.com/moonlight-stream)
10+
streaming as a companion application when running command-line tools on a host via Moonlight.
11+
12+
The common use case is to control the host PC state (**Shut down** / **Sleep** / **Hibernate**) with the tools
13+
like [NirCmd](https://www.nirsoft.net/utils/nircmd.html).
14+
15+
Instead of the black screen and an error dialog, if the connection is aborted unexpectedly, the user will see the
16+
message from this app, then the stream will close gracefully after the app exists.
17+
18+
This project page and documentation below also serve as a guide how to set up sleep/shutdown via Sunshine app
19+
shortcuts for Moonlight so that you can manually control your host state directly from a client.
20+
21+
Of course, there are other solutions for that:
22+
23+
- add an **Undo** command in Sunshine to run a tool that will suspend the PC when the app you stream exists
24+
- configure Windows Power profile to sleep/hibernate/shutdown after N minutes of inactivity
25+
- if streaming from Steam Deck,
26+
use [MoonDeck](https://github.com/FrogTheFrog/moondeck)/[MoonDeck Buddy](https://github.com/FrogTheFrog/moondeck-buddy)
27+
to control the PC state
28+
- for true nerds, use HomeAssistant with [HASS Agent](https://github.com/hass-agent/HASS.Agent) and
29+
a [WOL switch](https://www.home-assistant.io/integrations/wake_on_lan/) so that you can control the host PC via voice
30+
commands, HA dashboard, CLI and automations
31+
32+
While all the above will work just fine, sometimes you may want to manually force the streaming host to sleep directly
33+
from the client. That is where the blow guide should help.
34+
35+
### Usage
36+
37+
```
38+
winmsg.exe [<message>] [<timeout>]
39+
```
40+
41+
The message is the actual message to display, make sure to surround it with double quotes if it contains spaces.
42+
Timeout is the time in milliseconds to display the message. The app exits after timeout.
43+
44+
Example:
45+
46+
```commandline
47+
winmsg.exe "Going to sleep..." 5000
48+
```
49+
50+
This will show the "Going to sleep..." message in the center of the black screen and exit after 5 seconds (5000ms).
51+
52+
If no parameters are provided, the app will show the empty black screen with no text and exit after 5 seconds.
53+
54+
### Sample Sunshine Application configuration to suspend the PC via NirCmd
55+
56+
<details>
57+
<summary>Click to show the screenshot</summary>
58+
59+
![Sunshine Sleep App](doc/sunshine-app.png)
60+
</details>
61+
62+
Open Applications settings in Sunshine Web UI (`https://<sunshine-pc:47990/apps`), click **Add New**.
63+
64+
Make sure to download and install [NirCmd](https://www.nirsoft.net/utils/nircmd.html) so that it's available in your
65+
PATH (or adjust the **Detached Command** to use the full path to `nircmd.exe`). This app can do many things, including
66+
putting the PC in sleep mode (`standby` command), shutting down the PC (`exitwin shutdown`),
67+
rebooting (`exitwin reboot`), and [much more](https://www.nirsoft.net/utils/nircmd2.html#using).
68+
69+
In this example, we use the following command in the **Detached Commands** section (to be run in the background):
70+
71+
```commandline
72+
nircmd.exe cmdwait 20000 standby
73+
```
74+
75+
`cmdwait 20000` waits 20 seconds before forcing the PC to sleep, this allows Moonlight to disconnect properly and
76+
Sunshine to run "Undo" commands, if needed. Feel free to use a shorter delay.
77+
78+
As the main **Command** we use this 'winmsg.exe' tool to display a message and exit after timeout:
79+
80+
```commandline
81+
winmsg.exe "Sleeping..." 5000
82+
```
83+
84+
Recommended options:
85+
86+
- **Global Prep Commands**: _Disabled_ — this allows the command to run faster as the global Do/Undo commands will not
87+
run
88+
- **Continue streaming if the application exits quickly**: _Uncheck_ — the app will quick quickly anyway, we don't want
89+
any special handling by Sunshine
90+
- **Continue streaming until all app processes exit**: _Uncheck_ — also not needed for our case
91+
- **Exit Timeout**: 0 — for faster exit if forced by the client
92+
- `cmdwait` value should be greater than `winmsg` timeout (20000 > 5000 in this example)
93+
94+
If you run the configured **Sleep** app via Moonlight, it will start the streaming session, run the `nircmd.exe` in
95+
background with the timeout, run `winmsg.exe` as your main streaming app, you will see the specified message, after
96+
5 seconds the app will exit, Moonlight will close the streaming session and then the PC with Sunshine will go to sleep
97+
after ~15 more seconds.
98+
99+
<details>
100+
<summary>Click for Moonlight Sleep shortcut sample</summary>
101+
102+
![Sunshine Sleep App](doc/moonlight-app.png)
103+
</details>
104+
105+
### Compiling
106+
107+
This project can be built on Windows with [MinGW](https://www.mingw-w64.org/downloads/#mingw-builds)/CMake.
108+
109+
Inside `mingw64` shell, `cd` into the project root directory, then:
110+
111+
```commandline
112+
pacman -S mingw-w64-x86_64-ninja
113+
pacman -S mingw-w64-x86_64-cmake
114+
mkdir build
115+
cd build
116+
cmake ..
117+
cmake --build . --config Release
118+
```
119+
120+
`winmsg.exe` file will be in the `build` directory.
121+
122+
You can also use [JetBrains CLion IDE](https://www.jetbrains.com/clion/) to open this project and build it right away
123+
as it already comes with MinGW toolchain and CMake build tool.
124+
125+
Or just download the pre-compiled binary from the **Releases** page.

0 commit comments

Comments
 (0)