mirror of
https://git-qiuchenly.yltfspace.com/QiuChenly/corepatch
synced 2025-11-26 06:36:14 +08:00
Stash
This commit is contained in:
@@ -885,7 +885,8 @@
|
||||
"injectFile": "SenPlayer",
|
||||
"dylibSelect": "CoreInject.dylib",
|
||||
"supportVersion": [
|
||||
"5.2.2"
|
||||
"5.2.2",
|
||||
"5.5.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -14,39 +14,39 @@ from src.utils.color import Color
|
||||
# 获取工具真实路径的辅助函数
|
||||
def get_tool_path(tool_name):
|
||||
"""获取工具的真实路径
|
||||
|
||||
|
||||
Args:
|
||||
tool_name: 工具名称
|
||||
|
||||
|
||||
Returns:
|
||||
str: 工具的绝对路径
|
||||
"""
|
||||
# 获取项目根目录
|
||||
root_dir = Path(__file__).resolve().parent.parent.parent
|
||||
tool_path = os.path.join(root_dir, "tool", tool_name)
|
||||
|
||||
|
||||
# 检查工具是否存在
|
||||
if not os.path.exists(tool_path):
|
||||
print(Color.red(f"[错误] 工具 {tool_name} 不存在于路径: {tool_path}"))
|
||||
|
||||
|
||||
return tool_path
|
||||
|
||||
|
||||
# 执行命令并检查结果的辅助函数
|
||||
def run_command(command, shell=True, check_error=True):
|
||||
"""运行命令并检查结果,如果出错则显示红色警告
|
||||
|
||||
|
||||
Args:
|
||||
command: 要执行的命令
|
||||
shell: 是否使用shell执行
|
||||
check_error: 是否检查错误
|
||||
|
||||
|
||||
Returns:
|
||||
bool: 命令执行成功返回True,否则返回False
|
||||
"""
|
||||
try:
|
||||
result = subprocess.run(command, shell=shell, capture_output=True, text=True)
|
||||
|
||||
|
||||
# 检查命令是否执行成功
|
||||
if check_error and result.returncode != 0:
|
||||
error_msg = result.stderr.strip() or f"命令执行失败: {command}"
|
||||
@@ -64,7 +64,7 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
"""处理单个应用的注入逻辑"""
|
||||
# 获取项目根目录
|
||||
root_dir = Path(__file__).resolve().parent.parent.parent
|
||||
|
||||
|
||||
package_name = app.get("packageName")
|
||||
app_base_locate = app.get("appBaseLocate")
|
||||
bridge_file = app.get("bridgeFile")
|
||||
@@ -87,10 +87,10 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
SMExtra = app.get("SMExtra")
|
||||
keygen = app.get("keygen")
|
||||
useOptool = app.get("useOptool")
|
||||
helperNoInject = app.get("helperNoInject")
|
||||
helperNoInject = app.get("helperNoInject")
|
||||
forceSignMainExecute = app.get("forceSignMainExecute")
|
||||
dylibSelect = app.get("dylibSelect") # 选择注入的库
|
||||
|
||||
|
||||
if dylibSelect is None:
|
||||
dylibSelect = "91QiuChenly.dylib"
|
||||
|
||||
@@ -99,11 +99,18 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
optool_path = get_tool_path("optool")
|
||||
dylib_path = get_tool_path(dylibSelect)
|
||||
|
||||
local_app = [
|
||||
local_app
|
||||
for local_app in install_apps
|
||||
if local_app["CFBundleIdentifier"] == package_name
|
||||
]
|
||||
# 查找匹配的应用,同时考虑包名和路径
|
||||
local_app = []
|
||||
for app_info in install_apps:
|
||||
# 检查包名是否匹配
|
||||
if app_info["CFBundleIdentifier"] == package_name:
|
||||
# 如果配置中指定了路径,则检查路径是否匹配
|
||||
if app_base_locate:
|
||||
if app_info["appBaseLocate"] == app_base_locate:
|
||||
local_app.append(app_info)
|
||||
else:
|
||||
# 如果配置中没有指定路径,则只匹配包名
|
||||
local_app.append(app_info)
|
||||
|
||||
if not local_app and (
|
||||
app_base_locate is None or not os.path.isdir(app_base_locate)
|
||||
@@ -153,7 +160,7 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
success = True
|
||||
success &= run_command(["sudo", "chmod", "-R", "777", app_base_locate], shell=False)
|
||||
success &= run_command(["sudo", "xattr", "-cr", app_base_locate], shell=False)
|
||||
|
||||
|
||||
# 尝试终止进程,但忽略可能的错误
|
||||
run_command(["sudo", "pkill", "-f", getAppMainExecutable(app_base_locate)], shell=False, check_error=False)
|
||||
|
||||
@@ -174,11 +181,11 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
return False
|
||||
|
||||
isDevHome = False # os.getenv("InjectLibDev")
|
||||
|
||||
|
||||
# 设置工具权限
|
||||
if not run_command(f"chmod +x '{insert_dylib_path}'"):
|
||||
print(Color.red(f"[错误] 无法设置 insert_dylib 为可执行文件,请检查文件是否存在: {insert_dylib_path}"))
|
||||
|
||||
|
||||
if not run_command(f"chmod +x '{optool_path}'"):
|
||||
print(Color.red(f"[错误] 无法设置 optool 为可执行文件,请检查文件是否存在: {optool_path}"))
|
||||
|
||||
@@ -187,7 +194,7 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
command = f"sudo '{optool_path}' install -p '{dylib_path}' -t '{dest}'"
|
||||
else:
|
||||
command = f"sudo '{insert_dylib_path}' '{dylib_path}' '{backup}' '{dest}'"
|
||||
|
||||
|
||||
# 执行注入命令
|
||||
if not run_command(command):
|
||||
print(Color.red(f"[错误] 执行注入命令失败: {command}"))
|
||||
@@ -201,7 +208,7 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
if not run_command(f"{command} {source_dylib} {destination_dylib}"):
|
||||
print(Color.red(f"[错误] 复制动态库失败: {source_dylib} -> {destination_dylib}"))
|
||||
return False
|
||||
|
||||
|
||||
# codesign
|
||||
if not run_command(f"codesign -fs - --timestamp=none --all-architectures {destination_dylib}"):
|
||||
print(Color.yellow(f"[警告] 签名动态库失败: {destination_dylib}"))
|
||||
@@ -227,7 +234,7 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
if not run_command(command):
|
||||
print(Color.red(f"[错误] 执行注入命令失败: {command}"))
|
||||
success = False
|
||||
|
||||
|
||||
sign_prefix = (
|
||||
"/usr/bin/codesign -f -s - --timestamp=none --all-architectures"
|
||||
)
|
||||
@@ -245,7 +252,7 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
print("开始签名...")
|
||||
if not run_command(f"{sign_prefix} '{dest}'"):
|
||||
print(Color.yellow(f"[警告] 签名失败: {dest}"))
|
||||
|
||||
|
||||
if not run_command(f"{sign_prefix} '{app_base_locate}'"):
|
||||
print(Color.yellow(f"[警告] 签名失败: {app_base_locate}"))
|
||||
|
||||
@@ -314,5 +321,5 @@ def process_app(app, base_public_config, install_apps, current_dir=None, skip_co
|
||||
print(Color.green("App处理完成。"))
|
||||
else:
|
||||
print(Color.yellow("App处理完成,但存在一些警告或错误。"))
|
||||
|
||||
return success
|
||||
|
||||
return success
|
||||
@@ -11,7 +11,7 @@ def search_apps(app_list, install_apps, keyword):
|
||||
"""根据关键字搜索应用"""
|
||||
# 将关键字转为小写以便不区分大小写地搜索
|
||||
keyword = keyword.lower()
|
||||
|
||||
|
||||
# 构建已安装应用的字典,包含包名和应用名称(参考原始实现)
|
||||
installed_apps = {}
|
||||
for app in install_apps:
|
||||
@@ -23,12 +23,12 @@ def search_apps(app_list, install_apps, keyword):
|
||||
'name': app_name.lower(),
|
||||
'app_info': app
|
||||
}
|
||||
|
||||
|
||||
# 辅助函数:判断文本是否匹配关键字
|
||||
def is_match(text):
|
||||
if not text:
|
||||
return False
|
||||
|
||||
|
||||
if isinstance(text, str):
|
||||
# 检查文本是否包含关键字
|
||||
return keyword in text.lower()
|
||||
@@ -36,13 +36,15 @@ def search_apps(app_list, install_apps, keyword):
|
||||
# 如果是列表,检查任何元素是否匹配
|
||||
return any(keyword in item.lower() for item in text if isinstance(item, str))
|
||||
return False
|
||||
|
||||
|
||||
matched_apps = []
|
||||
|
||||
|
||||
# 遍历配置中的所有应用
|
||||
for app in app_list:
|
||||
pn_list = app.get("packageName")
|
||||
|
||||
# 获取配置中的应用路径
|
||||
config_app_path = app.get("appBaseLocate")
|
||||
|
||||
# 如果包名是列表,处理每个包名
|
||||
if isinstance(pn_list, list):
|
||||
matched = []
|
||||
@@ -53,11 +55,17 @@ def search_apps(app_list, install_apps, keyword):
|
||||
installed_app_data = installed_apps[pn]
|
||||
installed_app = installed_app_data['app_info']
|
||||
app_name = installed_app_data['name']
|
||||
|
||||
# 参考原始实现的匹配逻辑:检查包名或者应用名匹配关键字
|
||||
if is_match(pn) or is_match(app_name):
|
||||
installed_app_path = installed_app["appBaseLocate"]
|
||||
|
||||
# 检查路径是否匹配(如果配置中指定了路径)
|
||||
path_matches = True
|
||||
if config_app_path and installed_app_path:
|
||||
path_matches = config_app_path == installed_app_path
|
||||
|
||||
# 参考原始实现的匹配逻辑:检查包名或者应用名匹配关键字,并且路径匹配
|
||||
if (is_match(pn) or is_match(app_name)) and path_matches:
|
||||
matched.append({
|
||||
**app,
|
||||
**app,
|
||||
"packageName": pn,
|
||||
"displayName": installed_app["CFBundleName"],
|
||||
"version": installed_app["CFBundleShortVersionString"],
|
||||
@@ -70,59 +78,76 @@ def search_apps(app_list, install_apps, keyword):
|
||||
installed_app_data = installed_apps[pn_list]
|
||||
installed_app = installed_app_data['app_info']
|
||||
app_name = installed_app_data['name']
|
||||
|
||||
# 检查包名或者应用名匹配关键字
|
||||
if is_match(pn_list) or is_match(app_name):
|
||||
installed_app_path = installed_app["appBaseLocate"]
|
||||
|
||||
# 检查路径是否匹配(如果配置中指定了路径)
|
||||
path_matches = True
|
||||
if config_app_path and installed_app_path:
|
||||
path_matches = config_app_path == installed_app_path
|
||||
|
||||
# 检查包名或者应用名匹配关键字,并且路径匹配
|
||||
if (is_match(pn_list) or is_match(app_name)) and path_matches:
|
||||
matched_apps.append({
|
||||
**app,
|
||||
**app,
|
||||
"packageName": pn_list,
|
||||
"displayName": installed_app["CFBundleName"],
|
||||
"version": installed_app["CFBundleShortVersionString"],
|
||||
"buildVersion": installed_app["CFBundleVersion"],
|
||||
"appPath": installed_app["appBaseLocate"]
|
||||
})
|
||||
|
||||
|
||||
return matched_apps
|
||||
|
||||
|
||||
def get_installed_apps_info(app_list, install_apps):
|
||||
"""获取所有已安装且受支持的应用信息"""
|
||||
installed_supported_apps = []
|
||||
|
||||
|
||||
# 检查所有app是否在本地已安装,提前展开列表
|
||||
all_config_apps = []
|
||||
for app in app_list:
|
||||
if app.get("forQiuChenly") and not os.path.exists("/Users/qiuchenly"):
|
||||
continue
|
||||
|
||||
|
||||
pn_list = app.get("packageName")
|
||||
if isinstance(pn_list, list):
|
||||
for pn in pn_list:
|
||||
all_config_apps.append({**app, "packageName": pn})
|
||||
else:
|
||||
all_config_apps.append(app)
|
||||
|
||||
|
||||
# 检查是否已安装
|
||||
installed_app_ids = {app["CFBundleIdentifier"] for app in install_apps}
|
||||
|
||||
|
||||
# 匹配已安装的应用
|
||||
for app in all_config_apps:
|
||||
package_name = app.get("packageName")
|
||||
config_app_path = app.get("appBaseLocate")
|
||||
|
||||
if package_name in installed_app_ids:
|
||||
# 找到对应的安装应用信息
|
||||
for installed_app in install_apps:
|
||||
if installed_app["CFBundleIdentifier"] == package_name:
|
||||
# 合并信息
|
||||
app_info = {
|
||||
**app,
|
||||
"displayName": installed_app["CFBundleName"],
|
||||
"version": installed_app["CFBundleShortVersionString"],
|
||||
"buildVersion": installed_app["CFBundleVersion"],
|
||||
"appPath": installed_app["appBaseLocate"]
|
||||
}
|
||||
installed_supported_apps.append(app_info)
|
||||
break
|
||||
|
||||
installed_app_path = installed_app["appBaseLocate"]
|
||||
|
||||
# 检查路径是否匹配(如果配置中指定了路径)
|
||||
path_matches = True
|
||||
if config_app_path and installed_app_path:
|
||||
path_matches = config_app_path == installed_app_path
|
||||
|
||||
# 只有当路径匹配时才添加应用
|
||||
if path_matches:
|
||||
# 合并信息
|
||||
app_info = {
|
||||
**app,
|
||||
"displayName": installed_app["CFBundleName"],
|
||||
"version": installed_app["CFBundleShortVersionString"],
|
||||
"buildVersion": installed_app["CFBundleVersion"],
|
||||
"appPath": installed_app["appBaseLocate"]
|
||||
}
|
||||
installed_supported_apps.append(app_info)
|
||||
break
|
||||
|
||||
return installed_supported_apps
|
||||
|
||||
|
||||
@@ -130,60 +155,60 @@ def select_apps_by_keyword(app_list, install_apps):
|
||||
"""通过关键字搜索选择应用"""
|
||||
while True:
|
||||
clear_screen()
|
||||
|
||||
|
||||
# 显示提示信息
|
||||
print(Color.cyan(_("keyword_search", "关键字搜索")) + "\n")
|
||||
print(_("keyword_search_description", "请输入关键字进行搜索,支持应用名称和包名模糊搜索"))
|
||||
print(_("keyword_search_example", "示例:输入\"wechat\"可搜索微信相关应用"))
|
||||
|
||||
|
||||
# 获取用户输入
|
||||
keyword = read_input("\n" + _("enter_keyword", "请输入关键字 (输入0返回上一级): "))
|
||||
|
||||
|
||||
if keyword == '0':
|
||||
return []
|
||||
|
||||
|
||||
if not keyword:
|
||||
print(_("empty_keyword", "关键字不能为空"))
|
||||
wait_for_enter()
|
||||
continue
|
||||
|
||||
|
||||
# 搜索匹配的应用
|
||||
matched_apps = search_apps(app_list, install_apps, keyword)
|
||||
|
||||
|
||||
if not matched_apps:
|
||||
print(_("no_matching_apps", "未找到匹配的应用"))
|
||||
wait_for_enter()
|
||||
continue
|
||||
|
||||
|
||||
# 记录选择的应用列表
|
||||
app_Lst = []
|
||||
selected = set()
|
||||
|
||||
|
||||
while len(selected) < len(matched_apps):
|
||||
print("\n" + _("found_matching_apps", "找到以下匹配的应用程序:"))
|
||||
|
||||
|
||||
# 打印表头
|
||||
print_app_table_header(include_status=True)
|
||||
|
||||
|
||||
for i, app in enumerate(matched_apps, 1):
|
||||
status = _("selected", "✅ 已选中") if i-1 in selected else ""
|
||||
app_with_status = {**app, "status": status}
|
||||
print_app_info(i, app_with_status, include_status=True)
|
||||
|
||||
|
||||
print(f"\n{_('selected_apps_count', '已选择 {0}/{1} 个应用').format(len(selected), len(matched_apps))}")
|
||||
print(_("return_previous", "0. 返回上一级"))
|
||||
print(_("confirm_selection", "Enter. 确认当前选择并继续"))
|
||||
|
||||
|
||||
if len(selected) == len(matched_apps):
|
||||
print(_("all_apps_selected", "所有应用已选中..."))
|
||||
break
|
||||
|
||||
|
||||
# 显示输入提示但不换行
|
||||
print(_("enter_app_number", "请输入要选择的应用编号: "), end='', flush=True)
|
||||
|
||||
|
||||
# 获取单个字符输入
|
||||
choice = getch()
|
||||
|
||||
|
||||
if choice == '0':
|
||||
print(choice)
|
||||
if not app_Lst:
|
||||
@@ -193,7 +218,7 @@ def select_apps_by_keyword(app_list, install_apps):
|
||||
# 对于数字选择,需要读取完整的数字
|
||||
full_choice = choice
|
||||
print(choice, end='', flush=True) # 打印第一个数字
|
||||
|
||||
|
||||
# 继续读取数字直到遇到非数字字符或Enter
|
||||
while True:
|
||||
ch = getch()
|
||||
@@ -206,7 +231,7 @@ def select_apps_by_keyword(app_list, install_apps):
|
||||
else:
|
||||
print() # 换行
|
||||
break
|
||||
|
||||
|
||||
try:
|
||||
app_idx = int(full_choice)
|
||||
if 0 < app_idx <= len(matched_apps):
|
||||
@@ -216,7 +241,7 @@ def select_apps_by_keyword(app_list, install_apps):
|
||||
selected.add(index)
|
||||
print() # 换行
|
||||
print(_("app_selected", "已选择应用: {0}").format(matched_apps[index].get('displayName')))
|
||||
if len(selected) == len(matched_apps):
|
||||
if len(selected) == len(matched_apps):
|
||||
print(_("all_apps_selected", "所有应用已选中..."))
|
||||
else:
|
||||
print() # 换行
|
||||
@@ -241,7 +266,7 @@ def select_apps_by_keyword(app_list, install_apps):
|
||||
print(choice) # 打印无效字符
|
||||
print(_("invalid_input", "无效的输入,请重新选择。"))
|
||||
wait_for_enter()
|
||||
|
||||
|
||||
return app_Lst
|
||||
|
||||
|
||||
@@ -249,26 +274,26 @@ def display_supported_apps(app_list, install_apps, page=0, page_size=20):
|
||||
"""分页显示已安装且支持的应用程序"""
|
||||
installed_supported_apps = get_installed_apps_info(app_list, install_apps)
|
||||
total_apps = len(installed_supported_apps)
|
||||
|
||||
|
||||
if total_apps == 0:
|
||||
print("\n" + _("no_installed_supported_apps", "未找到已安装且受支持的应用程序"))
|
||||
return [], 0, 0
|
||||
|
||||
|
||||
total_pages = (total_apps + page_size - 1) // page_size
|
||||
page = max(0, min(page, total_pages - 1)) # 确保页码有效
|
||||
|
||||
|
||||
start_idx = page * page_size
|
||||
end_idx = min(start_idx + page_size, total_apps)
|
||||
|
||||
|
||||
page_info = _("installed_supported_apps_list", "已安装且支持的应用列表 (第 {0}/{1} 页, 共 {2} 个应用)").format(page+1, total_pages, total_apps)
|
||||
print(f"\n{page_info}")
|
||||
|
||||
|
||||
# 打印表头
|
||||
print_app_table_header()
|
||||
|
||||
|
||||
for i, app in enumerate(installed_supported_apps[start_idx:end_idx], start_idx+1):
|
||||
print_app_info(i, app)
|
||||
|
||||
|
||||
return installed_supported_apps[start_idx:end_idx], page, total_pages
|
||||
|
||||
|
||||
@@ -280,61 +305,75 @@ def show_all_supported_apps(app_list, install_apps):
|
||||
# 跳过特定用户专用的应用
|
||||
if app.get("forQiuChenly") and not os.path.exists("/Users/qiuchenly"):
|
||||
continue
|
||||
|
||||
|
||||
pn_list = app.get("packageName")
|
||||
if isinstance(pn_list, list):
|
||||
for pn in pn_list:
|
||||
all_apps.append({**app, "packageName": pn})
|
||||
else:
|
||||
all_apps.append(app)
|
||||
|
||||
|
||||
# 尝试匹配安装信息
|
||||
installed_apps_map = {app["CFBundleIdentifier"]: app for app in install_apps}
|
||||
for app in all_apps:
|
||||
package_name = app.get("packageName")
|
||||
config_app_path = app.get("appBaseLocate")
|
||||
|
||||
if package_name in installed_apps_map:
|
||||
installed_app = installed_apps_map[package_name]
|
||||
app["displayName"] = installed_app["CFBundleName"]
|
||||
app["version"] = installed_app["CFBundleShortVersionString"]
|
||||
app["buildVersion"] = installed_app["CFBundleVersion"]
|
||||
app["appPath"] = installed_app["appBaseLocate"]
|
||||
app["isInstalled"] = True
|
||||
installed_app_path = installed_app["appBaseLocate"]
|
||||
|
||||
# 检查路径是否匹配(如果配置中指定了路径)
|
||||
path_matches = True
|
||||
if config_app_path and installed_app_path:
|
||||
path_matches = config_app_path == installed_app_path
|
||||
|
||||
# 只有当路径匹配时才标记为已安装
|
||||
if path_matches:
|
||||
app["displayName"] = installed_app["CFBundleName"]
|
||||
app["version"] = installed_app["CFBundleShortVersionString"]
|
||||
app["buildVersion"] = installed_app["CFBundleVersion"]
|
||||
app["appPath"] = installed_app["appBaseLocate"]
|
||||
app["isInstalled"] = True
|
||||
else:
|
||||
app["displayName"] = package_name
|
||||
app["isInstalled"] = False
|
||||
else:
|
||||
app["displayName"] = package_name
|
||||
app["isInstalled"] = False
|
||||
|
||||
|
||||
print("\n" + _("total_supported_apps", "支持的应用总数: {0}").format(len(all_apps)))
|
||||
|
||||
|
||||
page_size = 10
|
||||
page = 0
|
||||
total_pages = (len(all_apps) + page_size - 1) // page_size
|
||||
|
||||
|
||||
selected_apps = []
|
||||
|
||||
|
||||
while True:
|
||||
start_idx = page * page_size
|
||||
end_idx = min(start_idx + page_size, len(all_apps))
|
||||
|
||||
|
||||
print("\n" + _("showing_page", "显示第 {0}/{1} 页 (应用 {2}-{3}/{4})").format(page+1, total_pages, start_idx+1, end_idx, len(all_apps)))
|
||||
|
||||
|
||||
# 打印表头
|
||||
print_app_table_header(include_status=True)
|
||||
|
||||
|
||||
for i, app in enumerate(all_apps[start_idx:end_idx], start_idx+1):
|
||||
print_app_info(i, app, include_status=True)
|
||||
|
||||
|
||||
print("\n" + _("operation_options", "操作选项:"))
|
||||
print(f"{Color.cyan('n')}. {_('next_page', '下一页')} | {Color.cyan('p')}. {_('prev_page', '上一页')} | {Color.cyan(_('number', '数字'))}. {_('select_app', '选择应用')} | {Color.cyan('0')}. {_('confirm_and_return', '确认并返回')}")
|
||||
|
||||
|
||||
# 显示输入提示但不换行
|
||||
print("\n" + _("select_operation", "请选择操作: "), end='', flush=True)
|
||||
|
||||
|
||||
# 获取单个字符输入
|
||||
choice = getch()
|
||||
|
||||
|
||||
if choice in ['n', 'p', '0']:
|
||||
print(choice) # 打印当前字符提供反馈
|
||||
|
||||
|
||||
if choice == 'n':
|
||||
if page < total_pages - 1:
|
||||
page += 1
|
||||
@@ -353,7 +392,7 @@ def show_all_supported_apps(app_list, install_apps):
|
||||
# 对于数字选择,需要读取完整的数字
|
||||
full_choice = choice
|
||||
print(choice, end='', flush=True) # 打印第一个数字
|
||||
|
||||
|
||||
# 继续读取数字直到遇到非数字字符或Enter
|
||||
while True:
|
||||
ch = getch()
|
||||
@@ -366,7 +405,7 @@ def show_all_supported_apps(app_list, install_apps):
|
||||
else:
|
||||
print() # 换行
|
||||
break
|
||||
|
||||
|
||||
try:
|
||||
app_idx = int(full_choice)
|
||||
if 1 <= app_idx <= len(all_apps[start_idx:end_idx]):
|
||||
@@ -392,5 +431,5 @@ def show_all_supported_apps(app_list, install_apps):
|
||||
print(choice) # 打印无效字符
|
||||
print(_("invalid_choice", "无效的选择,请重新选择"))
|
||||
wait_for_enter()
|
||||
|
||||
return selected_apps
|
||||
|
||||
return selected_apps
|
||||
Reference in New Issue
Block a user