computer-use-ootb-internal 0.0.165__py3-none-any.whl → 0.0.167__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- computer_use_ootb_internal/app_teachmode.py +558 -558
- computer_use_ootb_internal/computer_use_demo/animation/test_animation.py +39 -39
- computer_use_ootb_internal/computer_use_demo/tools/computer.py +7 -7
- computer_use_ootb_internal/guard_service.py +998 -922
- computer_use_ootb_internal/preparation/star_rail_prepare.py +99 -99
- computer_use_ootb_internal/run_teachmode_ootb_args.py +223 -223
- computer_use_ootb_internal/service_manager.py +194 -335
- computer_use_ootb_internal/signal_connection.py +47 -47
- computer_use_ootb_internal/test_click_0425.py +58 -0
- {computer_use_ootb_internal-0.0.165.dist-info → computer_use_ootb_internal-0.0.167.dist-info}/METADATA +8 -9
- {computer_use_ootb_internal-0.0.165.dist-info → computer_use_ootb_internal-0.0.167.dist-info}/RECORD +13 -13
- computer_use_ootb_internal-0.0.167.dist-info/entry_points.txt +2 -0
- computer_use_ootb_internal/launch_ootb_elevated.ps1 +0 -63
- computer_use_ootb_internal-0.0.165.dist-info/entry_points.txt +0 -4
- {computer_use_ootb_internal-0.0.165.dist-info → computer_use_ootb_internal-0.0.167.dist-info}/WHEEL +0 -0
@@ -1,336 +1,195 @@
|
|
1
|
-
# src/computer_use_ootb_internal/service_manager.py
|
2
|
-
import sys
|
3
|
-
import os
|
4
|
-
import inspect
|
5
|
-
import subprocess
|
6
|
-
import ctypes
|
7
|
-
import platform
|
8
|
-
import time
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
service_module
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
try:
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
#
|
81
|
-
if
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
print(
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
print(
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
if os.path.exists(shortcut_path):
|
196
|
-
try:
|
197
|
-
os.remove(shortcut_path)
|
198
|
-
print("Shortcut removed successfully.")
|
199
|
-
return True
|
200
|
-
except OSError as e:
|
201
|
-
print(f"Error removing shortcut: {e}", file=sys.stderr)
|
202
|
-
# Fallback attempt with PowerShell just in case of permission issues
|
203
|
-
ps_shortcut_path = shortcut_path.replace("'", "''")
|
204
|
-
ps_command = f"Remove-Item -Path '{ps_shortcut_path}' -Force -ErrorAction SilentlyContinue"
|
205
|
-
return _run_command([sys.executable, "-NoProfile", "-NonInteractive", "-Command", ps_command], verbose=False)
|
206
|
-
except Exception as e:
|
207
|
-
print(f"Unexpected error removing shortcut: {e}", file=sys.stderr)
|
208
|
-
return False
|
209
|
-
else:
|
210
|
-
print("Shortcut not found, no removal needed.")
|
211
|
-
return True
|
212
|
-
|
213
|
-
def install_and_start():
|
214
|
-
"""Installs and starts the Guard Service."""
|
215
|
-
print(f"Attempting to install service: '{_SERVICE_NAME}' ('{_SERVICE_DISPLAY_NAME}')")
|
216
|
-
# Step 1: Run the Python script to register the service class with SCM
|
217
|
-
install_success = False
|
218
|
-
try:
|
219
|
-
python_exe = sys.executable
|
220
|
-
service_script = get_service_module_path()
|
221
|
-
# Quote paths
|
222
|
-
python_exe_quoted = f'"{python_exe}"' if " " in python_exe else python_exe
|
223
|
-
service_script_quoted = f'"{service_script}"' if " " in service_script else service_script
|
224
|
-
# Use list for subprocess
|
225
|
-
install_cmd = [sys.executable, service_script, '--startup', 'auto', 'install']
|
226
|
-
print(f"Executing registration command: {' '.join(install_cmd)}")
|
227
|
-
# We need to check output/return code carefully
|
228
|
-
result = subprocess.run(install_cmd, capture_output=True, text=True, check=False, encoding='utf-8')
|
229
|
-
if result.stdout: print(f" Registration STDOUT: {result.stdout.strip()}")
|
230
|
-
if result.stderr: print(f" Registration STDERR: {result.stderr.strip()}")
|
231
|
-
# Check common success/already-installed messages or just return code 0?
|
232
|
-
# win32serviceutil often returns 0 even if service exists. Let's assume 0 is okay.
|
233
|
-
if result.returncode == 0:
|
234
|
-
print("Service registration command executed (might indicate success or already installed).")
|
235
|
-
install_success = True
|
236
|
-
else:
|
237
|
-
print(f"Service registration command failed (Exit Code {result.returncode}).", file=sys.stderr)
|
238
|
-
install_success = False
|
239
|
-
|
240
|
-
except FileNotFoundError as e:
|
241
|
-
print(f"Error finding Python or service script for registration: {e}", file=sys.stderr)
|
242
|
-
install_success = False
|
243
|
-
except Exception as e:
|
244
|
-
print(f"Unexpected error during service registration: {e}", file=sys.stderr)
|
245
|
-
install_success = False
|
246
|
-
|
247
|
-
if install_success:
|
248
|
-
print(f"\nRegistration command finished. Attempting to start service using 'sc start'...")
|
249
|
-
time.sleep(2) # Give SCM time
|
250
|
-
# Step 2: Use sc start
|
251
|
-
start_cmd = ['sc', 'start', _SERVICE_NAME]
|
252
|
-
start_success = _run_command(start_cmd, check_errors=False) # Don't fail script if start fails
|
253
|
-
|
254
|
-
# Optional: Query status after attempting start
|
255
|
-
time.sleep(3) # Wait a bit longer
|
256
|
-
query_cmd = ['sc', 'query', _SERVICE_NAME]
|
257
|
-
query_result = _run_command(query_cmd, capture_output=True, check_errors=False, verbose=False)
|
258
|
-
service_running = False
|
259
|
-
if query_result and query_result.stdout:
|
260
|
-
if "RUNNING" in query_result.stdout:
|
261
|
-
service_running = True
|
262
|
-
print(f"Service '{_SERVICE_NAME}' confirmed running.")
|
263
|
-
else:
|
264
|
-
print(f"Service '{_SERVICE_NAME}' status check returned:\n{query_result.stdout.strip()}")
|
265
|
-
else:
|
266
|
-
print("Warning: Could not query service status after start attempt.")
|
267
|
-
|
268
|
-
if start_success and service_running:
|
269
|
-
print(f"\nService '{_SERVICE_NAME}' installed/updated and started successfully.")
|
270
|
-
# Step 3: Create startup shortcut only if service started
|
271
|
-
print("Creating startup shortcut...")
|
272
|
-
_create_startup_shortcut()
|
273
|
-
elif start_success and not service_running:
|
274
|
-
print(f"\nService '{_SERVICE_NAME}' installed/updated. 'sc start' command succeeded but service is not in RUNNING state.", file=sys.stderr)
|
275
|
-
print(" Check logs or try starting manually.", file=sys.stderr)
|
276
|
-
else: # start_success was False
|
277
|
-
print(f"\nService '{_SERVICE_NAME}' installed/updated but 'sc start' command failed.", file=sys.stderr)
|
278
|
-
print(f" Check output above, service logs ('C:\ProgramData\OOTBGuardService\guard_post_mode.log'), or Windows Event Viewer.", file=sys.stderr)
|
279
|
-
else:
|
280
|
-
# This path is taken if the initial registration command failed critically
|
281
|
-
print(f"\nService '{_SERVICE_NAME}' registration failed critically. See errors above.", file=sys.stderr)
|
282
|
-
|
283
|
-
def stop_and_remove():
|
284
|
-
"""Stops and removes the Guard Service and associated resources."""
|
285
|
-
print(f"Attempting to remove Startup shortcut...")
|
286
|
-
_remove_startup_shortcut()
|
287
|
-
|
288
|
-
print(f"\nAttempting to stop service using 'sc stop'...")
|
289
|
-
# Run stop first, ignore errors (check_errors=False)
|
290
|
-
# run_service_command(['stop'], check_errors=False)
|
291
|
-
stop_cmd = ['sc', 'stop', _SERVICE_NAME]
|
292
|
-
_run_command(stop_cmd, check_errors=False)
|
293
|
-
time.sleep(3) # Give service time to stop
|
294
|
-
|
295
|
-
# Optional: Check if stopped
|
296
|
-
query_cmd = ['sc', 'query', _SERVICE_NAME]
|
297
|
-
query_result = _run_command(query_cmd, capture_output=True, check_errors=False, verbose=False)
|
298
|
-
service_exists = True # Assume it exists unless query fails specifically
|
299
|
-
if query_result:
|
300
|
-
if query_result.stderr and ("failed" in query_result.stderr.lower() or "does not exist" in query_result.stderr.lower()):
|
301
|
-
service_exists = False
|
302
|
-
print("Service does not appear to exist before removal attempt.")
|
303
|
-
elif query_result.stdout and "STOPPED" in query_result.stdout:
|
304
|
-
print("Service confirmed stopped.")
|
305
|
-
elif query_result.stdout:
|
306
|
-
print(f"Warning: Service state after stop attempt: {query_result.stdout.strip()}")
|
307
|
-
else:
|
308
|
-
print("Warning: Could not query service state after stop attempt.")
|
309
|
-
|
310
|
-
print(f"\nAttempting to remove service using 'sc delete'...")
|
311
|
-
# remove_success = run_service_command(['remove']) # Check if removal command itself failed
|
312
|
-
delete_cmd = ['sc', 'delete', _SERVICE_NAME]
|
313
|
-
delete_success = _run_command(delete_cmd, check_errors=False) # Ignore error if not found
|
314
|
-
|
315
|
-
# Always attempt task cleanup, even if service removal had issues
|
316
|
-
_cleanup_scheduled_tasks()
|
317
|
-
|
318
|
-
if delete_success:
|
319
|
-
# Check if it really doesn't exist now
|
320
|
-
time.sleep(1)
|
321
|
-
query_result_after = _run_command(query_cmd, capture_output=True, check_errors=False, verbose=False)
|
322
|
-
if query_result_after and query_result_after.stderr and ("failed" in query_result_after.stderr.lower() or "does not exist" in query_result_after.stderr.lower()):
|
323
|
-
print(f"\nService '{_SERVICE_NAME}' stopped (if running), removed successfully. Startup shortcut and logon tasks cleanup attempted.")
|
324
|
-
else:
|
325
|
-
print(f"\nService '{_SERVICE_NAME}' stop attempted. 'sc delete' command ran but service might still exist. Please check manually.", file=sys.stderr)
|
326
|
-
print(f" Startup shortcut and logon tasks cleanup attempted.", file=sys.stderr)
|
327
|
-
else:
|
328
|
-
# This might happen if sc delete failed for permission reasons etc.
|
329
|
-
print(f"\n'sc delete {_SERVICE_NAME}' command failed to execute properly.", file=sys.stderr)
|
330
|
-
print(f" Startup shortcut and logon tasks cleanup attempted.", file=sys.stderr)
|
331
|
-
print(f" Ensure the service was stopped first, or check permissions.", file=sys.stderr)
|
332
|
-
|
333
|
-
if __name__ == '__main__':
|
334
|
-
# Allow calling functions directly for testing if needed
|
335
|
-
print("This script provides service management commands.")
|
1
|
+
# src/computer_use_ootb_internal/service_manager.py
|
2
|
+
import sys
|
3
|
+
import os
|
4
|
+
import inspect
|
5
|
+
import subprocess
|
6
|
+
import ctypes
|
7
|
+
import platform
|
8
|
+
import time
|
9
|
+
|
10
|
+
# Constants need to match guard_service.py
|
11
|
+
_SERVICE_NAME = "OOTBGuardService"
|
12
|
+
_SERVICE_DISPLAY_NAME = "OOTB Guard Service"
|
13
|
+
_TASK_NAME_PREFIX = "OOTB_UserLogon_" # Must match guard_service.py
|
14
|
+
|
15
|
+
def is_admin():
|
16
|
+
"""Check if the script is running with administrative privileges."""
|
17
|
+
if platform.system() != "Windows":
|
18
|
+
return False # Only applicable on Windows
|
19
|
+
try:
|
20
|
+
return ctypes.windll.shell32.IsUserAnAdmin()
|
21
|
+
except:
|
22
|
+
return False
|
23
|
+
|
24
|
+
def get_service_module_path():
|
25
|
+
"""Gets the absolute path to the guard_service.py module."""
|
26
|
+
# Find the path relative to this script's location
|
27
|
+
# This assumes service_manager.py and guard_service.py are in the same installed package directory
|
28
|
+
try:
|
29
|
+
current_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
|
30
|
+
service_module = os.path.join(current_dir, "guard_service.py")
|
31
|
+
if not os.path.exists(service_module):
|
32
|
+
raise FileNotFoundError(f"guard_service.py not found adjacent to service_manager.py in {current_dir}")
|
33
|
+
return service_module
|
34
|
+
except Exception as e:
|
35
|
+
# Fallback if inspect fails (e.g., in some frozen environments)
|
36
|
+
# Try finding it relative to the script itself? Unreliable.
|
37
|
+
# Let's try sys.prefix - might work in standard venv/conda installs
|
38
|
+
try:
|
39
|
+
# sys.prefix points to the environment root (e.g., C:\path\to\env)
|
40
|
+
# Package likely installed in Lib\site-packages\<package_name>
|
41
|
+
# This depends heavily on installation layout
|
42
|
+
package_name = __name__.split('.')[0] # Should be 'computer_use_ootb_internal'
|
43
|
+
site_packages_path = os.path.join(sys.prefix, 'Lib', 'site-packages')
|
44
|
+
module_dir = os.path.join(site_packages_path, package_name)
|
45
|
+
service_module = os.path.join(module_dir, "guard_service.py")
|
46
|
+
if os.path.exists(service_module):
|
47
|
+
print(f"Warning: Found service module via sys.prefix fallback: {service_module}")
|
48
|
+
return service_module
|
49
|
+
else:
|
50
|
+
raise FileNotFoundError(f"guard_service.py not found via inspect or sys.prefix fallback (checked {module_dir})")
|
51
|
+
except Exception as fallback_e:
|
52
|
+
raise FileNotFoundError(f"Could not find guard_service.py using inspect ({e}) or sys.prefix ({fallback_e}). Check installation.")
|
53
|
+
|
54
|
+
|
55
|
+
def run_service_command(command_args, check_errors=True):
|
56
|
+
"""Runs the guard_service.py script with specified command-line args."""
|
57
|
+
if not is_admin():
|
58
|
+
print("Error: Administrative privileges are required to manage the service.", file=sys.stderr)
|
59
|
+
print("Please run this command from an Administrator Command Prompt or PowerShell.", file=sys.stderr)
|
60
|
+
return False
|
61
|
+
|
62
|
+
try:
|
63
|
+
python_exe = sys.executable # Use the same python that's running this script
|
64
|
+
service_script = get_service_module_path()
|
65
|
+
except FileNotFoundError as e:
|
66
|
+
print(f"Error: {e}", file=sys.stderr)
|
67
|
+
return False
|
68
|
+
|
69
|
+
# Quote paths if they contain spaces
|
70
|
+
if " " in python_exe and not python_exe.startswith('"'):
|
71
|
+
python_exe = f'"{python_exe}"'
|
72
|
+
if " " in service_script and not service_script.startswith('"'):
|
73
|
+
service_script = f'"{service_script}"'
|
74
|
+
|
75
|
+
# Construct command using list to avoid shell quoting issues
|
76
|
+
cmd = [sys.executable, get_service_module_path()] + command_args
|
77
|
+
print(f"Executing command: {' '.join(cmd)}")
|
78
|
+
|
79
|
+
try:
|
80
|
+
# Run the command. Use shell=False with list of args.
|
81
|
+
# Capture output to check for specific errors if needed, but print it too.
|
82
|
+
result = subprocess.run(cmd, capture_output=True, text=True, check=check_errors, encoding='utf-8')
|
83
|
+
if result.stdout:
|
84
|
+
print("Command STDOUT:")
|
85
|
+
print(result.stdout)
|
86
|
+
if result.stderr:
|
87
|
+
print("Command STDERR:")
|
88
|
+
print(result.stderr)
|
89
|
+
print(f"Command {' '.join(command_args)} executed successfully.")
|
90
|
+
return True
|
91
|
+
except FileNotFoundError as e:
|
92
|
+
print(f"Error: Could not find Python executable or service script during execution.", file=sys.stderr)
|
93
|
+
print(f" Details: {e}", file=sys.stderr)
|
94
|
+
return False
|
95
|
+
except subprocess.CalledProcessError as e:
|
96
|
+
print(f"Error executing service command {' '.join(command_args)} (Exit Code {e.returncode}).", file=sys.stderr)
|
97
|
+
if e.stdout:
|
98
|
+
print("Subprocess STDOUT:")
|
99
|
+
print(e.stdout)
|
100
|
+
if e.stderr:
|
101
|
+
print("Subprocess STDERR:")
|
102
|
+
print(e.stderr)
|
103
|
+
return False
|
104
|
+
except Exception as e:
|
105
|
+
print(f"An unexpected error occurred running service command: {e}", file=sys.stderr)
|
106
|
+
return False
|
107
|
+
|
108
|
+
# --- Add cleanup helpers ---
|
109
|
+
def _run_powershell_cleanup_command(command):
|
110
|
+
"""Executes a PowerShell command specifically for cleanup, ignoring most errors."""
|
111
|
+
if platform.system() != "Windows": return True # Skip on non-windows
|
112
|
+
print(f"Executing PowerShell Cleanup: {command}")
|
113
|
+
try:
|
114
|
+
# Use check=False, don't capture output unless needed for debug
|
115
|
+
subprocess.run(
|
116
|
+
["powershell.exe", "-NoProfile", "-NonInteractive", "-Command", command],
|
117
|
+
check=False, # Don't throw error if command fails (e.g., no tasks found)
|
118
|
+
stdout=subprocess.DEVNULL, # Suppress stdout
|
119
|
+
stderr=subprocess.DEVNULL # Suppress stderr
|
120
|
+
)
|
121
|
+
return True # Assume success for cleanup flow
|
122
|
+
except Exception as e:
|
123
|
+
print(f"Warning: PowerShell cleanup command failed: {e}", file=sys.stderr)
|
124
|
+
return False # Indicate potential issue
|
125
|
+
|
126
|
+
def _cleanup_scheduled_tasks():
|
127
|
+
"""Removes all OOTB user logon scheduled tasks."""
|
128
|
+
print("Attempting to remove any existing OOTB user logon scheduled tasks...")
|
129
|
+
# Use -like operator and wildcard
|
130
|
+
# Use try-catch within PowerShell for robustness
|
131
|
+
command = f"""
|
132
|
+
$tasks = Get-ScheduledTask | Where-Object {{ $_.TaskName -like '{_TASK_NAME_PREFIX}*' }}
|
133
|
+
if ($tasks) {{
|
134
|
+
Write-Host "Found $($tasks.Count) OOTB logon tasks to remove."
|
135
|
+
$tasks | Unregister-ScheduledTask -Confirm:$false -ErrorAction SilentlyContinue
|
136
|
+
Write-Host "OOTB logon task removal attempted."
|
137
|
+
}} else {{
|
138
|
+
Write-Host "No OOTB logon tasks found to remove."
|
139
|
+
}}
|
140
|
+
"""
|
141
|
+
_run_powershell_cleanup_command(command)
|
142
|
+
# --- End cleanup helpers ---
|
143
|
+
|
144
|
+
def install_and_start():
|
145
|
+
"""Installs and starts the Guard Service."""
|
146
|
+
print(f"Attempting to install service: '{_SERVICE_NAME}' ('{_SERVICE_DISPLAY_NAME}')")
|
147
|
+
# Call 'install' command first.
|
148
|
+
# We pass check_errors=True to stop if installation fails fundamentally.
|
149
|
+
install_success = run_service_command(['--startup', 'auto', 'install'], check_errors=True)
|
150
|
+
|
151
|
+
if install_success:
|
152
|
+
# Note: Even if install_success is True, pywin32 might have printed internal errors
|
153
|
+
# like 'service already installed'. We proceed to start anyway in that case.
|
154
|
+
print(f"\nInstallation command finished. Attempting to start service: '{_SERVICE_NAME}' (waiting a few seconds first)")
|
155
|
+
time.sleep(3) # Give SCM time to register the install/update
|
156
|
+
start_success = run_service_command(['start'], check_errors=True)
|
157
|
+
|
158
|
+
if start_success:
|
159
|
+
# Similar caveat: start might succeed according to subprocess, but pywin32 could print internal errors.
|
160
|
+
print(f"\nService '{_SERVICE_NAME}' install command executed and start command executed.")
|
161
|
+
print(f"Please verify service status in 'services.msc' and check logs.")
|
162
|
+
else:
|
163
|
+
# This path is taken if run_service_command returned False (subprocess error occurred)
|
164
|
+
print(f"\nService '{_SERVICE_NAME}' installed/updated but the 'start' command failed with an error.", file=sys.stderr)
|
165
|
+
print(f" Check output above, service logs ('C:\ProgramData\OOTBGuardService\guard_post_mode.log'), or Windows Event Viewer.", file=sys.stderr)
|
166
|
+
else:
|
167
|
+
# This path is taken if the initial 'install' command failed critically (subprocess error)
|
168
|
+
print(f"\nService '{_SERVICE_NAME}' installation failed critically. See errors above.", file=sys.stderr)
|
169
|
+
|
170
|
+
|
171
|
+
def stop_and_remove():
|
172
|
+
"""Stops and removes the Guard Service and associated scheduled tasks."""
|
173
|
+
print(f"Attempting to stop service: '{_SERVICE_NAME}' (will ignore errors if not running)")
|
174
|
+
# Run stop first, ignore errors (check_errors=False)
|
175
|
+
run_service_command(['stop'], check_errors=False)
|
176
|
+
time.sleep(2) # Give service time to stop
|
177
|
+
|
178
|
+
print(f"\nAttempting to remove service: '{_SERVICE_NAME}'")
|
179
|
+
remove_success = run_service_command(['remove']) # Check if removal command itself failed
|
180
|
+
|
181
|
+
# Always attempt task cleanup, even if service removal had issues
|
182
|
+
_cleanup_scheduled_tasks()
|
183
|
+
|
184
|
+
if remove_success:
|
185
|
+
print(f"\nService '{_SERVICE_NAME}' stopped (if running) and removed successfully. Associated logon tasks cleanup attempted.")
|
186
|
+
else:
|
187
|
+
print(f"\nService '{_SERVICE_NAME}' removal command failed.", file=sys.stderr)
|
188
|
+
# Make sure to mention cleanup was still attempted
|
189
|
+
print(f" Associated logon tasks cleanup attempted.", file=sys.stderr)
|
190
|
+
print(f" Ensure the service was stopped first, or check permissions.", file=sys.stderr)
|
191
|
+
|
192
|
+
if __name__ == '__main__':
|
193
|
+
# Allow calling functions directly for testing if needed
|
194
|
+
print("This script provides service management commands.")
|
336
195
|
print("Use 'ootb-install-service' or 'ootb-remove-service' as Administrator.")
|