computer-use-ootb-internal 0.0.161__py3-none-any.whl → 0.0.163__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 +113 -69
- computer_use_ootb_internal/launch_ootb_elevated.ps1 +69 -0
- {computer_use_ootb_internal-0.0.161.dist-info → computer_use_ootb_internal-0.0.163.dist-info}/METADATA +1 -1
- {computer_use_ootb_internal-0.0.161.dist-info → computer_use_ootb_internal-0.0.163.dist-info}/RECORD +6 -5
- {computer_use_ootb_internal-0.0.161.dist-info → computer_use_ootb_internal-0.0.163.dist-info}/WHEEL +0 -0
- {computer_use_ootb_internal-0.0.161.dist-info → computer_use_ootb_internal-0.0.163.dist-info}/entry_points.txt +0 -0
@@ -23,6 +23,7 @@ import psutil # For process/user info
|
|
23
23
|
from flask import Flask, request, jsonify # For embedded server
|
24
24
|
from waitress import serve # For serving Flask app
|
25
25
|
import json # Needed for status reporting
|
26
|
+
import shutil # Added for shutil.which
|
26
27
|
|
27
28
|
# --- Configuration ---
|
28
29
|
_SERVICE_NAME = "OOTBGuardService"
|
@@ -758,10 +759,9 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
758
759
|
self.log_error(f"Internal trigger: Error checking existing processes for {user}: {e}")
|
759
760
|
# Continue and attempt start despite error?
|
760
761
|
|
761
|
-
#
|
762
|
-
|
763
|
-
|
764
|
-
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting immediate start via direct PowerShell subprocess...")
|
762
|
+
# 4. Attempt immediate start using CreateProcessAsUser to run helper script
|
763
|
+
immediate_start_status = "start_attempted_helper_script"
|
764
|
+
self.log_info(f"Internal trigger: User '{user}' is active and not running. Attempting start via helper script...")
|
765
765
|
|
766
766
|
if not self.target_executable_path:
|
767
767
|
self.log_error("Internal trigger: Cannot start process - target executable path not found.")
|
@@ -769,67 +769,86 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
769
769
|
return final_status
|
770
770
|
|
771
771
|
try:
|
772
|
-
#
|
772
|
+
# Find helper script path
|
773
|
+
helper_script_path = self._find_helper_script("launch_ootb_elevated.ps1")
|
774
|
+
if not helper_script_path:
|
775
|
+
self.log_error("Internal trigger: Cannot start process - helper script not found.")
|
776
|
+
final_status = "failed_helper_script_not_found"
|
777
|
+
return final_status
|
778
|
+
|
779
|
+
# Get PowerShell executable path
|
780
|
+
powershell_executable = self._find_powershell_executable()
|
781
|
+
if not powershell_executable:
|
782
|
+
self.log_error("Internal trigger: Cannot start process - powershell.exe not found.")
|
783
|
+
final_status = "failed_powershell_not_found"
|
784
|
+
return final_status
|
785
|
+
|
786
|
+
# Prepare arguments for the helper script (paths need quoting if they contain spaces)
|
773
787
|
target_exe_unquoted = self.target_executable_path.strip('"')
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
#
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
powershell_executable,
|
792
|
-
"-NoProfile",
|
793
|
-
"-ExecutionPolicy", "Bypass",
|
794
|
-
"-Command",
|
795
|
-
f"{{ {ps_script_block_content_escaped} }}" # Use script block {}
|
796
|
-
]
|
797
|
-
|
798
|
-
self.log_info(f"Internal trigger: Executing subprocess: {command_list}")
|
799
|
-
|
800
|
-
# Execute the command directly from the service context
|
801
|
-
result = subprocess.run(
|
802
|
-
command_list,
|
803
|
-
capture_output=True,
|
804
|
-
text=True,
|
805
|
-
check=False, # Don't raise exception on non-zero exit
|
806
|
-
encoding='utf-8',
|
807
|
-
errors='ignore'
|
788
|
+
target_exe_dir = os.path.dirname(target_exe_unquoted) # Use directory of unquoted path
|
789
|
+
|
790
|
+
# Quote paths/args for command line - IMPORTANT: Use double quotes for PowerShell args
|
791
|
+
helper_script_arg = f'"{helper_script_path}"' if " " in helper_script_path else helper_script_path
|
792
|
+
target_exe_arg = f'"{target_exe_unquoted}"' if " " in target_exe_unquoted else target_exe_unquoted
|
793
|
+
working_dir_arg = f'"{target_exe_dir}"' if " " in target_exe_dir else target_exe_dir
|
794
|
+
# Username might need quoting if it contains special characters, double quote should be safe
|
795
|
+
target_user_arg = f'"{user}"'
|
796
|
+
|
797
|
+
# Construct the command line to execute powershell with the helper script and args
|
798
|
+
lpCommandLine = (
|
799
|
+
f'"{powershell_executable}" -NoProfile -ExecutionPolicy Bypass -NoExit '
|
800
|
+
f'-File {helper_script_arg} '
|
801
|
+
f'-TargetExePath {target_exe_arg} '
|
802
|
+
f'-Port {calculated_port} '
|
803
|
+
f'-TargetUser {target_user_arg} '
|
804
|
+
f'-WorkingDirectory {working_dir_arg}'
|
808
805
|
)
|
809
806
|
|
810
|
-
#
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
807
|
+
# Use CreateProcessAsUser to launch this command in the user's session
|
808
|
+
token = win32ts.WTSQueryUserToken(session_id)
|
809
|
+
env = win32profile.CreateEnvironmentBlock(token, False)
|
810
|
+
startup = win32process.STARTUPINFO()
|
811
|
+
# Ensure the window is visible on the user's desktop
|
812
|
+
startup.lpDesktop = "winsta0\\default"
|
813
|
+
creation_flags = win32con.CREATE_NEW_CONSOLE | win32con.NORMAL_PRIORITY_CLASS
|
814
|
+
lpApplicationName = None # Must be None when using lpCommandLine
|
815
|
+
# Working directory for powershell itself? Let it default or use script dir?
|
816
|
+
# Let's use the script's directory as CWD for powershell.exe
|
817
|
+
cwd = os.path.dirname(helper_script_path) # Use directory of unquoted path
|
818
|
+
|
819
|
+
self.log_info(f"Internal trigger: Launching helper script via CreateProcessAsUser:")
|
820
|
+
self.log_info(f" lpCommandLine: {lpCommandLine}")
|
821
|
+
self.log_info(f" lpCurrentDirectory: {cwd}")
|
822
|
+
|
823
|
+
# Execute the command in the user's session
|
824
|
+
hProcess, hThread, dwPid, dwTid = win32process.CreateProcessAsUser(
|
825
|
+
token, lpApplicationName, lpCommandLine, None, None, False,
|
826
|
+
creation_flags, env, cwd, startup
|
827
|
+
)
|
828
|
+
self.log_info(f"Internal trigger: CreateProcessAsUser call for helper script succeeded (Launcher PID: {dwPid}). Helper script should now run and trigger elevation.")
|
829
|
+
win32api.CloseHandle(hProcess)
|
830
|
+
win32api.CloseHandle(hThread)
|
831
|
+
|
832
|
+
# Assume success if CreateProcessAsUser succeeded.
|
833
|
+
# The actual success depends on the user interacting with UAC triggered by the helper.
|
834
|
+
immediate_start_status = "start_success_helper_launched"
|
835
|
+
final_status = "success_helper_launched"
|
836
|
+
|
837
|
+
except FileNotFoundError as fnf_err:
|
838
|
+
# This might now be powershell.exe OR the helper script
|
839
|
+
self.log_error(f"Internal trigger: File not found during helper script launch: {fnf_err}")
|
840
|
+
immediate_start_status = "start_failed_file_not_found"
|
841
|
+
final_status = "failed_file_not_found"
|
842
|
+
except Exception as launch_err:
|
843
|
+
self.log_error(f"Internal trigger: Exception during CreateProcessAsUser for helper script (user '{user}'): {launch_err}", exc_info=True)
|
844
|
+
immediate_start_status = "start_failed_launch_exception"
|
845
|
+
final_status = "failed_launch_exception"
|
846
|
+
finally:
|
847
|
+
if 'token' in locals() and token: # Ensure token is defined before trying to close
|
848
|
+
try:
|
849
|
+
win32api.CloseHandle(token)
|
850
|
+
except: # Ignore errors closing handle
|
851
|
+
pass
|
833
852
|
|
834
853
|
# Combine results (mostly determined by start attempt now)
|
835
854
|
# Example: final_status = f"{task_created_status}_{immediate_start_status}"
|
@@ -953,20 +972,45 @@ class GuardService(win32serviceutil.ServiceFramework):
|
|
953
972
|
|
954
973
|
def _find_signal_script(self):
|
955
974
|
"""Finds the signal_connection.py script relative to this service file."""
|
975
|
+
return self._find_helper_script("signal_connection.py") # Reuse helper finding logic
|
976
|
+
|
977
|
+
def _find_helper_script(self, script_name):
|
978
|
+
"""Finds a helper script relative to this service file."""
|
956
979
|
try:
|
980
|
+
# Use __file__ which should be reliable when run as a service via pythonservice.exe
|
957
981
|
base_dir = os.path.dirname(os.path.abspath(__file__))
|
958
|
-
script_path = os.path.join(base_dir,
|
982
|
+
script_path = os.path.join(base_dir, script_name)
|
959
983
|
if os.path.exists(script_path):
|
960
|
-
self.log_info(f"Found
|
961
|
-
#
|
962
|
-
if " " in script_path and not script_path.startswith('"'):
|
963
|
-
return f'"{script_path}"'
|
984
|
+
self.log_info(f"Found helper script '{script_name}' at: {script_path}")
|
985
|
+
# Return unquoted path for potential quoting later
|
964
986
|
return script_path
|
965
987
|
else:
|
966
|
-
self.log_error(f"
|
988
|
+
self.log_error(f"Helper script '{script_name}' not found near {base_dir}")
|
967
989
|
return None
|
968
990
|
except Exception as e:
|
969
|
-
self.log_error(f"Error finding
|
991
|
+
self.log_error(f"Error finding helper script '{script_name}': {e}")
|
992
|
+
return None
|
993
|
+
|
994
|
+
def _find_powershell_executable(self):
|
995
|
+
"""Finds powershell.exe, preferring the system path."""
|
996
|
+
try:
|
997
|
+
# Check System32 first
|
998
|
+
system32_path = os.path.join(os.environ.get('SystemRoot', 'C:\\Windows'), 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe')
|
999
|
+
if os.path.exists(system32_path):
|
1000
|
+
self.log_info(f"Found powershell.exe at: {system32_path}")
|
1001
|
+
return system32_path
|
1002
|
+
else:
|
1003
|
+
# Fallback to checking PATH using shutil.which (requires Python 3.3+)
|
1004
|
+
# Make sure to import shutil at the top of the file if not already present
|
1005
|
+
powershell_path = shutil.which("powershell.exe")
|
1006
|
+
if powershell_path:
|
1007
|
+
self.log_info(f"Found powershell.exe via PATH: {powershell_path}")
|
1008
|
+
return powershell_path
|
1009
|
+
else:
|
1010
|
+
self.log_error("powershell.exe not found in System32 or PATH.")
|
1011
|
+
return None
|
1012
|
+
except Exception as e:
|
1013
|
+
self.log_error(f"Error finding powershell.exe: {e}")
|
970
1014
|
return None
|
971
1015
|
|
972
1016
|
# --- Main Execution Block ---
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# launch_ootb_elevated.ps1
|
2
|
+
param(
|
3
|
+
[Parameter(Mandatory=$true)]
|
4
|
+
[string]$TargetExePath,
|
5
|
+
|
6
|
+
[Parameter(Mandatory=$true)]
|
7
|
+
[string]$Port,
|
8
|
+
|
9
|
+
[Parameter(Mandatory=$true)]
|
10
|
+
[string]$TargetUser,
|
11
|
+
|
12
|
+
[Parameter(Mandatory=$true)]
|
13
|
+
[string]$WorkingDirectory
|
14
|
+
)
|
15
|
+
|
16
|
+
try {
|
17
|
+
Write-Host "--- OOTB Elevation Helper ---"
|
18
|
+
Write-Host "Timestamp: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
|
19
|
+
Write-Host "Received parameters:"
|
20
|
+
Write-Host " Target Exe Path : $TargetExePath"
|
21
|
+
Write-Host " Port : $Port"
|
22
|
+
Write-Host " Target User : $TargetUser"
|
23
|
+
Write-Host " Working Dir : $WorkingDirectory"
|
24
|
+
Write-Host ""
|
25
|
+
|
26
|
+
# Validate paths
|
27
|
+
if (-not (Test-Path -Path $TargetExePath -PathType Leaf)) {
|
28
|
+
throw "Target executable not found at '$TargetExePath'"
|
29
|
+
}
|
30
|
+
if (-not (Test-Path -Path $WorkingDirectory -PathType Container)) {
|
31
|
+
throw "Working directory not found at '$WorkingDirectory'"
|
32
|
+
}
|
33
|
+
|
34
|
+
# Construct the second argument for cmd.exe /K, precisely matching the working command
|
35
|
+
# Format: "<quoted_exe_path>" --port <port> --target_user ''<username>''
|
36
|
+
# Note: PowerShell handles escaping within double quotes differently.
|
37
|
+
# Using backticks ` before inner quotes is safer here.
|
38
|
+
$cmdKSecondArg = "`"`"$TargetExePath`"`" --port $Port --target_user ''$TargetUser''"
|
39
|
+
|
40
|
+
# Construct the argument list array for Start-Process launching cmd.exe
|
41
|
+
$startProcessArgs = @('/K', $cmdKSecondArg)
|
42
|
+
|
43
|
+
Write-Host "Constructed cmd.exe /K arguments: $cmdKSecondArg"
|
44
|
+
Write-Host "Constructed Start-Process arguments array: $($startProcessArgs -join ' ')" # For logging
|
45
|
+
Write-Host "Executing elevated process..."
|
46
|
+
Write-Host "Command: Start-Process -FilePath cmd.exe -ArgumentList @('/K', '$cmdKSecondArg') -WorkingDirectory '$WorkingDirectory' -Verb RunAs"
|
47
|
+
Write-Host "--- Waiting for UAC prompt if necessary ---"
|
48
|
+
|
49
|
+
# Execute the command to launch cmd elevated, which runs the target app
|
50
|
+
Start-Process -FilePath cmd.exe -ArgumentList $startProcessArgs -WorkingDirectory $WorkingDirectory -Verb RunAs
|
51
|
+
|
52
|
+
Write-Host "--- OOTB Elevation Helper: Start-Process command executed. ---"
|
53
|
+
# The calling powershell window (started by CreateProcessAsUser with -NoExit) will remain open.
|
54
|
+
|
55
|
+
} catch {
|
56
|
+
Write-Error "--- OOTB Elevation Helper Error ---"
|
57
|
+
Write-Error "Error launching elevated process: $($_.Exception.Message)"
|
58
|
+
Write-Error "Script Parameters:"
|
59
|
+
Write-Error " Target Exe Path : $TargetExePath"
|
60
|
+
Write-Error " Port : $Port"
|
61
|
+
Write-Error " Target User : $TargetUser"
|
62
|
+
Write-Error " Working Dir : $WorkingDirectory"
|
63
|
+
Write-Host "Press Enter to exit..."
|
64
|
+
Read-Host # Keep window open on error
|
65
|
+
Exit 1
|
66
|
+
}
|
67
|
+
|
68
|
+
# Exit gracefully if successful
|
69
|
+
Exit 0
|
{computer_use_ootb_internal-0.0.161.dist-info → computer_use_ootb_internal-0.0.163.dist-info}/RECORD
RENAMED
@@ -2,7 +2,8 @@ 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=SV8vnxBUiu3Y7_RS4g7R3khzW7Ewh-5ooC7RO2DL4-c,55398
|
6
|
+
computer_use_ootb_internal/launch_ootb_elevated.ps1,sha256=h6CnpDd8pRwDqFu42E5GUuLdPrCHJWDuc_zOXaE9mtQ,2793
|
6
7
|
computer_use_ootb_internal/requirements-lite.txt,sha256=5DAHomz4A_P2BmTIXNkNqkHbnIF0AyZ4_1XAlb1LaYs,290
|
7
8
|
computer_use_ootb_internal/run_teachmode_ootb_args.py,sha256=eUPpfA7bB3bdBBiIBIxKJSS-Jpz2G6R46fpDO440Jyo,7687
|
8
9
|
computer_use_ootb_internal/service_manager.py,sha256=SD8jzfn0VVXBOr_nP6zmBWSC2TzrU_sp2e5JJkSlQFU,9734
|
@@ -34,7 +35,7 @@ computer_use_ootb_internal/computer_use_demo/tools/run.py,sha256=xhXdnBK1di9muaO
|
|
34
35
|
computer_use_ootb_internal/computer_use_demo/tools/screen_capture.py,sha256=L8qfvtUkPPQGt92N-2Zfw5ZTDBzLsDps39uMnX3_uSA,6857
|
35
36
|
computer_use_ootb_internal/preparation/__init__.py,sha256=AgtGHcBpiTkxJjF0xwcs3yyQ6SyUvhL3G0vD2XO-zJw,63
|
36
37
|
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.
|
38
|
+
computer_use_ootb_internal-0.0.163.dist-info/METADATA,sha256=sOJ6C_wWzwu6jp5zsWX9GseG1pabVxpIaEjkIRH-pRU,1048
|
39
|
+
computer_use_ootb_internal-0.0.163.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
40
|
+
computer_use_ootb_internal-0.0.163.dist-info/entry_points.txt,sha256=bXfyAU_qq-G1EiEgAQEioXvgEdRCFxaTooqdDD9Y4OA,258
|
41
|
+
computer_use_ootb_internal-0.0.163.dist-info/RECORD,,
|
{computer_use_ootb_internal-0.0.161.dist-info → computer_use_ootb_internal-0.0.163.dist-info}/WHEEL
RENAMED
File without changes
|
File without changes
|