looking4freedom 发表于 2021-11-1 14:27

写了一个控制wsa的工具箱,一键操作wsa和手机

本帖最后由 looking4freedom 于 2021-11-1 19:02 编辑


连接的设备默认是选中状态,如果同时连接多台设备需要注意勾选使用哪台设备
连接到wsa时会检查wsa安装的第三方包,下拉框选择包名启动
在wsa安装卸载应用或者新设备连接断开时,需要点击刷新设备获取最新数据
1.选择文件
浏览本地的电脑目录,选择需要被安装的apk文件,确定后自动写入到输入框中

2.安装APP
使用adb install -r 进行安装

3.刷新设备
当有新的设备连接时或者需要刷新最新安装包数据,需要点击此按钮

4.清除日志
使用adb logcat -c清除手机日志缓存

5.断开/重连
连接到wsa的时候点击是断开连接,再次点击则是重新连接wsa

6.获取页面
使用adb shell dumpsys activity activities | findstr mResumedActivity,信息在工具箱绑定的日志窗口查看,获取到正在运行的页面通过正则提取包名自动填写到输入框中


7.清除数据
需要输入对应app的包名,使用adb shell pm clear清除该app全部数据

8.杀掉应用
需要输入对应app的包名,使用adb shell am force-stop结束该app当前进程

9.查看进程
使用adb shell dumpsys ps -ef | findstr 查看app运行进程

10.一键卸载
使用adb uninstall卸载应用

# -*- coding: utf-8 -*-#

# -------------------------------------------------------------------------------
# Name:         wsa_tools
# Description:adb一键控制wsa和手机设备
# Author:       looking4freedom
# Date:         2021/10/25
# -------------------------------------------------------------------------------
import json
import os
import tkinter as tk
from tkinter import *
import threading
from tkinter import ttk
from tkinter import filedialog


