- PyWinAuto入门指南·https://zhuanlan.zhihu.com/p/37283722
- pywinauto简明教程·https://www.dazhuanlan.com/2019/09/26/5d8bf582966da/
- pywinauto教程·https://blog.csdn.net/weixin_40161673/article/details/83246861
一个栗子:File.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import tkinter as tk
from tkinter import ttk
from tkinter import scrolledtext #导入滚动文本框的模块
import tkinter.messagebox #弹窗库
import tkinter.filedialog #文件选择
from threading import Thread #线程
import uuid,socket,psutil,time,os,configparser,base64,subprocess,webbrowser,requests,json
#创建快捷方式用到的依赖
import comtypes
from comtypes.client import CreateObject
from comtypes.persist import IPersistFile
from comtypes.shelllink import ShellLink
#图标文件
from icon import Icon
#点击框架
import subprocess
import uiautomation as auto
auto.uiautomation.SetGlobalSearchTimeout(10) # 设置全局搜索超时 15
def PrintNetIfAddr(title="以太网",ip="192.168."):
#"以太网","192.168.1.177"
r""" 打印多网卡 mac 和 ip 信息 """
dic = psutil.net_if_addrs()
for adapter in dic:
snicList = dic[adapter]
mac = '无 mac 地址'
ipv4 = '无 ipv4 地址'
ipv6 = '无 ipv6 地址'
for snic in snicList:
if snic.family.name in {'AF_LINK', 'AF_PACKET'}:
mac = snic.address
elif snic.family.name == 'AF_INET':
ipv4 = snic.address
elif snic.family.name == 'AF_INET6':
ipv6 = snic.address
#print('%s, %s, %s, %s' % (adapter, mac, ipv4, ipv6))
if title in adapter and ip in ipv4:
mac = mac.replace("-",":")
print(mac,ipv4)
return mac,ipv4
print("没有获取到网卡信息")
return "00:00:00:00:00:00","0.0.0.0"
#初始化本地配置文件
def initConfigFile():
config = configparser.ConfigParser()
config.read("conf.ini")
config.add_section("chrome")
config.set("chrome", "path", "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe")
config.set("chrome", "number", "0")
with open("conf.ini","w+") as f:
config.write(f)
#读取配置文件
def rConfigFile():
config = configparser.ConfigParser()
config.read("conf.ini")
config.sections()
return config.get("chrome", "path"),config.get("chrome", "number")
#设置/更新配置文件
def sConfigFile():
config = configparser.ConfigParser()
config.read("conf.ini")
config.set("chrome", "path", path.get())
config.set("chrome", "number", age.get())
with open("conf.ini","w+") as f:
config.write(f)
tkinter.messagebox.showinfo(title="成功", message="配置保存成功!")
bLog.set("配置保存成功!")
#选择文件
def selectFile():
desktopPath = tkinter.filedialog.askopenfilename(title=u'选择文件', initialdir=(os.path.join(os.path.expanduser('~'),"Desktop")))
if len(desktopPath) <= 0:
return None
if "chrome.exe" not in desktopPath:
tkinter.messagebox.showwarning(title='文件错误', message='请选择Chrome浏览器的chrome.exe主程序!')
return None
path.set(desktopPath)
#创建窗口,并居中
def center_window(win, width=0, height=0):
screenwidth = win.winfo_screenwidth()
screenheight = win.winfo_screenheight()
size = '%dx%d+%d+%d' % (width, height, (screenwidth - width)/2, (screenheight - height)/2)
win.geometry(size)
#关闭提示
def on_closing():
if tkinter.messagebox.askokcancel("注意!","该程序用于处理XXXX事项,确定关闭该程序吗?"):
win.destroy()
#保存配置并创建快捷方式
def saveConfig():
bLog.set("请稍等...")
#这里验证用于用户第一次运行,使用默认路径时并未验证路径是否正确或是否安装的有浏览器
if os.path.isfile(path.get()) == False:
tkinter.messagebox.showwarning(title='文件错误', message='请确认是否安装Chrome浏览器或点击左侧重新选择浏览器路径!')
bLog.set("Chrome浏览器路径错误!")
return None
sConfigFile()
chromePath,chromeNumber = rConfigFile()
for BNum in range(int(chromeNumber)):
chromePatameter = r"-ignore-certificate-errors --test-type --ignore-certificate-errors --user-data-dir=C:\ChromeRf\No"+str(BNum+1)
vbsCenter = 'Set Shell = CreateObject("WScript.Shell") \n DesktopPath = Shell.SpecialFolders("Desktop") \n Set link = Shell.CreateShortcut(DesktopPath & "\Chrome浏览器_'+str(BNum+1)+'号.lnk") \n link.Arguments = "'+chromePatameter+'" \n link.Description = "" \n link.HotKey = "CTRL+K" \n link.IconLocation = "'+chromePath+'" \n link.TargetPath = "'+chromePath+'" \n link.WindowStyle = 1 \n link.WorkingDirectory = "'+chromePath+'" \n link.Save'
create__file("createLnk_"+str(BNum+1)+".vbs",vbsCenter)
subprocess.call('cscript createLnk_'+str(BNum+1)+'.vbs')
bLog.set("快捷方式已创建,3秒后删除创建脚本!")
print("快捷方式已创建,3秒后删除创建脚本!")
time.sleep(3)
for BNum in range(int(chromeNumber)):
os.remove('createLnk_'+str(BNum+1)+'.vbs')
bLog.set("已删除:createLnk_"+str(BNum+1)+".vbs")
print("已删除:",'createLnk_'+str(BNum+1)+'.vbs')
bLog.set("欢迎使用XXXX工具")
#创建文件
def create__file(file_path,msg):
f=open(file_path,"a")
f.write(msg)
f.close
#打开计划任务
def schtasks():
cmdObj = os.popen("taskschd")
#打开首页
def openHome():
webbrowser.open("http://www.baidu.com", new=0, autoraise=True)
#开启异步
def asyncs(f):
def wrapper(*args, **kwargs):
thr = Thread(target=f, args=args, kwargs=kwargs)
thr.start()
return wrapper
#请求接口
@asyncs
def getHttpApi():
mac,ipv4 = PrintNetIfAddr()
postUrl = "https://www.iicode.top/api.php"
postData = {
"action":"getConfig",
"mac":mac
}
try:
res = requests.post(postUrl,data = postData)
except Exception as e:
bLog.set("网络请求出现问题,暂时无法使用!")
print("网络请求出现问题:",postUrl)
#print(e)
if "res" in locals():
jsonObj = json.loads(res.text)
identityText.set("单位:"+jsonObj['remarks'])
serverDateText.set("服务器时间:"+jsonObj['serverDate'])
print(jsonObj['remarks'])
#1.重启浏览器 2推送机器状态 3重启 4关机 5
bLog.set("程序待命中...")
#输入密码
@asyncs
def inputPass():
print(auto.GetRootControl())
try:
#打开指定程序
#subprocess.Popen('notepad.exe')
# 首先从桌面的第一层子控件中找到记事本程序的窗口WindowControl,再从这个窗口查找子控件
notepadWindow = auto.WindowControl(searchDepth=4, ClassName='#32770')
print(notepadWindow.Name)
notepadWindow.SetTopmost(True)
# 查找notepadWindow所有子孙控件中的第一个EditControl,因为EditControl是第一个子控件,可以不指定深度
notepadWindow.EditControl(Name="计算机(C):").GetValuePattern().SetValue('Hello')
notepadWindow.EditControl(Name="用户名:").GetValuePattern().SetValue('Hi')
# 先从notepadWindow的第一层子控件中查找TitleBarControl,
# 然后从TitleBarControl的子孙控件中找第二个ButtonControl, 即最大化按钮,并点击按钮
#notepadWindow.TitleBarControl(Depth=1).ButtonControl(foundIndex=2).Click()
# 从notepadWindow前两层子孙控件中查找Name为'关闭'的按钮并点击按钮
notepadWindow.ButtonControl(searchDepth=2, Name='最小化').Click()
# 这时记事本弹出是否保存提示,按热键Alt+N不保存退出。
auto.SendKeys('{Alt}s')
except Exception as e:
print("找不到主窗口")
@asyncs
def clockLoop():
count = 0
while True:
time.sleep(1)
if count%20 == 0:#20秒执行一次
getHttpApi()
inputPass()
if count>=2678400:#一个月归零一次 2678400 秒大概是一个月的时间
count = 0
count += 1
if __name__ == "__main__":
#声明对象
win = tk.Tk()
#设置窗口主题
win.title("XXXX辅助工具 Python版")
#窗口是否允许拉伸
win.resizable(width=False,height=False)
#窗口透明度
win.attributes('-alpha', 1.0)
#居中
center_window(win,700,190)
#创建顶部日志容器,父级容器为win
monty_top = ttk.LabelFrame(win,text="日志区")
#设置行 列 外边距x 外边距y
monty_top.grid(row=0,column=0,padx=5,pady=5,sticky=tk.W)
#右边按钮区域容器
monty_right = ttk.LabelFrame(win,text="操作区")
#设置行 列 外边距x 外边距y
monty_right.grid(row=0,column=1,padx=5,pady=5,rowspan=2,sticky=tk.W)
#左边选择路径容器
monty_left = ttk.LabelFrame(win,text="常规区")
#设置行 列 外边距x 外边距y
monty_left.grid(row=1,column=0,padx=5,pady=5,sticky=tk.W)
##################################顶部容器##################################
#标签
bLog = tk.StringVar()
ttk.Label(monty_top,text="欢迎使用XXXX工具",font=("华文行楷",20),width=40,textvariable=bLog).grid(row=0,column=0,sticky=tk.W)
bLog.set("欢迎使用XXXX工具")
##################################左边容器##################################
#判断配置文件是否存在,否正初始化
if os.path.isfile("conf.ini") == False:
initConfigFile()
#读取配置文件
chromePath,chromeNumber = rConfigFile()
#按钮
action = ttk.Button(monty_left,text="Chrome浏览器:",command=selectFile)
action.grid(row=0,column=0,sticky=tk.W)
#输入框
path = tk.StringVar()
pathEntered = ttk.Entry(monty_left,width=48,textvariable=path)
pathEntered.grid(row=0,column=1,sticky=tk.W)
#程序启动自动聚焦到这里
pathEntered.focus()
path.set(chromePath)
#标签
ttk.Label(monty_left,text="数量:").grid(row=0,column=2,sticky=tk.W)
#下拉框
age = tk.StringVar()
ageChosen = ttk.Combobox(monty_left,width=6,textvariable=age,state="readonly")
#设置下拉框内的值
ageChosen["values"] = (0,1,2,3,4)
ageChosen.grid(row=0,column=3)
#下拉框默认的值 此处为下标参数
ageChosen.current(chromeNumber)
#显示配置
monty_config = ttk.LabelFrame(monty_left)
#设置行 列 外边距x 外边距y
monty_config.grid(row=1,column=0,padx=20,pady=2,columnspan=4,sticky=tk.W)
#标签
macText = tk.StringVar()
ipText = tk.StringVar()
pcNameText = tk.StringVar()
identityText = tk.StringVar()
serverDateText = tk.StringVar()
runDateText = tk.StringVar()
ttk.Label(monty_config,text="MAC地址:获取中...",textvariable=macText).grid(row=0,column=0,padx=10,sticky=tk.W)
ttk.Label(monty_config,text="本机IP:获取中...",textvariable=ipText).grid(row=0,column=1,padx=10,sticky=tk.W)
ttk.Label(monty_config,text="主机名:获取中...",textvariable=pcNameText).grid(row=0,column=2,padx=10,sticky=tk.W)
ttk.Label(monty_config,text="开机时间:获取中...",textvariable=runDateText).grid(row=1,column=0,padx=10,sticky=tk.W)
ttk.Label(monty_config,text="单位:获取中...",textvariable=identityText).grid(row=1,column=1,padx=10,sticky=tk.W)
ttk.Label(monty_config,text="服务器时间:获取中...",textvariable=serverDateText).grid(row=1,column=2,padx=10,sticky=tk.W)
#获取本机电脑名
pcname = socket.getfqdn(socket.gethostname())
#获取本机ip
mac,ipv4 = PrintNetIfAddr()
macText.set("MAC地址:"+mac)
ipText.set("本机IP:"+ipv4)
pcNameText.set("主机名:"+pcname)
runDateText.set("开机时间:"+time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(psutil.boot_time())))
identityText.set("单位:获取中..")
serverDateText.set("服务器时间:获取中...")
##################################右边容器##################################
#标签
action = ttk.Button(monty_right,text="保存配置",command=saveConfig)
action.grid(row=0,column=0,sticky=tk.W)
action1 = ttk.Button(monty_right,text="输入密码",command=inputPass)
action1.grid(row=1,column=0,sticky=tk.W)
action2 = ttk.Button(monty_right,text="检查更新",command=getHttpApi)
action2.grid(row=2,column=0,sticky=tk.W)
action3 = ttk.Button(monty_right,text="计划任务",command=schtasks)
action3.grid(row=3,column=0,sticky=tk.W)
action4 = ttk.Button(monty_right,text="打开首页",command=openHome)
action4.grid(row=4,column=0,sticky=tk.W)
#设置应用内的图标
with open('tmp.ico','wb') as tmp:
tmp.write(base64.b64decode(Icon().img))
win.iconbitmap('tmp.ico')
os.remove('tmp.ico')
#监听窗口将被关闭
win.protocol("WM_DELETE_WINDOW", on_closing)
#开启时钟循环
clockLoop()
win.mainloop() # 当调用mainloop()时,窗口才会显示出来
打包为exe文件
pyinstaller --clean --win-private-assemblies -F .\File.py
案例图
3 条评论
字里行间流露出真挚的情感,让人感同身受,共鸣不已。
正在学习Tk
学习一下