computer-use-ootb-internal 0.0.126__tar.gz → 0.0.128__tar.gz

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.
Files changed (40) hide show
  1. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/PKG-INFO +1 -1
  2. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/pyproject.toml +1 -1
  3. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/guard_service.py +103 -149
  4. computer_use_ootb_internal-0.0.128/src/computer_use_ootb_internal/preparation/star_rail_prepare.py +65 -0
  5. computer_use_ootb_internal-0.0.126/deploy.sh +0 -10
  6. computer_use_ootb_internal-0.0.126/src/computer_use_ootb_internal/preparation/star_rail_prepare.py +0 -63
  7. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/.gitignore +0 -0
  8. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/README.md +0 -0
  9. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/__init__.py +0 -0
  10. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/app_teachmode.py +0 -0
  11. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/animation/click_animation.py +0 -0
  12. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/animation/icons8-select-cursor-transparent-96.gif +0 -0
  13. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/animation/test_animation.py +0 -0
  14. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/executor/teachmode_executor.py +0 -0
  15. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/__init__.py +0 -0
  16. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/gui_capture.py +0 -0
  17. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/simple_parser/utils.py +0 -0
  18. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/__init__.py +0 -0
  19. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_cli.py +0 -0
  20. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/gui_parser/uia_tools/screenshot_service.py +0 -0
  21. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/llm_utils.py +0 -0
  22. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/oai.py +0 -0
  23. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_litellm.py +0 -0
  24. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/gui_agent/llm_utils/run_llm.py +0 -0
  25. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/__init__.py +0 -0
  26. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/aws_request.py +0 -0
  27. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/base.py +0 -0
  28. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/bash.py +0 -0
  29. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/collection.py +0 -0
  30. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/colorful_text.py +0 -0
  31. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/computer.py +0 -0
  32. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/computer_marbot.py +0 -0
  33. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/edit.py +0 -0
  34. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/run.py +0 -0
  35. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py +0 -0
  36. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/dependency_check.py +0 -0
  37. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/preparation/__init__.py +0 -0
  38. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/requirements-lite.txt +0 -0
  39. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/run_teachmode_ootb_args.py +0 -0
  40. {computer_use_ootb_internal-0.0.126 → computer_use_ootb_internal-0.0.128}/src/computer_use_ootb_internal/service_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: computer-use-ootb-internal
3
- Version: 0.0.126
3
+ Version: 0.0.128
4
4
  Summary: Computer Use OOTB
5
5
  Author-email: Siyuan Hu <siyuan.hu.sg@gmail.com>
6
6
  Requires-Python: >=3.11
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "computer-use-ootb-internal"
7
- version = "0.0.126"
7
+ version = "0.0.128"
8
8
  description = "Computer Use OOTB"
9
9
  authors = [{ name = "Siyuan Hu", email = "siyuan.hu.sg@gmail.com" }]
10
10
  requires-python = ">=3.11"
@@ -104,6 +104,8 @@ def receive_command():
104
104
 
105
105
  # --- End PowerShell Task Scheduler Helpers ---
106
106
 
107
+ TARGET_EXECUTABLE_NAME = "computer-use-ootb-internal.exe"
108
+
107
109
  class GuardService(win32serviceutil.ServiceFramework):
108
110
  _svc_name_ = _SERVICE_NAME
109
111
  _svc_display_name_ = _SERVICE_DISPLAY_NAME
@@ -134,145 +136,43 @@ class GuardService(win32serviceutil.ServiceFramework):
134
136
  # --- End Instance Logging ---
135
137
 
136
138
  # --- Instance Helper Methods (Moved from module level) ---
