我正在为Microsoft Dynamics Business Connector .net程序集编写一个python包装器。
这是我的代码:
"""Implements wrapper for axapta bussiness connector."""
import pathlib
from msl.loadlib import LoadLibrary
import clr
DLL_PATH = pathlib.Path(__file__).parent / 'Microsoft.Dynamics.BusinessConnectorNet.dll'
def test_msl_connector():
"""Get Axapta object via msl-loadlib package."""
connectorLL = LoadLibrary(DLL_PATH, 'net')
Axapta = getattr(connectorLL.lib,
'Microsoft.Dynamics.BusinessConnectorNet').Axapta
return Axapta
def test_pure_pythonnet_connector():
"""Get Axapta object via pythonnet package."""
clr.AddReference(str(DLL_PATH))
from Microsoft.Dynamics.BusinessConnectorNet import Axapta
return Axapta
运行pytest时出现错误:
============================= test session starts =============================
platform win32 -- Python 3.6.2, pytest-3.4.0, py-1.5.2, pluggy-0.6.0
rootdir: C:\Users\AZ\Desktop\test_bom-mcs, inifile:
collected 2 items
test_main.py FF [100%]
================================== FAILURES ===================================
_____________________________ test_msl_connector ______________________________
def test_msl_connector():
"""Get Axapta object via msl-loadlib package."""
> connectorLL = LoadLibrary(DLL_PATH, 'net')
test_main.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <[AttributeError("'LoadLibrary' object has no attribute '_lib'") raised in repr()] LoadLibrary object at 0
x4152c18>
path = WindowsPath('C:/Users/AZ/Desktop/test_bom-mcs/Microsoft.Dynamics.BusinessConnectorNet.dll')
libtype = 'net'
def __init__(self, path, libtype='cdll'):
_path = path
# a reference to the .NET Runtime Assembly
self._assembly = None
# assume a default extension if no extension was provided
if not os.path.splitext(_path)[1]:
_path += DEFAULT_EXTENSION
self._path = os.path.abspath(_path)
if not os.path.isfile(self._path):
# for find_library use the original 'path' value since it may be a library name
# without any prefix like lib, suffix like .so, .dylib or version number
self._path = ctypes.util.find_library(path)
if self._path is None: # then search sys.path and os.environ['PATH']
success = False
search_dirs = sys.path + os.environ['PATH'].split(os.pathsep)
for directory in search_dirs:
p = os.path.join(directory, _path)
if os.path.isfile(p):
self._path = p
success = True
break
if not success:
raise IOError('Cannot find the shared library "{}"'.format(path))
if libtype == 'cdll':
self._lib = ctypes.CDLL(self._path)
elif libtype == 'windll':
self._lib = ctypes.WinDLL(self._path)
elif libtype == 'oledll':
self._lib = ctypes.OleDLL(self._path)
elif libtype == 'net' and self.is_pythonnet_installed():
import clr
try:
# By default, pythonnet can only load libraries that are for .NET 4.0+.
#
# When MSL-LoadLib is installed, the useLegacyV2RuntimeActivationPolicy
# property should have been enabled automatically to allow for loading
# assemblies from previous .NET Framework versions.
self._assembly = clr.System.Reflection.Assembly.LoadFile(self._path)
except clr.System.IO.FileLoadException as err:
# Example error message that can occur if the library is for .NET <4.0,
# and the useLegacyV2RuntimeActivationPolicy is not enabled:
#
# " Mixed mode assembly is built against version 'v2.0.50727' of the
# runtime and cannot be loaded in the 4.0 runtime without additional
# configuration information. "
#
# To solve this problem, a <python-executable>.config file must exist and it must
# contain a useLegacyV2RuntimeActivationPolicy property that is set to be "true".
if "Mixed mode assembly" in str(err):
status, msg = self.check_dot_net_config(sys.executable)
if not status == 0:
raise IOError(msg)
else:
update_msg = 'Checking .NET config returned "{}" '.format(msg)
update_msg += 'and still cannot load library.\n'
update_msg += str(err)
raise IOError(update_msg)
raise IOError('The above "System.IO.FileLoadException" is not handled.\n')
# the shared library must be available in sys.path
head, tail = os.path.split(self._path)
sys.path.insert(0, head)
# don't include the library extension
clr.AddReference(os.path.splitext(tail)[0])
# import namespaces, create instances of classes or reference a System.Type[] object
dotnet = {}
> for t in self._assembly.GetTypes():
E System.Reflection.ReflectionTypeLoadException: Unable to load one or more of the requested types. Ret
rieve the LoaderExceptions property for more information.
E at System.Reflection.RuntimeModule.GetTypes(RuntimeModule module)
E at System.Reflection.Assembly.GetTypes()
..\..\.virtualenvs\test_bom-mcs-bwfslhpz\lib\site-packages\msl\loadlib\load_library.py:132: ReflectionTypeLoadExc
eption
________________________ test_pure_pythonnet_connector ________________________
def test_pure_pythonnet_connector():
"""Get Axapta object via pythonnet package."""
clr.AddReference(str(DLL_PATH))
> from Microsoft.Dynamics.BusinessConnectorNet import Axapta
E ModuleNotFoundError: No module named 'Microsoft'
test_main.py:21: ModuleNotFoundError
========================== 2 failed in 0.61 seconds ===========================
P.S。 stackoverflow分级器要求我添加更多细节:)
还有什么 - obj = clr.AddRefrence
有效,我可以在obj
中看到Microsoft属性。但没有任何Dynamics
等。
此示例的存储库位于 https://gitlab.com/remak_team/open-source/MicrosoftDynamicsConnector_python_wrapper/tree/master
答案 0 :(得分:2)
此异常与Microsoft.Dynamics.BusinessConnectorNet.dll
库未找到所有必需的依赖项有关。
在成功加载此库的计算机上,我使用Dependency Walker和DependencyWalker for .NET创建了一个文件,其中包含这两个Walker发现的所有依赖项的完整路径。可以下载here所需的依赖项列表。
希望您能够从此列表中找到缺少的依赖项,然后您就可以加载Microsoft.Dynamics.BusinessConnectorNet.dll
库。