在 python 中包装 Microsoft Dynamics Business Connector .net 程序集
Wrapping Microsoft Dynamics Business Connector .net assembly in python
我正在为 Microsoft Dynamics Business Connector .net 程序集编写 python 包装器。
这是我的代码:
"""Implements wrapper for axapta business 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 ===========================
.net反编译器显示:
P.S。 Whosebug 评分员要求我添加更多详细信息:)
还有什么 - obj = clr.AddRefrence
有效,我可以在 obj
中看到 Microsoft 属性。但是没有 Dynamics
等等
此示例的存储库在这里 https://gitlab.com/remak_team/open-source/MicrosoftDynamicsConnector_python_wrapper/tree/master
此异常与 Microsoft.Dynamics.BusinessConnectorNet.dll
库未找到所有必需的依赖项有关。
在能够成功加载此库的计算机上,我使用了 Dependency Walker and DependencyWalker for .NET to create a file that contains the full path to all of the dependencies that these two Walker's found. The list of dependencies that are required can be downloaded here。
希望您能够从此列表中找到缺少的依赖项,然后您将能够加载 Microsoft.Dynamics.BusinessConnectorNet.dll
库。
我正在为 Microsoft Dynamics Business Connector .net 程序集编写 python 包装器。
这是我的代码:
"""Implements wrapper for axapta business 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 ===========================
.net反编译器显示:
P.S。 Whosebug 评分员要求我添加更多详细信息:)
还有什么 - obj = clr.AddRefrence
有效,我可以在 obj
中看到 Microsoft 属性。但是没有 Dynamics
等等
此示例的存储库在这里 https://gitlab.com/remak_team/open-source/MicrosoftDynamicsConnector_python_wrapper/tree/master
此异常与 Microsoft.Dynamics.BusinessConnectorNet.dll
库未找到所有必需的依赖项有关。
在能够成功加载此库的计算机上,我使用了 Dependency Walker and DependencyWalker for .NET to create a file that contains the full path to all of the dependencies that these two Walker's found. The list of dependencies that are required can be downloaded here。
希望您能够从此列表中找到缺少的依赖项,然后您将能够加载 Microsoft.Dynamics.BusinessConnectorNet.dll
库。