137
- def get_base_python_executable(self):
138
- """Tries to find python.exe instead of pythonservice.exe if running as service."""
139
- service_exe = sys.executable
140
- self.log_info(f"get_base_python_executable: sys.executable is {service_exe}")
141
- # Normalize path for comparison
142
- service_exe_lower = service_exe.lower()
143
-
144
- # Check if running as pythonservice.exe
145
- if 'pythonservice.exe' in os.path.basename(service_exe_lower):
146
- # Construct expected python.exe path in the same directory
147
- dir_name = os.path.dirname(service_exe)
148
- potential_python_exe = os.path.join(dir_name, 'python.exe')
149
- self.log_info(f"get_base_python_executable: Checking for python.exe at {potential_python_exe}")
150
-
151
- if os.path.exists(potential_python_exe):
152
- self.log_info(f"get_base_python_executable: Found python.exe at {potential_python_exe}")
153
- # Quote if necessary
154
- final_exe = potential_python_exe
155
- if " " in final_exe and not final_exe.startswith('"'):
156
- return f'"{final_exe}"'
157
- return final_exe
158
- else:
159
- self.log_error(f"get_base_python_executable: Could not find python.exe near pythonservice.exe (checked {potential_python_exe}). Falling back to using {service_exe}.")
160
- # Fallback to original sys.executable (quoted if needed)
161
- if " " in service_exe and not service_exe.startswith('"'):
162
- return f'"{service_exe}"'
163
- return service_exe
164
- else: # Not running as pythonservice.exe, assume sys.executable is correct
165
- self.log_info(f"get_base_python_executable: sys.executable is not pythonservice.exe, using it directly.")
166
- if " " in service_exe and not service_exe.startswith('"'):
167
- return f'"{service_exe}"'
168
- return service_exe
169
-
170
- def get_python_executable(self):
171
- # This method is now just an alias for clarity if needed elsewhere,
172
- # but primary logic uses get_base_python_executable directly.
173
- # Keep for potential compatibility if anything still calls it.
174
- return self.get_base_python_executable()
175
-
176
- def get_pip_executable(self):
177
- """Tries to locate the pip executable in the same environment."""
139
+ def _find_target_executable(self):
140
+ """Finds the target executable (e.g., computer-use-ootb-internal.exe) in the Scripts directory."""
178
141
  try:
179
- # Use the potentially corrected python path to find pip's location
180
- # Note: This assumes pip is relative to python.exe, not pythonservice.exe
181
- base_python = self.get_base_python_executable()
182
- python_path = pathlib.Path(base_python.strip('"')) # Use unquoted path
183
- pip_path = python_path.parent / "Scripts" / "pip.exe"
184
- self.log_info(f"get_pip_executable: Checking for pip relative to {python_path.parent} at {pip_path}")
185
-
186
- if pip_path.exists():
187
- self.log_info(f"get_pip_executable: pip.exe found at {pip_path}")
188
- pip_exe = str(pip_path)
189
- if " " in pip_exe and not pip_exe.startswith('"'):
190
- pip_exe = f'"{pip_exe}"'
191
- return pip_exe
142
+ # sys.executable should be python.exe or pythonservice.exe in the env root/Scripts
143
+ env_dir = os.path.dirname(sys.executable)
144
+ # If sys.executable is in Scripts, go up one level
145
+ if os.path.basename(env_dir.lower()) == 'scripts':
146
+ env_dir = os.path.dirname(env_dir)
147
+
148
+ scripts_dir = os.path.join(env_dir, 'Scripts')
149
+ target_exe_path = os.path.join(scripts_dir, TARGET_EXECUTABLE_NAME)
150
+
151
+ self.log_info(f"_find_target_executable: Checking for executable at: {target_exe_path}")
152
+
153
+ if os.path.exists(target_exe_path):
154
+ self.log_info(f"_find_target_executable: Found executable: {target_exe_path}")
155
+ # Quote if necessary for command line usage
156
+ if " " in target_exe_path and not target_exe_path.startswith('"'):
157
+ return f'"{target_exe_path}"'
158
+ return target_exe_path
192
159
  else:
