-
-
Notifications
You must be signed in to change notification settings - Fork 48
feat(schedule): introduce schtasks-hide-window
option
#541
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
WalkthroughA new configuration option to hide the backup window when running scheduled tasks via Windows Task Scheduler has been introduced. This includes configuration, documentation, and logic to wrap the scheduled command with Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant ConfigLoader
participant ScheduleHandler
participant WindowsHandler
participant TaskScheduler
User->>ConfigLoader: Loads config with schedule-hide-window=true
ConfigLoader->>ScheduleHandler: Passes HideWindow flag
ScheduleHandler->>WindowsHandler: Calls CreateJob with HideWindow=true
WindowsHandler->>WindowsHandler: Wraps command in conhost.exe --headless
WindowsHandler->>TaskScheduler: Schedules job with modified command
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
✨ Finishing Touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
config/profile.go
(1 hunks)config/schedule.go
(3 hunks)schedule/config.go
(1 hunks)schedule/handler_windows.go
(1 hunks)schedule_jobs.go
(1 hunks)schtasks/config.go
(1 hunks)schtasks/taskscheduler.go
(1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: creativeprojects
PR: creativeprojects/resticprofile#459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the `schtasks` package, `tasksPath` is defined as a constant with value `\resticprofile backup\` in `taskscheduler.go`. It's used as a prefix for managing task paths in the Windows Task Scheduler.
schedule/handler_windows.go (1)
Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks
package, tasksPath
is defined as a constant with value \resticprofile backup\
in taskscheduler.go
. It's used as a prefix for managing task paths in the Windows Task Scheduler.
config/profile.go (1)
Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks
package, tasksPath
is defined as a constant with value \resticprofile backup\
in taskscheduler.go
. It's used as a prefix for managing task paths in the Windows Task Scheduler.
config/schedule.go (1)
Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks
package, tasksPath
is defined as a constant with value \resticprofile backup\
in taskscheduler.go
. It's used as a prefix for managing task paths in the Windows Task Scheduler.
schedule_jobs.go (1)
Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks
package, tasksPath
is defined as a constant with value \resticprofile backup\
in taskscheduler.go
. It's used as a prefix for managing task paths in the Windows Task Scheduler.
🔇 Additional comments (7)
schtasks/config.go (1)
12-12
: LGTM!The addition of the
HideWindow
boolean field to theConfig
struct is clean and follows the existing naming conventions.schedule/config.go (1)
26-26
: LGTM!The
SchtasksHideWindow
field is appropriately named to indicate its specific application to the schtasks scheduler, avoiding confusion with other hiding mechanisms.schedule_jobs.go (1)
240-240
: LGTM!The field assignment correctly propagates the configuration value using the
IsTrue()
method, consistent with the pattern used for other optional boolean fields in the same struct.schedule/handler_windows.go (1)
65-65
: LGTM!The field assignment correctly propagates the
SchtasksHideWindow
configuration from the schedule config to the schtasks config, maintaining the configuration flow through the scheduling layers.config/schedule.go (3)
48-48
: LGTM! Field declaration is properly structured.The field follows the established pattern with correct mapstructure tag, default value, and description.
95-97
: LGTM! Initialization logic is consistent.The initialization logic properly follows the pattern used by other
maybe.Bool
fields in the struct, checking if the value has been set and applying defaults when needed.
112-112
: LGTM! Override logic correctly implemented.The field assignment in
applyOverrides
follows the established pattern and correctly maps from the corresponding field inScheduleBaseSection
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
docs/content/schedules/configuration.md (1)
185-191
: Clarify scope, default, and OS prerequisites of the new flagThe paragraph does not mention (a) that the flag defaults to
false
, (b) that it has no effect underschedule-permission ≠ user_logged_on
, and (c) thatconhost.exe --headless
is available only on recent Windows versions (10 / Server 2019+). Stating these limitations up-front helps users avoid silent misconfiguration.Suggested tweak:
@@ -To prevent that, set this option to `true` to hide the task window by wrapping the execution in `conhost.exe --headless`. +Set this option to `true` to hide the task window by wrapping the execution in `conhost.exe --headless`. +This flag is honoured only when `schedule-permission` is `user_logged_on`; it is ignored (with a warning) for `system` or `user`. +`conhost.exe --headless` is supported starting with Windows 10 / Windows Server 2019 – on older versions the task will fail to start. +Default: `false`.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
config/profile.go
(1 hunks)docs/content/schedules/configuration.md
(1 hunks)schtasks/taskscheduler.go
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- config/profile.go
🚧 Files skipped from review as they are similar to previous changes (1)
- schtasks/taskscheduler.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: creativeprojects
PR: creativeprojects/resticprofile#459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the `schtasks` package, `tasksPath` is defined as a constant with value `\resticprofile backup\` in `taskscheduler.go`. It's used as a prefix for managing task paths in the Windows Task Scheduler.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.603Z
Learning: In the schtasks package, `config.Command` is guaranteed to be just a path to executable, making single quotes sufficient for wrapping in command construction.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.602Z
Learning: In the schtasks package, `config.Arguments` is already properly escaped by the caller, so additional escaping is not needed when constructing command arguments.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.603Z
Learning: In the schtasks package, double quotes cannot be used for command wrapping because `getTaskInfo` can't process them and unschedule commands fail when double quotes are used.
docs/content/schedules/configuration.md (3)
Learnt from: zumm
PR: #541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.602Z
Learning: In the schtasks package, config.Arguments
is already properly escaped by the caller, so additional escaping is not needed when constructing command arguments.
Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks
package, tasksPath
is defined as a constant with value \resticprofile backup\
in taskscheduler.go
. It's used as a prefix for managing task paths in the Windows Task Scheduler.
Learnt from: zumm
PR: #541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.603Z
Learning: In the schtasks package, double quotes cannot be used for command wrapping because getTaskInfo
can't process them and unschedule commands fail when double quotes are used.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #541 +/- ##
==========================================
+ Coverage 79.33% 79.66% +0.32%
==========================================
Files 136 136
Lines 13305 13404 +99
==========================================
+ Hits 10555 10677 +122
+ Misses 2332 2302 -30
- Partials 418 425 +7
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
schtasks/taskscheduler_test.go (3)
138-138
: Fix indentation inconsistency.Line 138 has incorrect indentation (appears to use tabs instead of spaces or vice versa).
Apply this diff to fix the indentation:
- found = true + found = true
140-141
: Consider using more descriptive assertion messages.The assertions could benefit from more descriptive messages to aid debugging when they fail.
Apply this diff to improve assertion messages:
- assert.Equal(t, registeredTask.Command, "conhost.exe") - assert.Equal(t, registeredTask.Arguments, "--headless 'echo' hello there") + assert.Equal(t, "conhost.exe", registeredTask.Command, "Command should be wrapped with conhost.exe when HideWindow is enabled") + assert.Equal(t, "--headless 'echo' hello there", registeredTask.Arguments, "Arguments should be prefixed with --headless when HideWindow is enabled")
125-125
: Consider testing the permission warning scenario.Based on the implementation in
taskscheduler.go
, a warning is logged whenHideWindow
is used with permissions other thanUserLoggedOnAccount
. Consider adding a test case to verify this behaviour for completeness.You could add a separate test function that uses a different permission type and captures the warning log output to ensure the warning is properly displayed.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
schtasks/taskscheduler.go
(1 hunks)schtasks/taskscheduler_test.go
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- schtasks/taskscheduler.go
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: creativeprojects
PR: creativeprojects/resticprofile#459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the `schtasks` package, `tasksPath` is defined as a constant with value `\resticprofile backup\` in `taskscheduler.go`. It's used as a prefix for managing task paths in the Windows Task Scheduler.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.603Z
Learning: In the schtasks package, `config.Command` is guaranteed to be just a path to executable, making single quotes sufficient for wrapping in command construction.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.602Z
Learning: In the schtasks package, `config.Arguments` is already properly escaped by the caller, so additional escaping is not needed when constructing command arguments.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.603Z
Learning: In the schtasks package, double quotes cannot be used for command wrapping because `getTaskInfo` can't process them and unschedule commands fail when double quotes are used.
schtasks/taskscheduler_test.go (1)
Learnt from: creativeprojects
PR: #459
File: schtasks/schtasks.go:29-30
Timestamp: 2025-02-14T22:53:42.689Z
Learning: In the schtasks
package, tasksPath
is defined as a constant with value \resticprofile backup\
in taskscheduler.go
. It's used as a prefix for managing task paths in the Windows Task Scheduler.
🧬 Code Graph Analysis (1)
schtasks/taskscheduler_test.go (3)
schtasks/config.go (1)
Config
(5-13)schtasks/taskscheduler.go (2)
Create
(36-112)Registered
(145-182)schtasks/permission.go (1)
UserLoggedOnAccount
(19-19)
🔇 Additional comments (1)
schtasks/taskscheduler_test.go (1)
110-148
: Well-structured test for the HideWindow feature.The test properly verifies that when
HideWindow: true
is set, the task command is wrapped withconhost.exe --headless
. The test setup, execution, and cleanup follow existing patterns in the file.
I decided to move |
I did some testing on old Windows 10 (very old, version 1607). It seems like conhost doesn't work here (it just doesn't run passed commands). Everything is good on my Windows 11 tho. Should we mention this in docs? |
Windows 10 support is ending in October so I'm not worried about no longer supporting it (although Microsoft might extend it) We should definitely mention it in the documentation though, thanks for testing it out 👍🏻 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
docs/content/schedules/configuration.md (2)
187-191
: Clarify the usage sentence and mention the default valueThe paragraph mixes the why and the how in one sentence and doesn’t state the default value. A slightly re-ordered wording improves readability and mirrors the phrasing used for the other options.
-To prevent that, set this option to `true` to hide the task window by wrapping the execution in `conhost.exe --headless`. +Set `schedule-hide-window = true` to prevent the task window from appearing. +When enabled, resticprofile wraps the command in `conhost.exe --headless`, which runs the task without showing a console window. +(Default: `false`)
194-196
: Fix missing preposition and keep spelling consistentMinor grammar and consistency touch-ups:
- Add the missing “to” after “According”.
- Use “Behavior”, as the document already employs American spelling earlier.
- Collapse the two sentences into one to remove repetition.
-Note: Behaviour of `conhost.exe` is not stable across Windows versions, so it may not work on some of them, especially older ones. -According our tests, it works on Windows 11 (version 24H2) and doesn't work on Windows 10 (version 1607). +Note: The behavior of `conhost.exe` varies between Windows versions. It has been confirmed to work on Windows 11 (24H2) but not on Windows 10 (1607) and earlier.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
docs/content/schedules/configuration.md
(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.636Z
Learning: In the schtasks package, `config.Arguments` is already properly escaped by the caller, so additional escaping is not needed when constructing command arguments.
Learnt from: zumm
PR: creativeprojects/resticprofile#541
File: schtasks/taskscheduler.go:60-67
Timestamp: 2025-07-29T16:14:02.636Z
Learning: In the schtasks package, `config.Command` is guaranteed to be just a path to executable, making single quotes sufficient for wrapping in command construction.
🪛 LanguageTool
docs/content/schedules/configuration.md
[grammar] ~194-~194: It appears that a preposition is missing after ‘According’.
Context: ...on some of them, especially older ones. According our tests, it works on Windows 11 (version ...
(MISSING_PREPOSITION)
Resolves #474
This pr introduces new
schedule-schtasks-hide-window
option. Option allows to hide task window by wrapping it inconhost --headless
.I chose name
schedule-schtasks-hide-window
overschedule-hidden
bczhidden
can be confused with schtasks built-in "hidden" feature (which hides task in the task manager UI).schtasks
prefix indicates that it works only with schtasks (likesystemd
insystemd-drop-in-files
option), i'm not sure if it's needed tho.I'm also not sure if
schtasks/tasksheduler/Create
good place for this logic.I will update docs if everyting is ok.