win32com.client模块 —— Python实现COM自动化控制与数据交互
文章目录
- 一、基本原理
- 二、注意事项
- 三、基础配置
- 四、项目实战
- 4.1、检测COM组件是否已注册
- 4.2、获取所有可用方法与属性(动态探索)
- 4.3、典型应用实例
- 🎯 (1)控制Word:批量写入并保存文档
- 📊(2)控制Excel:批量写入数据、保存图表
- 📧(3)控制Outlook:自动发送邮件
- 🔬(4)调用科研设备(如:蔡司扫描电镜 CZ.EMApiCtrl.1)
- 接口方法汇总表(如:CZ.EMApiCtrl.1)
- 📘 一、命令类(Execute):用于执行动作性指令,如启动扫描、自动对焦、保存图像、重置状态等。
- 📗 二、参数类(Set/Get):用于设置/读取成像参数,如倍率、聚焦、像散、扫描窗口、探测器选择等。
- 📙 三、图像采集类(Grab)
- 📒 四、状态与控制类
- 🧪 五、实战模板
一、基本原理
win32com.client模块
:是Windows平台Python中实现COM(Component Object Model)自动化的核心模块。通过该模块,Python程序能够直接访问并操控支持COM接口的硬件设备和软件系统,实现自动化控制与高效数据交互,从而显著提升操作效率与准确性。
核心功能
自动化设备控制
:通过COM接口调用设备功能,实现设备启动、参数配置、状态监测、任务调度等自动化操作。数据交互
:读取设备状态和采集数据,或向软件系统传递指令与参数,完成双向通信和实时控制。兼容性强
:支持微软Office系列、工业设备、实验仪器、第三方软件等多种COM组件,适用范围广泛。
应用方向 | 常见目标对象 | 示例用途 |
---|---|---|
Office自动化 | Word、Excel、PowerPoint、Outlook | 报告生成、批量写表、邮件发送 |
系统调用 | WMI、文件系统对象(Scripting.FileSystemObject) | 自动化管理、任务调度 |
科研仪器控制 | CZ.EMApiCtrl.1 、Leica.Microscope 等 | 自动采图、参数调节、批量图像获取 |
视频音频处理 | Windows Media Player | 嵌入播放、远程控制播放 |
工业控制 | OPC服务器、PLC组件 | 自动化生产、设备信息读取 |
二、注意事项
Windows专用
:win32com.client只在Windows平台可用,不支持Linux或macOS。接口名区分大小写
:比如:“Word.Application”、“Excel.Application” 必须严格一致。COM接口必须注册
:使用的程序或设备必须在系统中注册了对应的COM接口,否则Dispatch会失败。
# 使用 win32com.client 通过 COM 接口保存文件到指定路径时,
# 若目标路径已存在同名文件(如 demo.xlsx),Excel 默认会弹出覆盖确认窗口。
# 在自动化场景中,该弹窗将阻塞 Python 脚本执行,直至用户手动响应,严重影响流程稳定性。
# 具体表现包括:
# - 程序在 SaveAs 调用处暂停执行;
# - 弹窗可能在后台隐藏,用户难以察觉;
# - 若 Excel 处于隐藏模式(Visible=False),弹窗不可见,程序表面“无响应”。
# 鉴于 win32com 无法自动响应此类弹窗,建议在保存前主动检测并删除同名文件,以确保流程顺畅。
三、基础配置
# 安装: pip install pywin32
# 检查是否成功安装: import win32com.client
四、项目实战
4.1、检测COM组件是否已注册
import winregdef is_com_registered(prog_id):try:# 使用Python内置的winreg模块访问注册表,判断对应键是否存在。key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, prog_id)winreg.CloseKey(key)return Trueexcept FileNotFoundError:return Falseimport win32com.client
from pythoncom import com_error
def is_com_registered(prog_id):try:# 使用win32com.client.Dispatch尝试实例化COM对象,捕获异常判断是否注册。win32com.client.Dispatch(prog_id)return Trueexcept com_error:return Falseif __name__ == '__main__':prog_id = 'Word.Application' # 应用程序的ProgIDif is_com_registered(prog_id):print(f'COM组件"{prog_id}"已注册')else:print(f'COM组件"{prog_id}"未注册')
4.2、获取所有可用方法与属性(动态探索)
import win32com.clientword = win32com.client.Dispatch("Word.Application")
print("获取对象属性:", dir(word)) # 列出所有属性和方法# 打印对象所有属性
for i in dir(word):print(i)
4.3、典型应用实例
🎯 (1)控制Word:批量写入并保存文档
from win32com import clientword = client.Dispatch("Word.Application")
word.Visible = True # 显示word
doc = word.Documents.Add()
doc.Content.Text = "Hello, COM!"
doc.SaveAs("d:\\py\\demo.docx")
doc.Close()
word.Quit()
📊(2)控制Excel:批量写入数据、保存图表
import os
from win32com import clientexcel = client.Dispatch("Excel.Application") # 创建Excel对象
excel.Visible = True # 显示Excel
# excel.Visible = False # 后台执行,提升效率
###############################################################
wb = excel.Workbooks.Add() # 创建工作簿
sheet = wb.Sheets(1) # 获取工作表# 写入数据
sheet.Cells(1, 1).Value = "Hello, COM!"
for i in range(1, 6):sheet.Cells(i, 1).Value = f"数据{i}"sheet.Cells(i, 2).Value = i * 10
###############################################################
save_path = "d:\\py\\demo.xlsx" # 保存路径
if os.path.exists(save_path): # 若文件已存在,则删除os.remove(save_path)
wb.SaveAs(save_path) # 保存文件
###############################################################
wb.Close(SaveChanges=False) # 清理资源
excel.Quit() # 退出Excel
📧(3)控制Outlook:自动发送邮件
from win32com import clientoutlook = client.Dispatch("Outlook.Application")
mail = outlook.CreateItem(0)
mail.To = "receiver@example.com"
mail.Subject = "自动发送测试"
mail.Body = "这是一封由Python发送的测试邮件"
mail.Send()
🔬(4)调用科研设备(如:蔡司扫描电镜 CZ.EMApiCtrl.1)
如果设备厂商注册了COM组件,厂商提供API文档(包含方法、属性名等)。如"CZ.EMApiCtrl.1"(蔡司扫描电镜),可直接控制:
from win32com import client# 创建 COM 对象
mic = client.Dispatch('CZ.EMApiCtrl.1')# 初始化设备
mic.Initialise("MachineName")# 移动样品台到指定位置
mic.MoveStageDoubles(10.0, 20.0, 5.0, 0.0, 0.0, 0.0)# 设置图像采集参数
mic.Set("AP_MAG", 5000.0)
mic.Set("AP_FOCUS_FINE", 1.5)# 采集图像并保存
mic.Grab(0, 0, 1024, 768, 0, r"C:\Images\sample_image.png")
接口方法汇总表(如:CZ.EMApiCtrl.1)
方法签名 | 参数说明 | 返回值 | 示例用法 | 说明 |
---|---|---|---|---|
Initialise(machine_name) | machine_name : 字符串,设备标识名 | 无 | mic.Initialise("EM-1") | 初始化设备连接 |
InitialiseRemoting() | 无 | 无 | mic.InitialiseRemoting() | 启用远程控制通道 |
StartEMServer() | 无 | 无 | mic.StartEMServer() | 启动EM服务 |
ClosingControl() | 无 | 无 | mic.ClosingControl() | 关闭控制连接 |
AboutBox() | 无 | 无 | mic.AboutBox() | 弹出接口信息窗口 |
Set(param_name, value) | param_name : 参数名value : 控制值 | 无 | mic.Set("AP_FOCUS_FINE", 2.5) | 设置参数值 |
Get(param_name, default_value) | param_name : 参数名default_value : 默认值 | (状态, 值) | mic.Get("AP_FOCUS_FINE", 0.0)[1] | 获取参数值 |
SetMulti(param_name, values) | values : 元组 | 无 | mic.SetMulti("SCAN_SIZE", (512, 384)) | 设置多值参数 |
GetMulti(param_name) | param_name : 多值参数名 | 元组 | mic.GetMulti("SCAN_SIZE") | 获取多值参数 |
GetLimits(param_name) | param_name : 参数名 | (最小值, 最大值) | mic.GetLimits("AP_FOCUS_FINE") | 获取参数取值范围 |
SetNotify(param_name, flag) | flag : 是否启用变更通知 | 无 | mic.SetNotify("AP_STIGMA", True) | 设置监听标志 |
Grab(x0, y0, w, h, reduce, filename) | 图像ROI及文件路径参数 | 无 | mic.Grab(0, 0, 512, 384, 0, "C:\\img\\scan.png") | 图像采集 |
Execute(command) | command : 字符串命令 | 无 | mic.Execute("CMD_AUTOFOCUS") | 执行控制命令 |
GetStagePosition() | 无 | (x, y, z, t, r, m) | mic.GetStagePosition() | 获取样品台位置 |
MoveStage(x, y, z, t, r, m) | 单精度坐标值 | 无 | mic.MoveStage(0.1, 0.2, 0, 0, 0, 0) | 移动样品台 |
MoveStageDoubles(x, y, z, t, r, m) | 双精度坐标值 | 无 | mic.MoveStageDoubles(0.1, 0.2, 0, 0, 0, 0) | 精准移动 |
LogonToEMServer(username, password) | 用户登录名与密码 | 无 | mic.LogonToEMServer("admin", "1234") | 登录控制系统 |
GetCurrentUserName() | 无 | 字符串 | user = mic.GetCurrentUserName() | 当前用户名称 |
GetUserIsIdle() | 无 | 布尔值 | mic.GetUserIsIdle() | 判断是否空闲 |
GetLastError() | 无 | 字符串 | mic.GetLastError() | 获取最后错误 |
GetLastRemotingConnectionError() | 无 | 字符串 | mic.GetLastRemotingConnectionError() | 获取远程错误 |
SetSuppressRemotingConnectionErrors() | 无 | 无 | mic.SetSuppressRemotingConnectionErrors() | 屏蔽错误弹窗 |
GetVersion() | 无 | 字符串 | mic.GetVersion() | 获取接口版本 |
📘 一、命令类(Execute):用于执行动作性指令,如启动扫描、自动对焦、保存图像、重置状态等。
方法 | 含义 | 示例 |
---|---|---|
Execute("CMD_SCANRATE1") | 设置扫描速率(速率编号1~4) | mic.Execute("CMD_SCANRATE3") |
Execute("CMD_AUTO_CONTRAST") | 自动对比度调整 | mic.Execute("CMD_AUTO_CONTRAST") |
Execute("CMD_FOCUS_FINE") | 精细自动对焦 | mic.Execute("CMD_FOCUS_FINE") |
Execute("CMD_FOCUS_COARSE") | 粗略对焦 | mic.Execute("CMD_FOCUS_COARSE") |
Execute("CMD_STIG") | 启动像散校正 | mic.Execute("CMD_STIG") |
Execute("CMD_SAVE_IMAGE") | 保存当前图像(内部路径) | mic.Execute("CMD_SAVE_IMAGE") |
Execute("CMD_ABORT") | 中止当前命令/动作 | mic.Execute("CMD_ABORT") |
Execute("CMD_SE_MODE") | 设置二次电子工作模式 | mic.Execute("CMD_SE_MODE") |
Execute("CMD_BE_MODE") | 设置背散射电子模式 | mic.Execute("CMD_BE_MODE") |
📗 二、参数类(Set/Get):用于设置/读取成像参数,如倍率、聚焦、像散、扫描窗口、探测器选择等。
常见Set方法
参数名 | 含义 | 示例 |
---|---|---|
AP_MAG | 设置倍率 | mic.Set("AP_MAG", 10000.0) |
AP_FOCUS_FINE | 精细调焦 | mic.Set("AP_FOCUS_FINE", 1.5) |
AP_STIG_X / Y | 像散校正X/Y | mic.Set("AP_STIG_X", 0.05) |
AP_RED_RASTER_POSN_X / Y | 设置扫描起点坐标 | mic.Set("AP_RED_RASTER_POSN_X", 256.0) |
AP_RED_RASTER_WIDTH / HEIGHT | 扫描窗口宽/高 | mic.Set("AP_RED_RASTER_WIDTH", 512.0) |
AP_BRIGHTNESS | 设置亮度 | mic.Set("AP_BRIGHTNESS", 0.7) |
AP_CONTRAST | 设置对比度 | mic.Set("AP_CONTRAST", 0.6) |
AP_DETECTOR | 选择探测器编号 | mic.Set("AP_DETECTOR", 1.0) |
AP_SCANRATE | 设置扫描速率(1~4) | mic.Set("AP_SCANRATE", 3) |
常见Get方法
mag = mic.Get("AP_MAG", 0.0)[1]
focus = mic.Get("AP_FOCUS_FINE", 0.0)[1]
stigx = mic.Get("AP_STIG_X", 0.0)[1]
width = mic.Get("AP_RED_RASTER_WIDTH", 0.0)[1]
📙 三、图像采集类(Grab)
方法 | 含义 | 示例 |
---|---|---|
Grab(x1, y1, x2, y2, flag, path) | 在指定矩形区域抓图保存 | mic.Grab(256, 192, 512, 384, 0, "img.png") |
参数说明 | x1/y1 为起点,x2/y2 为终点坐标,flag 一般为0 |
注意:抓图前请务必确认已设置成像区域。
📒 四、状态与控制类
方法 | 说明 | 示例 |
---|---|---|
Abort() | 中止当前命令(等效于CMD_ABORT) | mic.Abort() |
GetStatus() | 获取当前设备状态(部分实现) | status = mic.Get("AP_STATUS", 0.0)[1] |
IsBusy() | 检查设备是否处于执行状态(非标准) | is_busy = mic.Get("AP_IS_BUSY", 0.0)[1] |
🧪 五、实战模板
以下三个示例是独立的,仅用于理解参数的使用。
# 1. 执行一次自动对焦+图像采集:
mic.Execute("CMD_FOCUS_FINE")
time.sleep(2.0)
img_path = r"C:\Temp\sem_1.png"
mic.Grab(256, 192, 512, 384, 0, img_path)# 2. 设置扫描窗口+多倍率采图:
mic.Set("AP_RED_RASTER_POSN_X", 256.0)
mic.Set("AP_RED_RASTER_POSN_Y", 192.0)
mic.Set("AP_RED_RASTER_WIDTH", 512.0)
mic.Set("AP_RED_RASTER_HEIGHT", 384.0)for mag in [500, 1000, 5000, 10000]:mic.Set("AP_MAG", mag)time.sleep(1.0)mic.Grab(256, 192, 512, 384, 0, f"C:/Temp/mag_{mag}.png")# 3. 获取图像参数并写入日志文件:
params = ["AP_MAG", "AP_FOCUS_FINE", "AP_STIG_X", "AP_STIG_Y"]
with open("log.txt", "w") as f:for p in params:val = mic.Get(p, 0.0)[1]f.write(f"{p}: {val}\n")