193
- self.log_error(f"get_pip_executable: pip.exe NOT found at {pip_path}. Falling back to '{base_python} -m pip'.")
194
- pass
195
- except Exception as e:
196
- self.log_error(f"get_pip_executable: Error determining pip path: {e}", exc_info=True)
197
- self.log_error(f"get_pip_executable: Falling back to 'python -m pip' due to error.")
198
-
199
- # Fallback uses the potentially corrected python path
200
- return f"{self.get_base_python_executable()} -m pip"
201
-
202
- # --- PowerShell Methods (Moved from module level) ---
203
- def run_powershell_command(self, command, log_output=True):
204
- """Executes a PowerShell command and handles output/errors. Returns True on success."""
205
- self.log_info(f"Executing PowerShell: {command}")
206
- try:
207
- result = subprocess.run(
208
- ["powershell.exe", "-NoProfile", "-NonInteractive", "-Command", command],
209
- capture_output=True, text=True, check=True, encoding='utf-8', errors='ignore'
210
- )
211
- if log_output and result.stdout:
212
- self.log_info(f"PowerShell STDOUT:\n{result.stdout.strip()}")
213
- if log_output and result.stderr:
214
- self.log_info(f"PowerShell STDERR:\n{result.stderr.strip()}")
215
- return True
216
- except FileNotFoundError:
217
- self.log_error("'powershell.exe' not found. Cannot manage scheduled tasks.")
218
- return False
219
- except subprocess.CalledProcessError as e:
220
- self.log_error(f"PowerShell command failed (Exit Code {e.returncode}):")
221
- self.log_error(f" Command: {e.cmd}")
222
- if e.stdout: self.log_error(f" STDOUT: {e.stdout.strip()}")
223
- if e.stderr: self.log_error(f" STDERR: {e.stderr.strip()}")
224
- return False
225
- except Exception as e:
226
- self.log_error(f"Unexpected error running PowerShell: {e}", exc_info=True)
227
- return False
228
-
229
- def create_or_update_logon_task(self, username, task_command, python_executable):
230
- """Creates or updates a scheduled task to run a command at user logon."""
231
- task_name = f"{self._task_name_prefix}{username}"
232
- safe_python_exe = python_executable.replace("'", "''")
233
- command_parts = task_command.split(' ', 1)
234
- if len(command_parts) > 1 and command_parts[0] == python_executable:
235
- safe_task_command_args = command_parts[1].replace("'", "''")
236
- else:
237
- safe_task_command_args = task_command.replace(python_executable, "").strip().replace("'", "''")
238
-
239
- safe_task_name = task_name.replace("'", "''")
240
- safe_username = username.replace("'", "''")
241
-
242
- action = f"$Action = New-ScheduledTaskAction -Execute '{safe_python_exe}' -Argument '{safe_task_command_args}'"
243
- trigger = f"$Trigger = New-ScheduledTaskTrigger -AtLogOn -User '{safe_username}'"
244
- principal = f"$Principal = New-ScheduledTaskPrincipal -UserId '{safe_username}' -LogonType Interactive"
245
- settings = "$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -DontStopOnIdleEnd -ExecutionTimeLimit ([System.TimeSpan]::Zero) -RunOnlyIfNetworkAvailable:$false"
246
-
247
- command = f"""
248
- try {{
249
- {action}
250
- {trigger}
251
- {principal}
252
- {settings}
253
- Register-ScheduledTask -TaskName '{safe_task_name}' -Action $Action -Trigger $Trigger -Principal $Principal -Settings $Settings -Force -ErrorAction Stop
254
- Write-Host "Scheduled task '{safe_task_name}' registered/updated successfully."
255
- }} catch {{
256
- Write-Error "Failed to register/update scheduled task '{safe_task_name}': $_"
257
- exit 1
258
- }}
259
- """
260
- success = self.run_powershell_command(command)
261
- if success:
262
- self.log_info(f"Successfully created/updated scheduled task '{task_name}' for user '{username}'.")
263
- else:
264
- self.log_error(f"Failed to create/update scheduled task '{task_name}' for user '{username}'.")
265
- return success
160
+ self.log_error(f"_find_target_executable: Target executable not found at {target_exe_path}")
161
+ # Fallback: Check env root directly (less common for scripts)
162
+ target_exe_path_root = os.path.join(env_dir, TARGET_EXECUTABLE_NAME)
163
+ self.log_info(f"_find_target_executable: Checking fallback location: {target_exe_path_root}")
164
+ if os.path.exists(target_exe_path_root):
165
+ self.log_info(f"_find_target_executable: Found executable at fallback location: {target_exe_path_root}")
166
+ if " " in target_exe_path_root and not target_exe_path_root.startswith('"'):
167
+ return f'"{target_exe_path_root}"'
168
+ return target_exe_path_root
169
+ else:
170
+ self.log_error(f"_find_target_executable: Target executable also not found at {target_exe_path_root}")
171
+ return None
266
172
 
