繁体   English   中英

Python 中的 Solidworks PDM API--获取 AttributeError 对象没有属性“QueryInterface”

[英]Solidworks PDM API in Python--getting AttributeError object has no attribute 'QueryInterface'

我已经编写了一堆 Python 代码,用于在 Solidworks PDM 中标记我们的供应商文件,并且我正在尝试使用 Solidworks PDM API 来实际应用该信息。 官方 API 仅支持 C# 和 VB,但如果可能的话,我想将所有内容都保留在 Python 中,因为其他所有内容都已经在 Python 中了(这是我最习惯使用的编程语言)。 这是我要完成的工作的高级列表:

  1. 查看一堆文件
  2. 更新数据卡变量
  3. 重新检入这些文件

API 定义了两种主要方式来检入/检出/更新单个文件中的变量——一种用于单个文件,另一种用于文件组。 您可以使用可通过 IEdmVault5 接口访问的方法对单个文件执行所有 3 项操作,而要对文件组执行这些操作,您必须使用 3 个单独的接口——IEdmBatchGet(检出)、IEdmBatchUpdate2(更新变量)和 IEdmBatchUnlock(报到)。

我能够编写为每个文件完成所有 3 件事的功能代码,但是在处理多个文件时速度很慢——我的目标是一次更新几千个文件。 事实证明,使批处理接口工作要困难得多,但我最终能够使批处理检出和检入工作(这绝对值得——使用 Vault 接口,每个操作的速度提高了大约 10 倍)。 但是,我在尝试使变量更新工作时遇到了困难。 这是我更新变量的代码:

import win32com.client
import os

import comtypes.client as cc
cc.GetModule('C:\Program Files (x86)\SOLIDWORKS PDM\EdmInterface.dll')
import comtypes.gen._5FA2C692_8393_4F31_9BDB_05E6F807D0D3_0_5_22 as pdm_lib2

vault_name = 'vault_name'
folder_path = 'some_folder_path'

def connect_to_vault(vault_name, lib = 'comtypes'):
    if lib == 'comtypes':
        vault = cc.CreateObject('ConisioLib.EdmVault.1')
        vault.LoginAuto(vault_name, 0)

    else: 
        vault = win32com.client.dynamic.Dispatch('ConisioLib.EdmVault.1')
        vault.LoginAuto(vault_name, 0)

    return vault

def getrefs(vault, filenames, folder_path):
    DocIDs = []
    ProjIDs = []

    for filename in filenames:
        temp_ProjID = vault.GetFolderFromPath(folder_path)
        temp_DocID = vault.GetFileFromPath(filename, temp_ProjID)[0] #this fails when I use a comtypes generated vault

        DocIDs.append(temp_DocID.ID)
        ProjIDs.append(temp_ProjID.ID)

    print('Document and Project IDs pulled')

    return DocIDs, ProjIDs

vault = connect_to_vault(vault_name)
ref_vault =connect_to_vault(vault_name, lib = 'win32com') 

filenames = [folder_path + s for s in os.listdir(folder_path)]
DocIDs, ProjIDs = getrefs(ref_vault, filenames, folder_path)

#Using Comtypes to update files
VarIDs = [54] * len(DocIDs) #Updating description only
var_values = [['foo' + str(s)] for s in range(len(DocIDs))] #dummy values for now

update_vars = vault.CreateUtility(2) #create instance of BatchUpdate 

for i, file in enumerate(DocIDs): 
    update_vars.SetVar(file, VarIDs[i], var_values[i], '', 1)

pdm_error = [pdm_lib2.EdmBatchError2()] * len(DocIDs)
update_vars.CommitUpdate([pdm_error])

当我调用 update_vars.CommitUpdate([pdm_error]) 时,出现以下错误:

ArgumentError: argument 2: <class 'AttributeError'>: 'list' object has no attribute 'QueryInterface'

我不确定为什么这个方法需要一个具有“QueryInterface”属性的对象——我只是向它传递一个结构列表,而不是像我的文件库那样的完整 COM 对象。 我也尝试使用 win32com 来执行该方法:

update_vars = ref_vault.CreateUtility(2) #create instance of BatchUpdate, use win32com instead

for i, file in enumerate(DocIDs): 
    update_vars.SetVar(file, VarIDs[i], var_values[i], '', 1)

pdm_error = [pdm_lib2.EdmBatchError2()] * len(DocIDs)
update_vars.CommitUpdate([pdm_error])

现在我收到这个错误:

Traceback (most recent call last):

  File "<ipython-input-222-0c49fb0861b9>", line 7, in <module>
    update_vars.CommitUpdate([pdm_error])

  File "D:\Users\apreacher\Documents\Shared Files\Python\Webscraping_projects\Helper Modules\pdm_lib.py", line 1500, in CommitUpdate
    , poCallback)

  File "C:\Users\apreacher\AppData\Local\Continuum\anaconda3\lib\site-packages\win32com\client\__init__.py", line 467, in _ApplyTypes_
    self._oleobj_.InvokeTypes(dispid, 0, wFlags, retType, argTypes, *args),

MemoryError: CreatingSafeArray

这就是我被困的地方。 我一直无法在让 CommitUpdate 方法正常工作方面取得任何进展。 我也有 makepy.py 和 comtypes 生成的文件中的方法定义,但我真的不知道如何解释它们:

makepy.py 方法定义:

def CommitUpdate(self, ppoRetErrors=pythoncom.Missing, poCallback=0):
    'method Commit'
    return self._ApplyTypes_(3, 1, (3, 0), ((24612, 2), (9, 49)), 'CommitUpdate', None,ppoRetErrors
        , poCallback)

comtypes 生成的文件:

COMMETHOD([dispid(3), helpstring('method Commit')], HRESULT, 'CommitUpdate',
          ( ['out'], POINTER(_midlSAFEARRAY(EdmBatchError2)), 'ppoRetErrors' ),
          ( ['in', 'optional'], POINTER(IEdmCallback), 'poCallback', 0 ),
          ( ['out', 'retval'], POINTER(c_int), 'plErrorCount' )),

有任何想法吗?

您使用的是哪个版本的 PDM? (我使用的是 Pro 2019 sp4。)

我只是注意到您的代码不一致。 vault.CreateUtility(2)将(在 .NET 中)返回类型为IEdmBatchUpdate的对象。 4 行之后,您将调用CommitUpdate方法,该方法仅适用于较新的 API IEdmBatchUpdate2 (请参阅https://help.solidworks.com/2020/english/api/epdmapi/EPDM.Interop.epdm~EPDM.Interop.epdm。 IEdmBatchUpdate2.html )。

我可以肯定地告诉您,在 C# 下,这需要将CreatUtility的结果CreatUtility为正确的对象类型。

您似乎正在寻找一种方法来自动将数据输入到文件数据卡中。 您是否尝试过使用数据导入规则? https://help.solidworks.com/2020/English/EnterprisePDM/Admin/c_Working_With_Variable_Values_overview.htm

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM