一个程序要用到某个文件,经常会出现文件被占用,而无法继续运行,所以需要探知文件是否被占用,及如何进行关闭。
搜集一些句柄的用法,同时也向大佬请教,脚本如下:

import win32api
import win32gui
import win32con
import win32process
import time
 
filename = '2020年公司经营对比表.xlsx'   #文件名
 
def close_process_by_hwnd(hwnd, _):
    if win32gui.IsWindowVisible(hwnd):
        # 可以正则判断
        if filename in win32gui.GetWindowText(hwnd):
            # PostMessage 会弹出关闭提示, 比如文件已经修改的情况  方法一
            win32gui.SetForegroundWindow(hwnd)  #使当前窗口在最前
            win32gui.PostMessage(hwnd, win32con.WM_CLOSE, 0, 0)
 
            # # 根据窗口句柄获取 进程ID 下面的 方法二
            # _id = win32process.GetWindowThreadProcessId(hwnd)
 
            # # 根据ID打开进程
            # handle = win32api.OpenProcess(1, False, _id[1])
            # # 根据进程句柄关闭进程
            # win32api.TerminateProcess(handle, -1)
 
 
if __name__ == '__main__':
    win32gui.EnumWindows(close_process_by_hwnd, None)
    time.sleep(5)

以下是关闭自己打开的文件,及遍历打开文件窗口的测试

import time
import win32process
handle = win32process.CreateProcess('C:\\Windows\\notepad.exe', '', None, None, 0, win32process 
.CREATE_NO_WINDOW, None, None, win32process.STARTUPINFO())            # 打开记事本,获得其句柄
print(handle,handle[0])
time.sleep(0.5)
win32process.TerminateProcess(handle[0], 0) 
 
 
import win32gui
hwnd_title = dict()
def get_all_hwnd(hwnd,mouse):
    if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
        hwnd_title.update({hwnd:win32gui.GetWindowText(hwnd)})
win32gui.EnumWindows(get_all_hwnd, 0)
  
for h,t in hwnd_title.items():
    if t != "":
        print(h,t)
通过窗口标题获取句柄
import win32gui
 
hld = win32gui.FindWindow(None,u"Adobe Acrobat") #返回窗口标题为Adobe Acrobat的句柄
  

通过父窗口句柄获取子句柄
#parent为父窗口句柄id
def get_child_windows(parent):
    '''
    获得parent的所有子窗口句柄
     返回子窗口句柄列表
     '''
    if not parent:
        return
    hwndChildList = []
    win32gui.EnumChildWindows(parent, lambda hwnd, param: param.append(hwnd),  hwndChildList)
    return hwndChildList
  

根据句柄获取句柄标题和类名
import win32gui
 
title = win32gui.GetWindowText(jbid)   #jbid为句柄id
#获取标题
clsname = win32gui.GetClassName(jbid)  
#获取类名
  

根据句柄获取窗口位置
import win32gui
left, top, right, bottom = win32gui.GetWindowRect(jbid)
#分别为左、上、右、下的窗口位置
  

根据句柄进行点击操作
import win32api,win32con
 
win32api.SetCursorPos([横坐标, 纵坐标])
#根据横纵坐标定位光标
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP | win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
#给光标定位的位置进行单击操作(若想进行双击操作,可以延时几毫秒再点击一次)
win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP | win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
#给光标定位的位置进行右击操作
  

根据句柄将窗口放在最前

win32gui.SetForegroundWindow(jbid)