computer-use-ootb-internal 0.0.160__py3-none-any.whl → 0.0.162__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/guard_service.py +66 -114
- {computer_use_ootb_internal-0.0.160.dist-info → computer_use_ootb_internal-0.0.162.dist-info}/METADATA +1 -1
- {computer_use_ootb_internal-0.0.160.dist-info → computer_use_ootb_internal-0.0.162.dist-info}/RECORD +5 -5
- {computer_use_ootb_internal-0.0.160.dist-info → computer_use_ootb_internal-0.0.162.dist-info}/WHEEL +0 -0
- {computer_use_ootb_internal-0.0.160.dist-info → computer_use_ootb_internal-0.0.162.dist-info}/entry_points.txt +0 -0
@@ -226,9 +226,7 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
226
226
|
self.log_info(f"Using target executable: {self.target_executable_path}")
|
227
227
|
|
228
228
|
_service_instance = self
|
229
|
-
|
230
|
-
self.signal_script_path = self._find_signal_script()
|
231
|
-
self.log_info(f"Service initialized. Target executable: {self.target_executable_path}. Signal script: {self.signal_script_path}")
|
229
|
+
self.log_info(f"Service initialized. Target executable: {self.target_executable_path}.")
|
232
230
|
|
233
231
|
def SvcStop(self):
|
234
232
|
self.log_info(f"Service stop requested.")
|
@@ -710,7 +708,7 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
710
708
|
try:
|
711
709
|
# 1. Ensure scheduled task exists (still useful fallback/persistence)
|
712
710
|
try:
|
713
|
-
task_created = self.create_or_update_logon_task(user)
|
711
|
+
task_created = self.create_or_update_logon_task(user, calculated_port)
|
714
712
|
task_created_status = "task_success" if task_created else "task_failed"
|
715
713
|
except Exception as task_err:
|
716
714
|
self.log_error(f"Internal trigger: Exception creating/updating task for {user}: {task_err}", exc_info=True)
|
@@ -758,74 +756,59 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
758
756
|
self.log_error(f"Internal trigger: Error checking existing processes for {user}: {e}")
|
759
757
|
# Continue and attempt start despite error?
|
760
758
|
|
761
|
-
# 4.
|
762
|
-
immediate_start_status = "
|
763
|
-
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting
|
764
|
-
|
765
|
-
if not self.target_executable_path:
|
766
|
-
self.log_error("Internal trigger: Cannot start process - target executable path not found.")
|
767
|
-
final_status = "failed_exe_not_found"
|
768
|
-
return final_status # Exit early if executable missing
|
759
|
+
# 4. Create/Update and Trigger Scheduled Task
|
760
|
+
immediate_start_status = "start_attempted_task_trigger"
|
761
|
+
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting start via Task Scheduler...")
|
769
762
|
|
763
|
+
# --- Start Task Scheduler logic ---
|
770
764
|
try:
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
target_exe_unquoted = self.target_executable_path.strip('"')
|
779
|
-
target_exe_for_ps = target_exe_unquoted.replace("'", "''") # Escape single quotes for PS strings
|
780
|
-
target_exe_dir_for_ps = os.path.dirname(target_exe_unquoted).replace("'", "''")
|
781
|
-
|
782
|
-
# 1. 准备 PowerShell 命令中需要的变量 (进行基本的 PowerShell 字符串转义)
|
783
|
-
ps_target_exe = target_exe_for_ps
|
784
|
-
ps_working_dir = target_exe_dir_for_ps
|
785
|
-
# 用户名 'altair' 在最终命令里需要 ''altair'' 格式
|
786
|
-
ps_user_arg_format = user.replace("'", "''") # 先转义用户名本身的单引号
|
787
|
-
|
788
|
-
# 2. 构建最终的、完整的 PowerShell 命令字符串,严格按照模板
|
789
|
-
# 模板: Start-Process -FilePath cmd.exe -ArgumentList @('/K', '"<exe_path>" --port <port> --target_user ''<username>''') -WorkingDirectory '<working_dir>' -Verb RunAs
|
790
|
-
ps_command_string = f"Start-Process -FilePath cmd.exe -ArgumentList @('/K', '"""{ps_target_exe}""" --port {calculated_port} --target_user ''''{ps_user_arg_format}''''') -WorkingDirectory '{ps_working_dir}' -Verb RunAs"
|
791
|
-
|
792
|
-
# 3. 为 powershell.exe -Command '...' 参数转义整个命令字符串中的单引号
|
793
|
-
ps_command_string_escaped = ps_command_string.replace("'", "''")
|
794
|
-
|
795
|
-
# 4. 生成最终传递给 CreateProcessAsUser 的命令行
|
796
|
-
# 依然使用 powershell.exe -NoExit -Command '{ ... }' 以便观察,虽然不一定有效
|
797
|
-
lpCommandLine = f"powershell.exe -NoProfile -ExecutionPolicy Bypass -NoExit -Command '{{ {ps_command_string_escaped} }}'"
|
765
|
+
# Step 4a: Ensure the task is created/updated correctly
|
766
|
+
# Pass calculated port to the task creation function
|
767
|
+
task_created = self.create_or_update_logon_task(user, calculated_port)
|
768
|
+
if not task_created:
|
769
|
+
self.log_error(f"Internal trigger: Failed to create/update scheduled task for user '{user}'. Cannot proceed with start.")
|
770
|
+
final_status = "failed_task_creation"
|
771
|
+
return final_status
|
798
772
|
|
799
|
-
|
800
|
-
|
773
|
+
# Step 4b: Trigger the task to run immediately
|
774
|
+
task_name = f"OOTB_UserConnect_{user}" # Must match the name used in create_or_update_logon_task
|
775
|
+
trigger_command = ["schtasks", "/Run", "/TN", task_name]
|
776
|
+
self.log_info(f"Internal trigger: Attempting to run task '{task_name}' immediately using: {trigger_command}")
|
777
|
+
|
778
|
+
result = subprocess.run(
|
779
|
+
trigger_command,
|
780
|
+
capture_output=True,
|
781
|
+
text=True,
|
782
|
+
check=False, # Check return code manually
|
783
|
+
encoding='utf-8',
|
784
|
+
errors='ignore'
|
785
|
+
)
|
801
786
|
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
787
|
+
if result.stdout:
|
788
|
+
self.log_info(f"Internal trigger: schtasks /Run STDOUT:\n{result.stdout.strip()}")
|
789
|
+
if result.stderr:
|
790
|
+
# schtasks often prints success message to stderr, log as info
|
791
|
+
self.log_info(f"Internal trigger: schtasks /Run STDERR:\n{result.stderr.strip()}")
|
806
792
|
|
807
|
-
|
808
|
-
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
finally:
|
827
|
-
if token: win32api.CloseHandle(token)
|
828
|
-
|
793
|
+
if result.returncode == 0 or "SUCCESS: Attempted to run the scheduled task" in result.stdout or "SUCCESS: Attempted to run the scheduled task" in result.stderr:
|
794
|
+
self.log_info(f"Internal trigger: Successfully triggered task '{task_name}' for user '{user}'.")
|
795
|
+
immediate_start_status = "start_success_task_triggered"
|
796
|
+
final_status = "success_task_triggered"
|
797
|
+
else:
|
798
|
+
self.log_error(f"Internal trigger: Failed to trigger task '{task_name}' (Exit Code: {result.returncode}).")
|
799
|
+
immediate_start_status = f"start_failed_task_trigger_code_{result.returncode}"
|
800
|
+
final_status = f"failed_task_trigger_code_{result.returncode}"
|
801
|
+
|
802
|
+
except FileNotFoundError:
|
803
|
+
self.log_error("Internal trigger: 'schtasks.exe' not found.")
|
804
|
+
immediate_start_status = "start_failed_schtasks_not_found"
|
805
|
+
final_status = "failed_schtasks_not_found"
|
806
|
+
except Exception as task_trigger_err:
|
807
|
+
self.log_error(f"Internal trigger: Exception during task trigger for user '{user}': {task_trigger_err}", exc_info=True)
|
808
|
+
immediate_start_status = "start_failed_task_trigger_exception"
|
809
|
+
final_status = "failed_task_trigger_exception"
|
810
|
+
# --- End Task Scheduler logic ---
|
811
|
+
|
829
812
|
# Combine results (mostly determined by start attempt now)
|
830
813
|
# Example: final_status = f"{task_created_status}_{immediate_start_status}"
|
831
814
|
return final_status
|
@@ -835,48 +818,35 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
835
818
|
return "failed_trigger_exception"
|
836
819
|
|
837
820
|
|
838
|
-
def create_or_update_logon_task(self, username):
|
821
|
+
def create_or_update_logon_task(self, username, port):
|
839
822
|
"""Creates/updates task to trigger the internal signal script on session connect."""
|
840
|
-
if not self.
|
841
|
-
self.log_error(f"Cannot create task for {username}:
|
823
|
+
if not self.target_executable_path:
|
824
|
+
self.log_error(f"Cannot create task for {username}: Target executable path not found.")
|
842
825
|
return False
|
843
|
-
if not sys.executable:
|
844
|
-
self.log_error(f"Cannot create task for {username}: sys.executable is not found.")
|
845
|
-
return False
|
846
|
-
|
847
|
-
# Use the python executable that the service itself is running under
|
848
|
-
python_exe = sys.executable
|
849
|
-
if ' ' in python_exe and not python_exe.startswith('"'):
|
850
|
-
python_exe = f'"{python_exe}"'
|
851
826
|
|
852
827
|
task_name = f"OOTB_UserConnect_{username}"
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
#
|
858
|
-
user_arg = username # Keep simple for now
|
859
|
-
action_arguments = f'{script_arg} "{user_arg}"' # Pass username as quoted arg
|
860
|
-
safe_action_executable = action_executable.replace("'", "''") # Escape for PS
|
861
|
-
safe_action_arguments = action_arguments.replace("'", "''") # Escape for PS
|
862
|
-
|
863
|
-
# Working directory for the script (likely its own directory)
|
828
|
+
target_exe_unquoted = self.target_executable_path.strip('"')
|
829
|
+
target_exe_for_ps = target_exe_unquoted.replace("'", "''")
|
830
|
+
action_arguments = f"--port {port} --target_user '{username}'".replace("'", "''") # Arguments for the target exe
|
831
|
+
|
832
|
+
# Working directory for the executable
|
864
833
|
try:
|
865
|
-
|
866
|
-
if not
|
867
|
-
safe_working_directory =
|
834
|
+
target_dir = os.path.dirname(target_exe_unquoted)
|
835
|
+
if not target_dir: target_dir = "."
|
836
|
+
safe_working_directory = target_dir.replace("'", "''")
|
868
837
|
working_directory_setting = f"$action.WorkingDirectory = '{safe_working_directory}'"
|
869
838
|
except Exception as e:
|
870
|
-
self.log_error(f"Error determining working directory for
|
839
|
+
self.log_error(f"Error determining working directory for target exe task: {e}. WD will not be set.")
|
871
840
|
working_directory_setting = "# Could not set WorkingDirectory"
|
872
841
|
|
873
842
|
# PowerShell command construction
|
874
843
|
ps_command = f"""
|
875
844
|
$taskName = "{task_name}"
|
876
|
-
|
845
|
+
# Principal runs as the user, but with highest privileges
|
846
|
+
$principal = New-ScheduledTaskPrincipal -UserId "{username}" -LogonType Interactive -RunLevel Highest
|
877
847
|
|
878
|
-
# Action: Run
|
879
|
-
$action = New-ScheduledTaskAction -Execute '{
|
848
|
+
# Action: Run the target executable directly with arguments
|
849
|
+
$action = New-ScheduledTaskAction -Execute '{target_exe_for_ps}' -Argument '{action_arguments}'
|
880
850
|
{working_directory_setting}
|
881
851
|
|
882
852
|
# Trigger: On session connect (Event ID 21)
|
@@ -946,24 +916,6 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
946
916
|
self.log_info(f"Attempted removal of scheduled task '{task_name}' for user '{username}'.")
|
947
917
|
return True
|
948
918
|
|
949
|
-
def _find_signal_script(self):
|
950
|
-
"""Finds the signal_connection.py script relative to this service file."""
|
951
|
-
try:
|
952
|
-
base_dir = os.path.dirname(os.path.abspath(__file__))
|
953
|
-
script_path = os.path.join(base_dir, "signal_connection.py")
|
954
|
-
if os.path.exists(script_path):
|
955
|
-
self.log_info(f"Found signal script at: {script_path}")
|
956
|
-
# Quote if needed?
|
957
|
-
if " " in script_path and not script_path.startswith('"'):
|
958
|
-
return f'"{script_path}"'
|
959
|
-
return script_path
|
960
|
-
else:
|
961
|
-
self.log_error(f"Signal script signal_connection.py not found near {base_dir}")
|
962
|
-
return None
|
963
|
-
except Exception as e:
|
964
|
-
self.log_error(f"Error finding signal script: {e}")
|
965
|
-
return None
|
966
|
-
|
967
919
|
# --- Main Execution Block ---
|
968
920
|
if __name__ == '__main__':
|
969
921
|
if len(sys.argv) > 1 and sys.argv[1] == 'debug':
|
{computer_use_ootb_internal-0.0.160.dist-info → computer_use_ootb_internal-0.0.162.dist-info}/RECORD
RENAMED
@@ -2,7 +2,7 @@ computer_use_ootb_internal/README.md,sha256=FxpW95lyub2iX73ZDfK6ML7SdEKg060H5I6G
|
|
2
2
|
computer_use_ootb_internal/__init__.py,sha256=Nqnn8clbgv-5l0PgxcTOldg8mkMKrFn4TvPL-rYUUGg,1
|
3
3
|
computer_use_ootb_internal/app_teachmode.py,sha256=hiUTiX4jl1-5yqs3AwrOjNmToL5LbUb42o5XS4fiKAA,23805
|
4
4
|
computer_use_ootb_internal/dependency_check.py,sha256=y8RMEP6RXQzTgU1MS_1piBLtz4J-Hfn9RjUZg59dyvo,1333
|
5
|
-
computer_use_ootb_internal/guard_service.py,sha256=
|
5
|
+
computer_use_ootb_internal/guard_service.py,sha256=3gYAhyzx561fn9Jzj9wHWAfFZeu28KGUTmVEUO_49LY,49981
|
6
6
|
computer_use_ootb_internal/requirements-lite.txt,sha256=5DAHomz4A_P2BmTIXNkNqkHbnIF0AyZ4_1XAlb1LaYs,290
|
7
7
|
computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=eUPpfA7bB3bdBBiIBIxKJSS-Jpz2G6R46fpDO440Jyo,7687
|
8
8
|
computer_use_ootb_internal/service_manager.py,sha256=SD8jzfn0VVXBOr_nP6zmBWSC2TzrU_sp2e5JJkSlQFU,9734
|
@@ -34,7 +34,7 @@ computer_use_ootb_internal/computer_use_demo/tools/run.py,sha256=xhXdnBK1di9muaO
|
|
34
34
|
computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py,sha256=L8qfvtUkPPQGt92N-2Zfw5ZTDBzLsDps39uMnX3_uSA,6857
|
35
35
|
computer_use_ootb_internal/preparation/__init__.py,sha256=AgtGHcBpiTkxJjF0xwcs3yyQ6SyUvhL3G0vD2XO-zJw,63
|
36
36
|
computer_use_ootb_internal/preparation/star_rail_prepare.py,sha256=r0b19M_c1sXkN3_MRFjql8w_ThC9nZUe8zbSLYUvKS8,4635
|
37
|
-
computer_use_ootb_internal-0.0.
|
38
|
-
computer_use_ootb_internal-0.0.
|
39
|
-
computer_use_ootb_internal-0.0.
|
40
|
-
computer_use_ootb_internal-0.0.
|
37
|
+
computer_use_ootb_internal-0.0.162.dist-info/METADATA,sha256=95vezOZ2LEudzalKLavbO7dRZEqbv9WqYPUHWneHAzc,1048
|
38
|
+
computer_use_ootb_internal-0.0.162.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
39
|
+
computer_use_ootb_internal-0.0.162.dist-info/entry_points.txt,sha256=bXfyAU_qq-G1EiEgAQEioXvgEdRCFxaTooqdDD9Y4OA,258
|
40
|
+
computer_use_ootb_internal-0.0.162.dist-info/RECORD,,
|
{computer_use_ootb_internal-0.0.160.dist-info → computer_use_ootb_internal-0.0.162.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|