Мне не терпится использовать API Solidworks PDM для автоматизации некоторых файловых задач. Первым делом я запустил makepy.py в библиотеке PDMWorks Enterprise, как указано здесь . Это создало файл python с кучей определений классов, которые я затем переименовал в "pdm_lib.py". API определяет группу «интерфейсов» и «членов», которые в python, по-видимому, переводятся в «классы» и «методы». Например, вот как выглядит определение класса IEdmVault5:
class IEdmVault5(DispatchBaseClass):
'IEdmVault5 Interface'
CLSID = IID('{11AD8C69-12EA-4C9D-B20B-8C6D43B735AC}')
coclass_clsid = IID('{AE784C6C-0155-11D3-B24B-0000F879F93B}')
# Result is of type IEdmStrLst5
def BrowseForFile(self, hParentWnd=defaultNamedNotOptArg, lEdmBrowseFlags=8, bsFilter='', bsDefaultExtension=''
, bsDefaultFileName='', bsDefaultFolder='', bsCaption=''):
'method BrowseForFile'
return self._ApplyTypes_(22, 1, (9, 32), ((3, 1), (3, 49), (8, 49), (8, 49), (8, 49), (8, 49), (8, 49)), 'BrowseForFile', '{AAFEA179-C9AE-4032-81C4-2AFCAA67B81A}',hParentWnd
, lEdmBrowseFlags, bsFilter, bsDefaultExtension, bsDefaultFileName, bsDefaultFolder
, bsCaption)
# Result is of type IEdmFolder5
def BrowseForFolder(self, hParentWnd=defaultNamedNotOptArg, bsMessage=defaultNamedNotOptArg):
'method BrowseForFolder'
ret = self._oleobj_.InvokeTypes(15, LCID, 1, (9, 0), ((3, 1), (8, 1)),hParentWnd
, bsMessage)
if ret is not None:
ret = Dispatch(ret, 'BrowseForFolder', '{050E7719-E0B4-4824-824F-6055B41B52FD}')
return ret
# Result is of type IEdmMenu5
def CreatePluginMenu(self, hMenu=defaultNamedNotOptArg, lInsertPosition=defaultNamedNotOptArg, plStartID=defaultNamedNotOptArg, lSelFileCount=defaultNamedNotOptArg
, lSelFolderCount=defaultNamedNotOptArg, lCreateMenuFlags=defaultNamedNotOptArg, plItemCount=pythoncom.Missing):
'method CreatePluginMenu'
return self._ApplyTypes_(14, 1, (9, 0), ((3, 1), (3, 1), (16387, 3), (3, 1), (3, 1), (3, 1), (16387, 2)), 'CreatePluginMenu', '{65C885D1-C105-45D7-89D2-86B59F5DDCBC}',hMenu
, lInsertPosition, plStartID, lSelFileCount, lSelFolderCount, lCreateMenuFlags
, plItemCount)
# Result is of type IEdmSearch5
def CreateSearch(self):
'method CreateSearch'
ret = self._oleobj_.InvokeTypes(20, LCID, 1, (9, 0), (),)
if ret is not None:
ret = Dispatch(ret, 'CreateSearch', '{DF0EDC59-1AD6-401A-B332-70C10318E263}')
return ret
# Result is of type IEdmDictionary5
def GetDictionary(self, bsName=defaultNamedNotOptArg, bCreateIfNew=defaultNamedNotOptArg):
'method GetDictionary'
ret = self._oleobj_.InvokeTypes(13, LCID, 1, (9, 0), ((8, 1), (11, 1)),bsName
, bCreateIfNew)
if ret is not None:
ret = Dispatch(ret, 'GetDictionary', '{656C1CE8-E21B-4FDB-A493-484ABBBA5197}')
return ret
def GetErrorString(self, lError=defaultNamedNotOptArg, pbsErrorName='0', pbsDescription='0'):
'method GetErrorString'
return self._ApplyTypes_(5, 1, (24, 32), ((3, 1), (16392, 50), (16392, 50)), 'GetErrorString', None,lError
, pbsErrorName, pbsDescription)
# Result is of type IEdmFile5
def GetFileFromPath(self, bsFilePath=defaultNamedNotOptArg, ppoRetParentFolder=0):
'method GetFileFromPath'
return self._ApplyTypes_(16, 1, (9, 0), ((8, 1), (16393, 50)), 'GetFileFromPath', '{BDFB0459-491E-4E29-9E86-A726B508766F}',bsFilePath
, ppoRetParentFolder)
# Result is of type IEdmFolder5
def GetFolderFromPath(self, bsFolderPath=defaultNamedNotOptArg):
'method GetFolderFromPath'
ret = self._oleobj_.InvokeTypes(17, LCID, 1, (9, 0), ((8, 1),),bsFolderPath
)
if ret is not None:
ret = Dispatch(ret, 'GetFolderFromPath', '{050E7719-E0B4-4824-824F-6055B41B52FD}')
return ret
# Result is of type IEdmObject5
def GetObject(self, eType=defaultNamedNotOptArg, lObjectID=defaultNamedNotOptArg):
'method GetObject'
ret = self._oleobj_.InvokeTypes(12, LCID, 1, (9, 0), ((3, 1), (3, 1)),eType
, lObjectID)
if ret is not None:
ret = Dispatch(ret, 'GetObject', '{2EE10E23-4B8A-4BC2-9043-E40FB5603169}')
return ret
def GetVaultNameFromPath(self, bsPath=defaultNamedNotOptArg):
'method GetVaultNameFromPath'
# Result is a Unicode object
return self._oleobj_.InvokeTypes(4, LCID, 1, (8, 0), ((8, 1),),bsPath
)
def GetVersion(self, plMajor=defaultNamedNotOptArg, plMinor=defaultNamedNotOptArg):
'method GetVersion'
return self._ApplyTypes_(10, 1, (24, 0), ((16387, 3), (16387, 3)), 'GetVersion', None,plMajor
, plMinor)
def Login(self, bsUserName=defaultNamedNotOptArg, bsPasswd=defaultNamedNotOptArg, bsVaultName=defaultNamedNotOptArg):
'method Login'
return self._oleobj_.InvokeTypes(1, LCID, 1, (24, 0), ((8, 1), (8, 1), (8, 1)),bsUserName
, bsPasswd, bsVaultName)
def LoginAuto(self, bsVaultName=defaultNamedNotOptArg, hParentWnd=defaultNamedNotOptArg):
'method LoginAuto'
return self._oleobj_.InvokeTypes(2, LCID, 1, (24, 0), ((8, 1), (3, 1)),bsVaultName
, hParentWnd)
def MsgBox(self, lParentWnd=defaultNamedNotOptArg, bsMsg=defaultNamedNotOptArg, eType=0, bsCaption=''):
'method MsgBox'
return self._ApplyTypes_(21, 1, (3, 32), ((3, 1), (8, 1), (3, 49), (8, 49)), 'MsgBox', None,lParentWnd
, bsMsg, eType, bsCaption)
def RefreshFolder(self, bsFolderPath=defaultNamedNotOptArg):
'method RefreshFolder'
return self._oleobj_.InvokeTypes(23, LCID, 1, (24, 0), ((8, 1),),bsFolderPath
)
def SetAddInWnd(self, lAddInWnd=defaultNamedNotOptArg, lParentWnd=defaultNamedNotOptArg):
'method SetAddinWnd'
return self._oleobj_.InvokeTypes(25, LCID, 1, (24, 0), ((3, 1), (3, 1)),lAddInWnd
, lParentWnd)
def VerifyVersion(self, lMajor=defaultNamedNotOptArg, lMinor=defaultNamedNotOptArg):
'method VerifyVersion'
return self._oleobj_.InvokeTypes(11, LCID, 1, (24, 0), ((3, 1), (3, 1)),lMajor
, lMinor)
_prop_map_get_ = {
"CommandID": (8, 2, (3, 0), (), "CommandID", None),
"IsLoggedIn": (3, 2, (11, 0), (), "IsLoggedIn", None),
"Language": (9, 2, (3, 0), (), "Language", None),
"Name": (6, 2, (8, 0), (), "Name", None),
# Method 'RootFolder' returns object of type 'IEdmFolder5'
"RootFolder": (7, 2, (9, 0), (), "RootFolder", '{050E7719-E0B4-4824-824F-6055B41B52FD}'),
"RootFolderID": (18, 2, (3, 0), (), "RootFolderID", None),
"RootFolderPath": (24, 2, (8, 0), (), "RootFolderPath", None),
"SilentMode": (19, 2, (11, 0), (), "SilentMode", None),
}
_prop_map_put_ = {
}
def __iter__(self):
"Return a Python iterator for this object"
try:
ob = self._oleobj_.InvokeTypes(-4,LCID,3,(13, 10),())
except pythoncom.error:
raise TypeError("This object does not support enumeration")
return win32com.client.util.Iterator(ob, None)
Вот простой фрагмент кода, который я написал, который подключается к хранилищу файлов и извлекает файл:
from pdm_lib import *
folder_path = 'C:\\Logos_Production\\vendors\\mcmaster-carr\\test\\'
file_path = 'C:\\Logos_Production\\vendors\\mcmaster-carr\\test\\1019A12.SLDPRT'
username = 'username'
pw = 'pw'
vault_name = 'vault_name'
vault = EdmVault5()
vault.Login(username, pw, vault_name)
folder = vault.GetFolderFromPath(folder_path)
file = vault.GetFileFromPath(file_path, folder)[0]
file.LockFile(folder.ID, file.CurrentVersion)
Проблема, с которой я сталкиваюсь, заключается в том, что, когда я пытаюсь использовать интерфейс IEdmBatchUnlock. В соответствии с документацией API для него должны быть доступны следующие "члены" (методы):
- AddSelection
- CreateFileTree
- GetFilelist
- ShowDlg
- UnlockFiles
Вот моя попытка создать IEdmBatchUnlock и вызвать метод "AddSelection":
from pdm_lib import *
username = 'username'
pw = 'pw'
vault_name = 'vault'
vault = EdmVault5()
vault.Login(username, pw, vault_name)
unlocker = logos_prod.CreateUtility(6)
unlocker.AddSelection(vault, selected_items)
У меня есть также пытался сделать то же самое с использованием позднего связывания:
from win32com.client import Dispatch
username = 'username'
pw = 'pw'
vault_name = 'vault'
vault = win32com.client.Dispatch('ConisioLib.EdmVault.1')
vault.Login(username, pw, vault_name)
unlocker = logos_prod.CreateUtility(6)
unlocker.AddSelection(vault, selected_items)
Оба набора кода, по-видимому, успешно создают объект "IEdmBatchUnlock", но в обоих случаях я получаю один и тот же "объект не имеет атрибута" AddSelection " ошибка при попытке запустить метод AddSelection. Когда я смотрю на определение класса в pdm_lib.py, это все, что я вижу:
class IEdmBatchUnlock(DispatchBaseClass):
'IEdmBatchUnlock Interface'
CLSID = IID('{748E6759-E16D-4F69-A0BC-98A9A9F2E650}')
coclass_clsid = None
_prop_map_get_ = {
"Comment": (5, 2, (3, 0), ((16392, 10),), "Comment", None),
}
_prop_map_put_ = {
"Comment": ((5, LCID, 4, 0),()),
}
def __iter__(self):
"Return a Python iterator for this object"
try:
ob = self._oleobj_.InvokeTypes(-4,LCID,3,(13, 10),())
except pythoncom.error:
raise TypeError("This object does not support enumeration")
return win32com.client.util.Iterator(ob, None)
Я не вижу здесь ссылки ни на один из вышеупомянутых методов или где-либо еще в pdm_lib.py, поэтому я не удивлен, что когда я вызываю метод AddSelection для объекта IEdmBatchUnlock, python выдает ошибку. Любые предложения о том, как я могу заставить это работать в Python?
* РЕДАКТИРОВАТЬ: обновил мой пост для ясности