244 lines
7.1 KiB
Python
244 lines
7.1 KiB
Python
|
|
"""
|
|||
|
|
Word COM 诊断和修复工具
|
|||
|
|
用于诊断和解决Word COM组件实例化问题
|
|||
|
|
"""
|
|||
|
|
import sys
|
|||
|
|
import os
|
|||
|
|
import subprocess
|
|||
|
|
import winreg
|
|||
|
|
import pythoncom
|
|||
|
|
import win32com.client
|
|||
|
|
from pathlib import Path
|
|||
|
|
|
|||
|
|
def check_word_installation():
|
|||
|
|
"""检查Word是否已安装"""
|
|||
|
|
print("\n=== 检查Word安装 ===")
|
|||
|
|
try:
|
|||
|
|
# 检查注册表中的Word安装信息
|
|||
|
|
key_paths = [
|
|||
|
|
r"SOFTWARE\Microsoft\Office\16.0\Word\InstallRoot",
|
|||
|
|
r"SOFTWARE\Microsoft\Office\15.0\Word\InstallRoot",
|
|||
|
|
r"SOFTWARE\Microsoft\Office\14.0\Word\InstallRoot",
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
for key_path in key_paths:
|
|||
|
|
try:
|
|||
|
|
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path)
|
|||
|
|
path, _ = winreg.QueryValueEx(key, "Path")
|
|||
|
|
winreg.CloseKey(key)
|
|||
|
|
print(f"✓ 找到Word安装: {path}")
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
continue
|
|||
|
|
|
|||
|
|
print("✗ 未在注册表中找到Word安装信息")
|
|||
|
|
return False
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"✗ 检查失败: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def check_word_com_registration():
|
|||
|
|
"""检查Word COM组件注册"""
|
|||
|
|
print("\n=== 检查Word COM注册 ===")
|
|||
|
|
try:
|
|||
|
|
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, r"Word.Application")
|
|||
|
|
winreg.CloseKey(key)
|
|||
|
|
print("✓ Word.Application COM类已注册")
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
print("✗ Word.Application COM类未注册")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_word_creation_methods():
|
|||
|
|
"""测试不同的Word实例创建方法"""
|
|||
|
|
print("\n=== 测试Word实例创建方法 ===")
|
|||
|
|
|
|||
|
|
methods = [
|
|||
|
|
("pythoncom.CoInitialize + Dispatch", lambda: test_with_coinit_dispatch()),
|
|||
|
|
("pythoncom.CoInitializeEx(COINIT_APARTMENTTHREADED)", lambda: test_with_coinit_apartment()),
|
|||
|
|
("pythoncom.CoInitializeEx(COINIT_MULTITHREADED)", lambda: test_with_coinit_multi()),
|
|||
|
|
("DispatchEx (新实例)", lambda: test_dispatchex()),
|
|||
|
|
("EnsureDispatch (缓存)", lambda: test_ensure_dispatch()),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
success_methods = []
|
|||
|
|
|
|||
|
|
for method_name, test_func in methods:
|
|||
|
|
try:
|
|||
|
|
print(f"\n测试: {method_name}")
|
|||
|
|
result = test_func()
|
|||
|
|
if result:
|
|||
|
|
print(f" ✓ 成功")
|
|||
|
|
success_methods.append(method_name)
|
|||
|
|
else:
|
|||
|
|
print(f" ✗ 失败")
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f" ✗ 异常: {e}")
|
|||
|
|
|
|||
|
|
return success_methods
|
|||
|
|
|
|||
|
|
def test_with_coinit_dispatch():
|
|||
|
|
"""使用CoInitialize + Dispatch"""
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoInitialize()
|
|||
|
|
word = win32com.client.Dispatch("Word.Application")
|
|||
|
|
version = word.Version
|
|||
|
|
word.Quit()
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_with_coinit_apartment():
|
|||
|
|
"""使用CoInitializeEx APARTMENTTHREADED"""
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoInitializeEx(pythoncom.COINIT_APARTMENTTHREADED)
|
|||
|
|
word = win32com.client.Dispatch("Word.Application")
|
|||
|
|
version = word.Version
|
|||
|
|
word.Quit()
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_with_coinit_multi():
|
|||
|
|
"""使用CoInitializeEx MULTITHREADED"""
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoInitializeEx(pythoncom.COINIT_MULTITHREADED)
|
|||
|
|
word = win32com.client.Dispatch("Word.Application")
|
|||
|
|
version = word.Version
|
|||
|
|
word.Quit()
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_dispatchex():
|
|||
|
|
"""使用DispatchEx"""
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoInitialize()
|
|||
|
|
word = win32com.client.DispatchEx("Word.Application")
|
|||
|
|
version = word.Version
|
|||
|
|
word.Quit()
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def test_ensure_dispatch():
|
|||
|
|
"""使用EnsureDispatch"""
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoInitialize()
|
|||
|
|
word = win32com.client.gencache.EnsureDispatch("Word.Application")
|
|||
|
|
version = word.Version
|
|||
|
|
word.Quit()
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
return True
|
|||
|
|
except:
|
|||
|
|
try:
|
|||
|
|
pythoncom.CoUninitialize()
|
|||
|
|
except:
|
|||
|
|
pass
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
def check_dcom_permissions():
|
|||
|
|
"""检查DCOM权限配置"""
|
|||
|
|
print("\n=== 检查DCOM权限 ===")
|
|||
|
|
print("提示: 需要管理员权限才能修改DCOM设置")
|
|||
|
|
print("\n手动检查步骤:")
|
|||
|
|
print("1. Win+R 运行 'dcomcnfg'")
|
|||
|
|
print("2. 组件服务 -> 计算机 -> 我的电脑 -> DCOM配置")
|
|||
|
|
print("3. 找到 'Microsoft Word 97-2003 文档' 或 'Microsoft Word Document'")
|
|||
|
|
print("4. 右键 -> 属性 -> 安全")
|
|||
|
|
print("5. 确保当前用户有 '启动和激活' 权限")
|
|||
|
|
|
|||
|
|
def generate_fix_script():
|
|||
|
|
"""生成修复脚本"""
|
|||
|
|
print("\n=== 生成修复脚本 ===")
|
|||
|
|
|
|||
|
|
fix_script = """@echo off
|
|||
|
|
echo 修复Word COM权限问题
|
|||
|
|
echo 需要管理员权限运行此脚本
|
|||
|
|
echo.
|
|||
|
|
|
|||
|
|
REM 重新注册Word COM组件
|
|||
|
|
echo 正在重新注册Word...
|
|||
|
|
for %%i in (WINWORD.EXE) do set WORD_PATH=%%~$PATH:i
|
|||
|
|
if defined WORD_PATH (
|
|||
|
|
"%WORD_PATH%" /regserver
|
|||
|
|
echo Word COM组件已重新注册
|
|||
|
|
) else (
|
|||
|
|
echo 未找到Word可执行文件
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
echo.
|
|||
|
|
echo 修复完成,请重新运行程序
|
|||
|
|
pause
|
|||
|
|
"""
|
|||
|
|
|
|||
|
|
script_path = Path("fix_word_com.bat")
|
|||
|
|
script_path.write_text(fix_script, encoding='gbk')
|
|||
|
|
print(f"✓ 已生成修复脚本: {script_path.absolute()}")
|
|||
|
|
print(" 请右键以管理员身份运行此脚本")
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
print("=" * 60)
|
|||
|
|
print("Word COM 诊断工具")
|
|||
|
|
print("=" * 60)
|
|||
|
|
|
|||
|
|
# 1. 检查Word安装
|
|||
|
|
word_installed = check_word_installation()
|
|||
|
|
|
|||
|
|
# 2. 检查COM注册
|
|||
|
|
com_registered = check_word_com_registration()
|
|||
|
|
|
|||
|
|
# 3. 测试创建方法
|
|||
|
|
success_methods = test_word_creation_methods()
|
|||
|
|
|
|||
|
|
# 4. DCOM权限提示
|
|||
|
|
check_dcom_permissions()
|
|||
|
|
|
|||
|
|
# 5. 生成修复脚本
|
|||
|
|
if not success_methods:
|
|||
|
|
generate_fix_script()
|
|||
|
|
|
|||
|
|
# 总结
|
|||
|
|
print("\n" + "=" * 60)
|
|||
|
|
print("诊断总结")
|
|||
|
|
print("=" * 60)
|
|||
|
|
print(f"Word已安装: {'是' if word_installed else '否'}")
|
|||
|
|
print(f"COM已注册: {'是' if com_registered else '否'}")
|
|||
|
|
print(f"成功的创建方法: {len(success_methods)}")
|
|||
|
|
|
|||
|
|
if success_methods:
|
|||
|
|
print("\n✓ 找到可用的创建方法:")
|
|||
|
|
for method in success_methods:
|
|||
|
|
print(f" - {method}")
|
|||
|
|
print("\n建议: 在代码中使用上述成功的方法")
|
|||
|
|
else:
|
|||
|
|
print("\n✗ 所有创建方法都失败")
|
|||
|
|
print("\n建议的解决步骤:")
|
|||
|
|
print("1. 以管理员身份运行 fix_word_com.bat")
|
|||
|
|
print("2. 检查DCOM权限配置 (运行 dcomcnfg)")
|
|||
|
|
print("3. 确保Word没有被杀毒软件阻止")
|
|||
|
|
print("4. 尝试修复Office安装")
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|