267
- def remove_logon_task(self, username):
268
- """Removes the logon scheduled task for a user."""
269
- task_name = f"{self._task_name_prefix}{username}"
270
- safe_task_name = task_name.replace("'", "''")
271
- command = f"Unregister-ScheduledTask -TaskName '{safe_task_name}' -Confirm:$false -ErrorAction SilentlyContinue"
272
- self.run_powershell_command(command, log_output=False)
273
- self.log_info(f"Attempted removal of scheduled task '{task_name}' for user '{username}'.")
274
- return True
275
- # --- End Instance Helper Methods ---
173
+ except Exception as e:
174
+ self.log_error(f"Error finding target executable: {e}")
175
+ return None
276
176
 
277
177
  def __init__(self, args):
278
178
  global _service_instance
@@ -284,13 +184,16 @@ class GuardService(win32serviceutil.ServiceFramework):
284
184
  self.command_processor_thread = None
285
185
  self.session = requests.Session()
286
186
 
287
- # Initialize paths using instance methods that prefer python.exe
288
- self.python_exe = self.get_base_python_executable()
289
- self.pip_command_base = self.get_pip_executable()
290
- # Construct command using the potentially corrected python.exe path
291
- self.ootb_command = f"{self.python_exe} -m {_OOTB_MODULE}"
187
+ self.target_executable_path = self._find_target_executable()
188
+ if not self.target_executable_path:
189
+ # Log error and potentially stop service if critical executable is missing
190
+ self.log_error(f"CRITICAL: Could not find {TARGET_EXECUTABLE_NAME}. Service cannot function.")
191
+ # Consider stopping the service here if needed, or handle appropriately
192
+ else:
193
+ self.log_info(f"Using target executable: {self.target_executable_path}")
194
+
292
195
  _service_instance = self
293
- self.log_info(f"Service initialized. OOTB command set to: {self.ootb_command}")
196
+ self.log_info(f"Service initialized. Target executable set to: {self.target_executable_path}")
294
197
 
295
198
  def SvcStop(self):
296
199
  self.log_info(f"Service stop requested.")
@@ -418,11 +321,11 @@ class GuardService(win32serviceutil.ServiceFramework):
418
321
 
419
322
  def handle_update(self):
420
323
  self.log_info("Executing OOTB update...")
421
- if not self.pip_command_base:
422
- self.log_error("Cannot update: pip command not found.")
423
- return "failed_pip_not_found"
324
+ if not self.target_executable_path:
325
+ self.log_error("Cannot update: Target executable not found.")
326
+ return "failed_executable_not_found"
424
327
 
425
- update_command = f"{self.pip_command_base} install --upgrade --no-cache-dir {_PACKAGE_NAME}"
328
+ update_command = f"{self.target_executable_path} update"
426
329
  self.log_info(f"Running update command: {update_command}")
427
330
  try:
428
331
  result = subprocess.run(update_command, shell=True, capture_output=True, text=True, check=True, timeout=300, encoding='utf-8')
