import os
import subprocess
import re
class LdInit:
def __init__(self, path: str):
"""
初始化雷电模拟器ldconsole.exe操作
:param path: str,雷电模拟器安装目录
"""
os.putenv('Path', path)
@staticmethod
def Run_Command(command: str):
"""
取DOS执行结果
:param command: str,命令
:return: str,返回值
"""
# process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# stdout, _ = process.communicate()
# return stdout.decode('gbk')
result = subprocess.run(command, capture_output=True, shell=True, encoding='gbk')
return result.stdout
def Info_Ld(self):
"""
# 获取雷电模拟器的信息/刷新模拟器
:return:
"""
return self.Run_Command('ldconsole.exe list2')
def Start_Ld(self, num: int):
"""
启动指定雷电模拟器
:param num: int,模拟器ID
:return:
"""
command = f'ldconsole.exe launch --index {num}'
self.Run_Command(command)
def Stop_Ld(self, num: int):
"""
关闭指定雷电模拟器
:param num: int,模拟器ID
:return:
"""
command = f'ldconsole.exe quit --index {num}'
self.Run_Command(command)
def Restart_Ld(self, num: int):
"""
重启指定雷电模拟器
:param num: int,模拟器ID
:return:
"""
command = f'ldconsole.exe reboot --index {num}'
self.Run_Command(command)
def Sort_Ld_Windows(self):
"""
排列模拟器窗口
:return:
"""
self.Run_Command('ldconsole.exe sortWnd')
class LdOperate:
def __init__(self, path: str):
"""
初始化雷电模拟器ld.exe操作
:param path: str,雷电模拟器安装路径
"""
os.putenv('Path', path)
@staticmethod
def Run_Command(command: str):
"""
取DOS执行结果
:param command: str,命令
:return: str,返回值
"""
# process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# stdout, _ = process.communicate()
# return stdout.decode('gbk')
result = subprocess.run(command, capture_output=True, shell=True, encoding='gbk')
return result.stdout
def Key_Click(self, num: int, key: str):
"""
雷电模拟器按键点击
:param num: int,模拟器ID
:param key: str,键值
:return:
"""
command = f'ld.exe -s {num} input keyevent {key}'
return self.Run_Command(command)
def Get_Phone_Model(self, num: int):
"""
取模雷电拟器机型信息
:param num: int,模拟器ID
:return:
"""
command = f'ld.exe -s {num} getprop ro.product.model'
return self.Run_Command(command)
def View_Memory_Usage(self, num: int, PackageName: str):
"""
查看指定应用内存占用
:param num: int,模拟器ID
:param PackageName: str,应用包名
:return:
"""
command = f'ld.exe -s {num} dumpsys meminfo {PackageName}'
return self.Run_Command(command)
def Enumerate_Package_Names(self, num: int,
filter: int):
"""
枚举包名 filter留空或者为0,枚举所有包名;1,显示每个包的文件位置;2,只显示禁用的应用的包名;3,只显示可用的应用的包名;4,只显示系统应用的包名;5,只显示第三方应用的包名;6,查看应用的安装者。
:param num: int,模拟器ID
:param filter: int,枚举范围
:return:
"""
filter_dict = {
0: "",
1: " -f",
2: " -d",
3: " -e",
4: " -s",
5: " -3",
6: " -i"
}
if filter in filter_dict:
parameter = filter_dict[filter]
else:
parameter = ""
command = f'ld.exe -s {num} pm list packages {parameter}'
return self.Run_Command(command)
def Get_Android_Version(self, num: int):
"""
取雷电模拟器安卓版本
:param num: int,模拟器ID
:return:
"""
command = f'ld.exe -s {num} getprop ro.build.version.release'
return self.Run_Command(command)
def View_File_Contents(self, num: int, path: str):
"""
查看文件内容,如果安卓版本小于7,需要处理文件路径,好像用不到,现在都是7以上(懒得写文件路径处理)
:param num: int,模拟器ID
:param path: str,欲查看文件绝对路径
:return:
"""
command = f'ld.exe -s {num} cat "{path}"'
return self.Run_Command(command)
def Find_Files(self, num: int, path: str, filename: str):
"""
查找文件
:param num: int,模拟器ID
:param path: str,查找路径
:param filename: str,文件名
:return:
"""
command = f'ld.exe -s {num} "find {path} -name "{filename}""'
return self.Run_Command(command)
def Find_App_Package_Name(self, num: int, keyword: str):
"""
通过关键词来模糊搜索模拟器中安装的应用,返回匹配的数量和包名数组。比如不同平台的游戏客户端,包名都会有所不同,但都有着相似的包名,这个命令就很有用了。
:param num: int,模拟器ID
:param keyword: str,关键词
:return:
"""
AllPackageName = self.Enumerate_Package_Names(num, 0)
lines = AllPackageName.splitlines()
allPackageName = [line for line in lines if line != ""]
search_pattern = re.compile(re.escape(keyword), re.IGNORECASE)
matching_packages = [package for package in allPackageName if search_pattern.search(package)]
if matching_packages:
for package in matching_packages:
return package
else:
return None
def Create_Directory(self, num: int, directoryname: str):
"""
创建目录
:param num: int,模拟器ID
:param directoryname: str,目录绝对路径
:return:
"""
command = f'ld.exe -s {num} mkdir "{directoryname}"'
return self.Run_Command(command)
def Create_A_File(self, num: int, filename: str):
"""
创建文件
:param num: int,模拟器ID
:param filename: str,文件绝对路径
:return:
"""
command = f'ld.exe -s {num} touch "{filename}"'
return self.Run_Command(command)
def Read_Task_Stack(self, num: int, filtertype: int):
"""
读任务栈
:param num: int,模拟器ID
:param filtertype: int,0 = 全部activity信息,也就是“adb dumpsys activity”所返回的内容。1 = 运行中的任务栈(Running activities)。2 = 顶栈任务栈(mFocusedActivity)。3 = 最顶端top-activity。
:return:
"""
filtertype_dict = {
0: f"dumpsys activity",
1: f"dumpsys activity | grep 'mResumedActivity'",
2: f"dumpsys activity | grep 'mFocusedActivity'",
3: f"dumpsys activity | grep 'top-activity'",
}
if filtertype in filtertype_dict:
parameter = filtertype_dict[filtertype]
else:
parameter = "dumpsys activity"
command = f'ld.exe -s {num} "{parameter}"'
return self.Run_Command(command)
def Send_Text(self, num: int, TextContent: str):
"""
向窗口输入指定文本内容,不支持中文
:param num: int,模拟器ID
:param TextContent: str,文本内容
:return:
"""
command = f'ld.exe -s {num} input text "{TextContent}"'
return self.Run_Command(command)
def Copy_File(self, num: int, CopiedFiles: str, CopyToFile: str):
"""
复制文件
:param num: int,模拟器ID
:param CopiedFiles: str,被复制文件名
:param CopyToFile: str,复制到文件名
:return:
"""
command = f'ld.exe -s {num} cp {CopiedFiles} {CopyToFile}'
return self.Run_Command(command)
def Close_App(self, num: int, PackageName: str):
"""
关闭应用
:param num: int,模拟器ID
:param PackageName: str,应用包名
:return:
"""
command = f'ld.exe -s {num} am force-stop {PackageName}'
return self.Run_Command(command)
def Disable_App(self, num: int, PackageName: str, State: bool):
"""
禁用应用,只有系统应用才可以用,第三方应用不行
:param num: int,模拟器ID
:param PackageName: str,应用包名
:param State: bool,假为不禁用,真为禁用
:return:
"""
if State:
parameter = "enable"
else:
parameter = "disable"
command = f'ld.exe -s {num} pm {parameter} {PackageName}'
return self.Run_Command(command)
def Screenshot(self, num: int, FilePath: str):
"""
截屏
:param num: int,模拟器ID
:param FilePath: str,文件路径
:return:
"""
command = f'ld.exe -s {num} "shell screencap -p {FilePath}"'
return self.Run_Command(command)
def Browse_Web_Pages(self, num: int, url: str):
"""
浏览网页
:param num: int,模拟器ID
:param url: str,网址
:return:
"""
command = f'ld.exe -s {num} am start -a android.intent.action.VIEW -d {url}'
return self.Run_Command(command)
class DnconsoleOperate:
def __init__(self, path): # 路径加载到环境变量
"""
初始化雷电模拟器dnconsole.exe操作
:param path: str,雷电模拟器安装路径
"""
os.putenv('Path', path)
@staticmethod
def Run_Command(command):
"""
取DOS执行结果
:param command: str,命令
:return: str,返回值
"""
# process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
# stdout, _ = process.communicate()
# return stdout.decode('gbk')
result = subprocess.run(command, capture_output=True, shell=True, encoding='gbk')
return result.stdout
def Get_Prop(self, num, method):
"""
不知道干什么的 看不懂 嘤嘤嘤
:param num: int,模拟器ID
:param method:
:return:
"""
command = f'dnconsole.exe getprop --index {num} --key "{method}"'
return self.Run_Command(command)
def StartingApplication(self, num, package):
"""
启动指定包名app
:param num: int,模拟器ID
:param package: str,应用包名
:return:
"""
command = f'dnconsole.exe runapp --index {num} --packagename {package}'
return self.Run_Command(command)
if __name__ == "__main__":
# ldinit = LdInit(r'D:\leidian\LDPlayer9')
# ldinit.Start_Ld(0)
ldop = LdOperate(r'D:\leidian\LDPlayer9')
# ldop.Create_Directory(0, r"/storage/emulated/0/test")
# ldop.Find_Files(0, r"/storage/emulated/0", "a.txt")
# print(ldop.Get_Android_Version(0))
# print(ldop.Read_Task_Stack(0, 0))
# ldop.Send_Text(0, "183726")
res = ldop.Copy_File(0, "/data/misc/user/0/cacerts-added/364618e0.0", "system/etc/security/cacerts/364618e0.0")
print(res)
版权属于:CuteKitty
本文链接:https://blog.cutekitty.cn/index.php/archives/10/
作品采用
知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可