首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用comtypes.client.CreateObject()后释放安装程序对象

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

Stack Overflow用户
提问于 2020-11-06 22:32:35
回答 1查看 74关注 0票数 1

我使用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对象仍然在使用中,所以我不能访问文件,函数和函数调用看起来像这样(显然这非常简单,但看起来应该是这样的):

代码语言:javascript
复制
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来设置这个(键,值)对:

代码语言:javascript
复制
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

我会在我的python代码中使用os.system(cscript {VBScript} {path} {Key} {Value})来调用它,但是我希望我的python代码尽可能减少外部依赖。我在四处寻找一些答案,我查看了comtypes文档,看看我是否可以显式释放或“解耦”我的COM对象。我尝试使用installerCOM.Quit()installerCOM.Exit(),它们似乎不是WindowsInstaller.Installer对象的选项。

最后,我在前面几篇关于StackOverflow的非python (主要是C#)的回答中看到,将COM对象变量设置为null可以解决这个问题,这在VBScript中也很清楚,但这似乎不适用于使用None的python

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-09 20:02:08

也许:

代码语言:javascript
复制
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()
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64716506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档