@@ -452,7 +355,7 @@ class GuardService(win32serviceutil.ServiceFramework):
452
355
  self.log_info(f"Searching for OOTB processes for users: {target_users}")
453
356
 
454
357
  # Use the potentially corrected python.exe path for matching
455
- python_exe_path_for_check = self.python_exe.strip('"')
358
+ python_exe_path_for_check = self.target_executable_path.strip('"')
456
359
  self.log_info(f"_get_ootb_processes: Checking against python path: {python_exe_path_for_check}")
457
360
 
458
361
  for proc in psutil.process_iter(['pid', 'name', 'username', 'cmdline', 'exe']):
@@ -688,7 +591,7 @@ class GuardService(win32serviceutil.ServiceFramework):
688
591
 
689
592
  # 1. Always try to create/update the scheduled task
690
593
  try:
691
- task_created = self.create_or_update_logon_task(user, self.ootb_command, self.python_exe)
594
+ task_created = self.create_or_update_logon_task(user)
692
595
  task_created_status = "task_success" if task_created else "task_failed"
693
596
  except Exception as task_err:
694
597
  self.log_error(f"Exception creating/updating scheduled task for {user}: {task_err}", exc_info=True)
@@ -719,7 +622,7 @@ class GuardService(win32serviceutil.ServiceFramework):
719
622
  user_profile_dir = win32profile.GetUserProfileDirectory(token)
720
623
 
721
624
  hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
722
- token, self.python_exe, self.ootb_command,
625
+ token, self.target_executable_path,
723
626
  None, None, False, creation_flags, env, user_profile_dir, startup
724
627
  )
725
628
  self.log_info(f"CreateProcessAsUser call succeeded for user '{user}' (PID: {dwPid}). Checking existence...")
@@ -780,6 +683,57 @@ class GuardService(win32serviceutil.ServiceFramework):
780
683
  self.log_error(f"Error during combined start OOTB process: {e}", exc_info=True)
781
684
  return "failed_exception"
782
685
 
686
+ def create_or_update_logon_task(self, username):
687
+ """Creates or updates a scheduled task to run the OOTB app on user logon."""
688
+ if not self.target_executable_path:
689
+ self.log_error(f"Cannot create task for {username}: Target executable path is not set.")
690
+ return False
691
+
692
+ task_name = f"OOTB_UserLogon_{username}"
693
+ # Use the found target executable path directly
694
+ # No arguments needed if the executable handles everything
695
+ command_to_run = self.target_executable_path
696
+ # Arguments are now empty as the exe is called directly
697
+ arguments = ""
698
+
699
+ # Ensure command_to_run is properly quoted if it contains spaces
700
+ # The _find_target_executable should already handle quoting
701
+ # Example PowerShell command construction (adjust as needed)
702
+ ps_command = f"""
703
+ $taskName = "{task_name}"
704
+ $principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive
705
+ # Action: Run the target executable directly
706
+ $action = New-ScheduledTaskAction -Execute '{command_to_run}'
707
+ # Optional: Set working directory if needed, otherwise it might default to System32 or user profile
708
+ # $action.WorkingDirectory = "C:\path\to\working\dir"
709
+ $trigger = New-ScheduledTaskTrigger -AtLogOn -User "{username}"
710
+ $settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -ExecutionTimeLimit (New-TimeSpan -Days 9999) -RestartCount 3 -RestartInterval (New-TimeSpan -Minutes 1)
711
+ $description = "Runs OOTB Application for user {username} upon logon."
712
+
713
+ # Unregister existing task first (force)
714
+ Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue
715
+
716
+ # Register the new task
717
+ Register-ScheduledTask -TaskName $taskName -Principal $principal -Action $action -Trigger $trigger -Settings $settings -Description $description -Force
718
+ """
719
+ self.log_info(f"Attempting to create/update task '{task_name}' for user '{username}' to run '{command_to_run}'")
720
+ try:
721
+ # ... (run PowerShell command) ...
722
+ self.log_info(f"Successfully ran PowerShell command to create/update task '{task_name}'.")
723
+ return True
724
+ except Exception as e:
725
+ self.log_error(f"Failed to create/update scheduled task '{task_name}' for user '{username}': {e}")
726
+ return False
727
+
728
+ def remove_logon_task(self, username):
729
+ """Removes the logon scheduled task for a user."""
730
+ task_name = f"{self._task_name_prefix}{username}"
731
+ safe_task_name = task_name.replace("'", "''")
732
+ command = f"Unregister-ScheduledTask -TaskName '{safe_task_name}' -Confirm:$false -ErrorAction SilentlyContinue"
733
+ self.run_powershell_command(command, log_output=False)
734
+ self.log_info(f"Attempted removal of scheduled task '{task_name}' for user '{username}'.")
735
+ return True
736
+
783
737
  # --- Main Execution Block ---
