如何解决使用comtypes.client.CreateObject后释放安装程序对象
我使用comtypes.client
模块在python中编写了一个函数,该函数应该从.msi文件打开数据库并编写一个特殊的(键,值)对。到目前为止,我的问题是调用该函数没有问题后,我尝试使用os.rename()
之后重命名.msi文件并获得权限错误:
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process
我了解到我的COM对象仍在使用中,因此我无法访问该文件。函数和函数调用看起来像这样(显然,这是非常简化的,但应该看起来像这样):
import comtypes.client
import os,shutil
def setInstallerAttribute(installer_path,attribute_key,attribute_value):
installerCOM = comtypes.client.CreateObject("WindowsInstaller.Installer")
installerDatabase = installerCOM.OpenDatabase (installer_path,1)
view = installerDatabase.OpenView ("INSERT INTO Property (Property,Value) VALUES ('{0}','{1}')".format(attribute_key,attribute_value))
view.Execute
installerDatabase.Commit
view = None
installerDatabase = None
installerCOM = None
if __name__ == "__main__":
input = '{}'.format(msi_fullapth)
key = "Build"
value = "test_value"
if os.path.exists(input):
setInstallerAttribute(input,key,value)
os.rename(input,{some other path})
之所以编写该函数,是因为以前我使用VBScript来设置此(键,值)对:
Option Explicit
Dim installer,database,view,myproperty,stdout,key
Set installer = CreateObject("WindowsInstaller.Installer")
Set database = installer.OpenDatabase (WScript.Arguments.Item(0),1)
' Update Property'
'Set view = database.OpenView ("UPDATE Property SET Value = '" & myproperty & "' WHERE Property = 'MYPROPERTY'")'
myproperty = WScript.Arguments.Item(2)
key = WScript.Arguments.Item(1)
' Add/Insert Property'
Set view = database.OpenView ("INSERT INTO Property (Property,Value) VALUES ('" & key & "','" & myproperty & "')")
view.Execute
database.Commit
Set database = nothing
Set installer = nothing
Set view = nothing
我会在os.system(cscript {VBScript} {path} {Key} {Value})
的python代码中调用它,但是我希望python代码尽可能减少外部依赖。我一直在寻找一些答案,我查看了comtypes
文档,以查看是否可以显式释放或“解除耦合”我的COM对象。我尝试使用installerCOM.Quit()
和installerCOM.Exit()
,它们似乎不是WindowsInstaller.Installer
对象的选项。
最后,我在StackOverflow上读了一些先前的非python(主要是C#)答案,指出将COM对象变量设置为null
可以解决此问题,这在VBScript中也很明显,但这似乎并没有使用None
解决方法
也许:
import gc
def setInstallerAttribute(installer_path,attribute_key,attribute_value):
installerCOM = comtypes.client.CreateObject("WindowsInstaller.Installer")
installerDatabase = installerCOM.OpenDatabase (installer_path,1)
view = installerDatabase.OpenView ("INSERT INTO Property (Property,Value) VALUES ('{0}','{1}')".format(attribute_key,attribute_value))
view.Execute
installerDatabase.Commit
del view
del installerDatabase
del installerCOM
gc.collect()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。