# tkinter制作界面
class APKTk:

    def __init__(self):
      self.root = Tk()
      self.root.geometry('800x300')
      self.root.title("ADB控制器")
      self.path = StringVar()
      self.path.set("请输入需要安装的apk完整路径")
      self.package_name = StringVar()
      self.package_name.set("请输入app的包名")
      self.select_device_list = []
      self.device_list = self.get_device_list()
      self.cb_list = []
      self.cmb_list = []
      self.package_3 = self.show_package()
      self.flag = True

      try:
            cmd = 'adb connect 127.0.0.1:58526'
            os.system(cmd)
      except:
            print("请检查WSA设置,是否开启开发人员模式")

    @staticmethod
    def install_and_open(device_name, file_path):
      # 安装app
      os.system("adb -s " + device_name + " install -r " + file_path)

    @staticmethod
    def clear_data(device_name, package_name):
      # 清除全部数据
      os.system("adb -s " + device_name + " shell pm clear " + package_name)

    @staticmethod
    def kill_process(device_name, package_name):
      # 强制杀死app
      os.system("adb -s " + device_name + " shell am force-stop " + package_name)

    def get_activity(self):
      # 获取设备当前的activity
      for j in self.devices_list():
            print(f"设备{j}当前页面信息:")
            phone_page = os.popen("adb -s " + j + " shell dumpsys activity activities | findstr mResumedActivity")
            phone_page_str = phone_page.read()
            phone_page.close()
            print(phone_page_str)
            try:
                for i in phone_page_str.split('\n'):
                  if "com.microsoft.windows.userapp" not in i:
                        app_name = re.findall(r'(com.*?)/', i)
                        self.package_name.set(app_name)
            except IndexError:
                pass

    def check_process(self):
      # 查看进程
      for i in self.devices_list():
            print(f"设备{i}的应用{self.get_package_name()}当前进程信息:")
            os.system("adb -s " + i + " shell ps -ef | findstr " + str(self.get_package_name()))

    def show_package(self):
      # 列出第三方包
      for i in self.device_list:
            if i == '127.0.0.1:58526':
                print(f"设备{i}的第三方应用包:")
                res = os.popen("adb -s " + i + " shell pm list package -3")
                res_str = res.readlines()
                res.close()
                packages = for i in res_str]
                print('packages', packages)
                return packages

    def outline_or_online(self):
      if self.flag:
            os.system("adb disconnect 127.0.0.1:58526")
            self.flag = False
      else:
            os.system("adb connect 127.0.0.1:58526")
            self.flag = True

    @staticmethod
    def clear_log_cache(device_name):
      # 清除手机日志缓存
      os.system("adb -s " + device_name + " logcat -c")
      print(f"设备{device_name}清除日志缓存成功")

    @staticmethod
    def uninstall_all(device_name, package_name):
      # 卸载app
      os.system("adb -s " + device_name + " uninstall " + package_name)

    @staticmethod
    def get_device_list():
      res = os.popen("adb devices")
      res_str = res.readlines()
      res.close()
      device_list = for sub in res_str]
      return device_list

    def mul_check_box(self):
      print("制作多选框", self.device_list)
      for index, item in enumerate(self.device_list):
            with os.popen("adb -s " + item + " -d shell getprop ro.product.brand") as f:
                android_brand = f.read().strip()
            with os.popen("adb -s " + item + " -d shell getprop ro.product.model") as f:
                android_model = f.read().strip()
            with os.popen("adb -s " + item + " -d shell getprop ro.build.version.release") as f:
                android_version = f.read().strip()
            device_mes = {
                "手机品牌": android_brand,
                "手机型号": android_model,
                "安卓版本": android_version
            }
            device_mes = json.dumps(device_mes, ensure_ascii=False)
            device_info = item + '\n' + device_mes
            self.select_device_list.append(tk.StringVar())
            cb = Checkbutton(self.root, text=device_info, variable=self.select_device_list[-1],
                           onvalue=item, offvalue='')
            self.cb_list.append(cb)
            cb.grid(row=index, column=0, sticky='w')
            cb.select()

    def combobox_list(self):
      theLabel = tk.Label(self.root, text='请选择WSA中你要启动的APP:')
      self.cmb_list.append(theLabel)
      theLabel.grid(row=len(self.device_list) + 1, sticky='w')
      comvalue = tk.StringVar()
      comboxlist = ttk.Combobox(self.root, textvariable=comvalue, state='readonly', values=self.package_3)# 初始化
      self.cmb_list.append(comboxlist)
      comboxlist.bind("<<ComboboxSelected>>", lambda _: os.system("adb -s 127.0.0.1 shell monkey -p " + str(comboxlist.get()) + ' 1'))# 绑定事件,(下拉列表框被选中时,绑定go()函数)
      comboxlist.grid(row=len(self.device_list) + 1)

    def select_path(self):
      # 选择文件
      file_path = filedialog.askopenfilename()
      self.path.set(file_path)
      return file_path

    # 刷新设备列表
    def refresh_data(self):
      print("重新获取设备信息")
      for item in self.cb_list:
            item.destroy()
      self.cb_list = []
      self.device_list = self.get_device_list()
      self.select_device_list = []
      self.mul_check_box()
      for item in self.cmb_list:
            item.destroy()
      self.cmb_list = []
      self.package_3 = self.show_package()
      self.combobox_list()

    def path_button(self):
      Entry(self.root, textvariable=self.path, width=65).grid(row=len(self.device_list) + 2, column=0)
      Button(self.root, text="选择文件", command=self.select_path).grid(row=len(self.device_list) + 2, column=1)

    def install_button(self):
      button_install = Button(self.root, text="安装APP", command=self.install)
      button_install.grid(row=len(self.device_list) + 2, column=2)

    def refresh_button(self):
      button_install = Button(self.root, text="刷新设备", command=self.refresh_data)
      button_install.grid(row=len(self.device_list) + 2, column=3)

    def activity_button(self):
      Button(self.root, text="获取页面", command=self.get_activity).grid(row=len(self.device_list) + 3, column=1)

    def clear_button(self):
      button_clear = Button(self.root, text="清除数据", command=self.clear)
      button_clear.grid(row=len(self.device_list) + 3, column=2)

    def kill_button(self):
      button_kill = Button(self.root, text="杀掉应用", command=self.kill)
      button_kill.grid(row=len(self.device_list) + 3, column=3)

    def check_button(self):
      button_check = Button(self.root, text="查看进程", command=self.check_process)
      button_check.grid(row=len(self.device_list) + 3, column=4)

    def package_button(self):
      button_check = Button(self.root, text="断开/重连", command=self.outline_or_online)
      button_check.grid(row=len(self.device_list) + 2, column=5)

    def cache_button(self):
      button_gdt = Button(self.root, text="清除日志", command=self.cache)
      button_gdt.grid(row=len(self.device_list) + 2, column=4)

    def uninstall_button(self):
      button_gdt = Button(self.root, text="一键卸载", command=self.uninstall)
      button_gdt.grid(row=len(self.device_list) + 3, column=5)

    def input_text(self):
      entry_log = Entry(self.root, width=65, textvariable=self.path)
      entry_log.grid(row=len(self.device_list) + 2, column=0, sticky='w')

    def input_package(self):
      package_log = Entry(self.root, width=65, textvariable=self.package_name)
      package_log.grid(row=len(self.device_list) + 3, column=0, sticky='w')

    def get_apk_name(self):
      return self.path.get()

    def get_package_name(self):
      return self.package_name.get()

    def devices_list(self):
      selected_device_list =
      print(selected_device_list)
      return selected_device_list

    def mainloop(self):
      self.root.mainloop()

    def install(self):
      apk_name = self.get_apk_name()
      print(apk_name)
      for device in self.devices_list():
            threading.Thread(target=self.install_and_open, args=(device, apk_name)).start()

    def clear(self):
      package_name = self.get_package_name()

      for device in self.devices_list():
            threading.Thread(target=self.clear_data, args=(device, package_name)).start()

    def kill(self):
      package_name = self.get_package_name()

      for device in self.devices_list():
            threading.Thread(target=self.kill_process, args=(device, package_name)).start()

    def cache(self):
      for device in self.devices_list():
            threading.Thread(target=self.clear_log_cache, args=(device,)).start()

    def uninstall(self):
      package_name = self.get_package_name()
      for device in self.devices_list():
            threading.Thread(target=self.uninstall_all, args=(device, package_name)).start()