784
738
  if __name__ == '__main__':
785
739
  if len(sys.argv) > 1 and sys.argv[1] == 'debug':
@@ -0,0 +1,65 @@
1
+ # src/computer_use_ootb_internal/preparation/star_rail_prepare.py
2
+ import time
3
+ import platform
4
+ import pyautogui
5
+ import webbrowser
6
+ import logging # Use logging instead of print for better practice
7
+
8
+ # Set up logging for this module if needed, or rely on root logger
9
+ log = logging.getLogger(__name__)
10
+
11
+ def run_preparation(state):
12
+ """
13
+ Performs environment preparation specific to Star Rail on Windows.
14
+ Opens the specified URL in Edge and performs initial clicks.
15
+ """
16
+ if platform.system() != "Windows":
17
+ log.info("Star Rail preparation skipped: Not running on Windows.")
18
+ return
19
+
20
+ log.info("Star Rail preparation: Starting environment setup on Windows...")
21
+ url = "https://sr.mihoyo.com/cloud/#/" # Consider making this configurable later
22
+ browser_opened = False
23
+ try:
24
+ # Use only webbrowser.open
25
+ log.info(f"Attempting to open {url} using webbrowser.open()...")
26
+ if webbrowser.open(url):
27
+ log.info(f"Successfully requested browser to open {url} via webbrowser.open().")
28
+ browser_opened = True
29
+ else:
30
+ log.warning("webbrowser.open() returned False, indicating potential failure.")
31
+
32
+ if not browser_opened:
33
+ log.error("Failed to confirm browser opening via webbrowser.open(). Will still attempt clicks.")
34
+
35
+ # Add pyautogui click after attempting to open the browser
36
+ log.info("Proceeding with pyautogui actions...")
37
+ time.sleep(5) # Wait time for the browser to load
38
+
39
+ # Get screen size
40
+ screen_width, screen_height = pyautogui.size()
41
+ log.info(f"Detected screen size: {screen_width}x{screen_height}")
42
+
43
+ # Calculate click coordinates based on a reference resolution (e.g., 1280x720)
44
+ # TODO: Make these coordinates more robust or configurable
45
+ click_x = int(screen_width * (1036 / 1280))
46
+ click_y = int(screen_height * (500 / 720))
47
+ log.info(f"Calculated click coordinates: ({click_x}, {click_y})")
48
+
49
+ # Disable failsafe before clicking
50
+ pyautogui.FAILSAFE = False
51
+ log.info("PyAutoGUI failsafe temporarily disabled.")
52
+
53
+ log.info(f"Clicking at coordinates: ({click_x}, {click_y})")
54
+ pyautogui.click(click_x, click_y)
55
+ time.sleep(2)
56
+ pyautogui.click(click_x, click_y) # Double click?
57
+
58
+ log.info("Star Rail preparation clicks completed.")
59
+
60
+ except Exception as e:
61
+ log.error(f"Error during Star Rail preparation (browser/click): {e}", exc_info=True)
62
+ finally:
63
+ # Ensure failsafe is re-enabled
64
+ pyautogui.FAILSAFE = True
65
+ log.info("PyAutoGUI failsafe re-enabled.")
@@ -1,10 +0,0 @@
1
- #!/bin/bash
2
-
3
- # Clean previous builds
4
- rm -rf dist
5
-
6
- # Build the package
7
- python -m build
8
-
9
- # Upload to PyPI using API key
10
- python -m twine upload dist/* -u __token__ -p pypi-AgEIcHlwaS5vcmcCJDkwMTlkNmE2LWFkZmYtNGU2ZC1hYzUwLWFiYmRjYTg4YTNkYgACIlsxLFsiY29tcHV0ZXItdXNlLW9vdGItaW50ZXJuYWwiXV0AAixbMixbIjllNmQ5NTRjLTgxZGEtNGRkNy05Yjk5LWVjYzMzOGUwN2NlZSJdXQAABiBFIKbytGELyFb1-i20Cu4tSo8cAUlX1DCLmUALq0mcPA
@@ -1,63 +0,0 @@
1
- # src/computer_use_ootb_internal/preparation/star_rail_prepare.py
2
- import time
3
- import platform
4
- import subprocess # Added for taskkill
5
- import webbrowser
6
- import logging # Use logging instead of print for better practice
7
-
8
- # Set up logging for this module if needed, or rely on root logger
9
- log = logging.getLogger(__name__)
10
-
11
- def run_preparation(state):
12
- """
13
- Performs environment preparation specific to Star Rail on Windows.
14
- Closes existing Edge browsers and opens the specified URL in a new Edge instance.
15
- """
16
- if platform.system() != "Windows":
17
- log.info("Star Rail preparation skipped: Not running on Windows.")
18
- return
19
-
20
- log.info("Star Rail preparation: Starting environment setup on Windows...")
21
- url = "https://sr.mihoyo.com/cloud/#/" # Consider making this configurable later
22
- browser_opened = False
23
- try:
24
- # Attempt to close existing Microsoft Edge processes
25
- log.info("Attempting to close existing Microsoft Edge processes...")
26
- try:
27
- # /F forces termination, /IM specifies image name
28
- result = subprocess.run(['taskkill', '/F', '/IM', 'msedge.exe'],
29
- capture_output=True, text=True, check=False)
30
- if result.returncode == 0:
31
- log.info("Successfully sent termination signal to msedge.exe processes.")
32
- elif "not found" in result.stderr.lower() or "not found" in result.stdout.lower():
33
- log.info("No running msedge.exe processes found to close.")
34
- else:
35
- log.warning(f"taskkill command finished with return code {result.returncode}. Output: {result.stdout} Stderr: {result.stderr}")
36
- time.sleep(2) # Give processes time to close
37
- except FileNotFoundError:
38
- log.error("Error: 'taskkill' command not found. Make sure it's in the system PATH.")
39
- except Exception as e:
40
- log.error(f"Error occurred while trying to close Edge: {e}", exc_info=True)
41
-
42
-
43
- # Use only webbrowser.open
44
- log.info(f"Attempting to open {url} using webbrowser.open()...")
45
- if webbrowser.open(url):
46
- log.info(f"Successfully requested browser to open {url} via webbrowser.open().")
47
- browser_opened = True
48
- time.sleep(5) # Wait time for the browser to potentially load the page
49
- else:
50
- log.warning("webbrowser.open() returned False, indicating potential failure.")
51
- # No need to error out completely if browser *request* failed,
52
- # but it's unlikely the rest of the process would work.
53
-
54
- if not browser_opened:
55
- log.error("Failed to confirm browser opening via webbrowser.open().")
56
-
57
- # Removed pyautogui click logic
58
-
59
- log.info("Star Rail preparation completed (browser opened).")
60
-
61
- except Exception as e:
62
- log.error(f"Error during Star Rail preparation: {e}", exc_info=True)
63
- # No finally block needed anymore as pyautogui failsafe is removed