微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用comtypes.client.CreateObject后释放安装程序对象

如何解决使用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

在python中工作

解决方法

也许:

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 举报,一经查实,本站将立刻删除。