computer-use-ootb-internal 0.0.179__py3-none-any.whl → 0.0.181__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.
@@ -1,195 +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
- # 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.")
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.")
195
195
  print("Use 'ootb-install-service' or 'ootb-remove-service' as Administrator.")
@@ -1,48 +1,48 @@
1
- # Helper script to signal guard service about user connection
2
- # Save as e.g., ootb_lite_pypi/ootb_lite_pypi/src/computer_use_ootb_internal/signal_connection.py
3
- import sys
4
- import requests
5
- import logging
6
- import os
7
- import pathlib
8
-
9
- # Basic logging for the script itself
10
- LOG_DIR = pathlib.Path(os.environ.get('PROGRAMDATA', 'C:/ProgramData')) / "OOTBGuardService" / "SignalLogs"
11
- LOG_DIR.mkdir(parents=True, exist_ok=True)
12
- LOG_FILE = LOG_DIR / "signal_connection.log"
13
-
14
- logging.basicConfig(
15
- filename=LOG_FILE,
16
- level=logging.INFO,
17
- format='%(asctime)s %(levelname)s: %(message)s'
18
- )
19
-
20
- GUARD_SERVICE_URL = "http://localhost:14000/internal/user_connected"
21
-
22
- if __name__ == "__main__":
23
- if len(sys.argv) < 2:
24
- logging.error("Username argument missing.")
25
- sys.exit(1)
26
-
27
- username = sys.argv[1]
28
- logging.info(f"Signaling connection for user: {username}")
29
-
30
- payload = {"username": username}
31
-
32
- try:
33
- response = requests.post(GUARD_SERVICE_URL, json=payload, timeout=10)
34
- response.raise_for_status()
35
- logging.info(f"Successfully signaled connection for user {username}. Status: {response.status_code}")
36
- sys.exit(0)
37
- except requests.exceptions.ConnectionError:
38
- logging.error(f"Connection refused when trying to signal for user {username}. Guard service might not be running or accessible.")
39
- sys.exit(2)
40
- except requests.exceptions.Timeout:
41
- logging.error(f"Timeout when trying to signal for user {username}.")
42
- sys.exit(3)
43
- except requests.exceptions.RequestException as e:
44
- logging.error(f"Error signaling connection for user {username}: {e}")
45
- sys.exit(4)
46
- except Exception as e:
47
- logging.error(f"Unexpected error for user {username}: {e}")
1
+ # Helper script to signal guard service about user connection
2
+ # Save as e.g., ootb_lite_pypi/ootb_lite_pypi/src/computer_use_ootb_internal/signal_connection.py
3
+ import sys
4
+ import requests
5
+ import logging
6
+ import os
7
+ import pathlib
8
+
9
+ # Basic logging for the script itself
10
+ LOG_DIR = pathlib.Path(os.environ.get('PROGRAMDATA', 'C:/ProgramData')) / "OOTBGuardService" / "SignalLogs"
11
+ LOG_DIR.mkdir(parents=True, exist_ok=True)
12
+ LOG_FILE = LOG_DIR / "signal_connection.log"
13
+
14
+ logging.basicConfig(
15
+ filename=LOG_FILE,
16
+ level=logging.INFO,
17
+ format='%(asctime)s %(levelname)s: %(message)s'
18
+ )
19
+
20
+ GUARD_SERVICE_URL = "http://localhost:14000/internal/user_connected"
21
+
22
+ if __name__ == "__main__":
23
+ if len(sys.argv) < 2:
24
+ logging.error("Username argument missing.")
25
+ sys.exit(1)
26
+
27
+ username = sys.argv[1]
28
+ logging.info(f"Signaling connection for user: {username}")
29
+
30
+ payload = {"username": username}
31
+
32
+ try:
33
+ response = requests.post(GUARD_SERVICE_URL, json=payload, timeout=10)
34
+ response.raise_for_status()
35
+ logging.info(f"Successfully signaled connection for user {username}. Status: {response.status_code}")
36
+ sys.exit(0)
37
+ except requests.exceptions.ConnectionError:
38
+ logging.error(f"Connection refused when trying to signal for user {username}. Guard service might not be running or accessible.")
39
+ sys.exit(2)
40
+ except requests.exceptions.Timeout:
41
+ logging.error(f"Timeout when trying to signal for user {username}.")
42
+ sys.exit(3)
43
+ except requests.exceptions.RequestException as e:
44
+ logging.error(f"Error signaling connection for user {username}: {e}")
45
+ sys.exit(4)
46
+ except Exception as e:
47
+ logging.error(f"Unexpected error for user {username}: {e}")
48
48
  sys.exit(5)