if __name__ == '__main__':
    apkTk = APKTk()
    apkTk.mul_check_box()
    apkTk.combobox_list()
    apkTk.path_button()
    apkTk.input_package()
    apkTk.install_button()
    apkTk.refresh_button()
    apkTk.activity_button()
    apkTk.clear_button()
    apkTk.kill_button()
    apkTk.check_button()
    apkTk.package_button()
    apkTk.cache_button()
    apkTk.uninstall_button()
    apkTk.root.mainloop()


上传的压缩包大于3.1M{:301_1008:},那就只有自己在本地使用pyinstaller -F 加文件名打包成exe方便使用
网盘链接:https://www.aliyundrive.com/s/wVpn9gf5br5

风逝998 发表于 2021-11-1 17:57

支持原创,幸苦楼主

looking4freedom 发表于 2021-11-1 17:59

风逝998 发表于 2021-11-1 17:57
支持原创,幸苦楼主

谢谢支持

ljxnl1 发表于 2021-11-1 18:44

looking4freedom 发表于 2021-11-1 19:04

ljxnl1 发表于 2021-11-1 18:44
希望楼主把打好包的文件传到网盘下载谢谢!

上传审核中,需要下载的话先提前把网盘链接发给你
链接:https://www.aliyundrive.com/s/wVpn9gf5br5

ljxnl1 发表于 2021-11-2 18:19

looking4freedom 发表于 2021-11-2 19:37

ljxnl1 发表于 2021-11-2 18:19
能换个别的网盘吗,比如百度网盘之类的,谢谢。(还没审核通过呢)

链接:https://pan.baidu.com/s/1FX5SU5ep06B3siTKC8ky1A
提取码:4o22
ps:运行需要adb环境

ljxnl1 发表于 2021-11-2 20:04

looking4freedom 发表于 2021-11-2 20:08

ljxnl1 发表于 2021-11-2 20:04
请问这是个安卓手机刷机软件吗?能具体解释一下吗谢谢!

我上面使用方法写的很详细 就是用按钮代替adb命令控制连接电脑的手机和win11上面安装的wsa

luckyHu 发表于 2021-11-12 17:24

支持原创
页: [1] 2
查看完整版本: 写了一个控制wsa的工具箱,一键操作wsa和手机