ベスパリブ

プログラミングを主とした日記・備忘録です

pythonnetのclrのインストールと使い方

pythonnetパッケージとは、Python for .NETと呼ばれるもので、.NETのCommon Language Runtime(CLR)をPythonで扱えるようになるパッケージです。

といってもあまりよくわかってないのですが、とにかくこのpythonnetのclrモジュールを使うことで、Pythonプログラムの中でdllファイルを読み込んで、そのdllモジュールを使うことができます。

github.com

pythonnetのインストール

Installation · pythonnet/pythonnet Wiki · GitHub

Anacondaだとまたインストールの方法が違うようです。詳しくは上記の公式Wikiを見てください。

Python3.8.xだとPythonの3.8.0のバグにより、インストールに失敗します。(2020/03/23現在)

pythonnetの公式には3.8.1で修正される予定みたいなこと書いてありますが、3.8.1でも以下のようなエラーが出てしまいます。

(venv) > pip install pythonnet
    Collecting pythonnet
      Using cached pythonnet-2.4.0.tar.gz (1.8 MB)
    Building wheels for collected packages: pythonnet
      Building wheel for pythonnet (setup.py) ... error
      ERROR: Command errored out with exit status 1:
        command: 'c:\users\XXXX\workspace\clr_test\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\XXXX\\AppData\\Local\\Temp\\pip-install-co_4hlm1\\pythonnet\\setup.py'"'"'; __file__='"'"'C:\\Users\\XXXX\\AppData\\Local\\Temp\\pip-install-co_4hlm1\\pythonnet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' bdist_wheel -d 'C:\Users\XXXX\AppData\Local\Temp\pip-wheel-j0v3wdk9'
            cwd: C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\
      Complete output (70 lines):
      running bdist_wheel
      running build
      running build_ext
      https://www.nuget.org/api/v2/ の更新を確認しています。
      NuGet.exe 4.1.0 は実行中です。
      NuGet.exe を 5.4.0 に更新しています。
      正常に更新されました。
      MSBuild auto-detection: using msbuild version '14.0' from 'C:\Program Files (x86)\MSBuild\14.0\bin\amd64'.
      Restoring NuGet package NUnit.3.7.1.
      Restoring NuGet package UnmanagedExports.1.2.7.
      Restoring NuGet package NUnit.ConsoleRunner.3.7.0.
      Adding package 'NUnit.ConsoleRunner.3.7.0' to folder 'C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\packages'
      Adding package 'UnmanagedExports.1.2.7' to folder 'C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\packages'
      Adding package 'NUnit.3.7.1' to folder 'C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\packages'
      Added package 'UnmanagedExports.1.2.7' to folder 'C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\packages'
      Added package 'NUnit.ConsoleRunner.3.7.0' to folder 'C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\packages'
      Added package 'NUnit.3.7.1' to folder 'C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\packages'

      NuGet Config files used:
          C:\Users\XXXX\AppData\Roaming\NuGet\NuGet.Config
          C:\Program Files (x86)\NuGet\Config\Microsoft.VisualStudio.Offline.config

      Feeds used:
          C:\Users\XXXX\.nuget\packages\
          https://api.nuget.org/v3/index.json
          C:\Program Files (x86)\Microsoft SDKs\NuGetPackages\

      Installed:
          3 package(s) to packages.config projects
      Traceback (most recent call last):
        File "tools\geninterop\geninterop.py", line 24, in <module>
          from pycparser import c_ast, c_parser
      ModuleNotFoundError: No module named 'pycparser'
      Traceback (most recent call last):
        File "<string>", line 1, in <module>
        File "C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\setup.py", line 623, in <module>
          setup(
        File "c:\users\XXXX\workspace\clr_test\venv\lib\site-packages\setuptools\__init__.py", line 145, in setup
          return distutils.core.setup(**attrs)
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\core.py", line 148, in setup
          dist.run_commands()
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\dist.py", line 966, in run_commands
          self.run_command(cmd)
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\dist.py", line 985, in run_command
          cmd_obj.run()
        File "C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\setup.py", line 610, in run
          return bdist_wheel.bdist_wheel.run(self)
        File "c:\users\XXXX\workspace\clr_test\venv\lib\site-packages\wheel\bdist_wheel.py", line 223, in run
          self.run_command('build')
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\cmd.py", line 313, in run_command
          self.distribution.run_command(command)
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\dist.py", line 985, in run_command
          cmd_obj.run()
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\command\build.py", line 135, in run
          self.run_command(cmd_name)
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\cmd.py", line 313, in run_command
          self.distribution.run_command(command)
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\dist.py", line 985, in run_command
          cmd_obj.run()
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\command\build_ext.py", line 340, in run
          self.build_extensions()
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\command\build_ext.py", line 449, in build_extensions
          self._build_extensions_serial()
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\distutils\command\build_ext.py", line 474, in _build_extensions_serial
          self.build_extension(ext)
        File "C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\setup.py", line 298, in build_extension
          subprocess.check_call([sys.executable, geninterop, interop_file])
        File "C:\Users\XXXX\AppData\Local\Programs\Python\Python38-32\lib\subprocess.py", line 364, in check_call
          raise CalledProcessError(retcode, cmd)
      subprocess.CalledProcessError: Command '['c:\\users\\XXXX\\workspace\\clr_test\\venv\\scripts\\python.exe', 'tools\\geninterop\\geninterop.py', 'src\\runtime\\interop38.cs']' returned non-zero exit status
    1.
      ----------------------------------------
      ERROR: Failed building wheel for pythonnet
      Running setup.py clean for pythonnet
    Failed to build pythonnet
    Installing collected packages: pythonnet
        Running setup.py install for pythonnet ... error
        ERROR: Command errored out with exit status 1:
          command: 'c:\users\XXXX\workspace\clr_test\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\XXXX\\AppData\\Local\\Temp\\pip-install-co_4hlm1\\pythonnet\\setup.py'"'"'; __file__='"'"'C:\\Users\\XXXX\\AppData\\Local\\Temp\\pip-install-co_4hlm1\\pythonnet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\XXXX\AppData\Local\Temp\pip-record-avnq3p6k\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\XXXX\workspace\clr_test\venv\include\site\python3.8\pythonnet'
              cwd: C:\Users\XXXX\AppData\Local\Temp\pip-install-co_4hlm1\pythonnet\
        Complete output (6 lines):
        usage: setup.py [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
            or: setup.py --help [cmd1 cmd2 ...]
            or: setup.py --help-commands
            or: setup.py cmd --help

        error: option --single-version-externally-managed not recognized
        ----------------------------------------
    ERROR: Command errored out with exit status 1: 'c:\users\XXXX\workspace\clr_test\venv\scripts\python.exe' -u -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'C:\\Users\\XXXX\\AppData\\Local\\Temp\\pip-install-co_4hlm1\\pythonnet\\setup.py'"'"'; __file__='"'"'C:\\Users\\XXXX\\AppData\\Local\\Temp\\pip-install-co_4hlm1\\pythonnet\\setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' install --record 'C:\Users\XXXX\AppData\Local\Temp\pip-record-avnq3p6k\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\users\XXXX\workspace\clr_test\venv\include\site\python3.8\pythonnet' Check the logs for full command output.

python3.7以下だとインストールできます。(以下の方法はグローバルインストールするので、アンインストールしたければpy -3.7 -m pip uninstall pythonnetをすること)

(venv) PS C:\Users\XXXX\workspace\clr_test> py -3.7 -m pip install pythonnet
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> exit()
Collecting pythonnet
  Downloading https://files.pythonhosted.org/packages/65/ed/cd200e95392d7f4a74319ff9166ba8a4a6fb28a405b065297f3fdec82da9/pythonnet-2.4.0-cp37-cp37m-win_amd64.whl (70kB)
      |████████████████████████████████| 71kB 1.5MB/s 
Installing collected packages: pythonnet
Successfully installed pythonnet-2.4.0

グローバルインストールされてるので、アンインストールしたければ以下のようにアンインストールします。

# インストールの確認
PS C:\Users\XXXX\workspace\hoge> py -3.7 -m pip freeze
pythonnet==2.4.0
# アンインストール
PS C:\Users\XXXX\workspace\hoge> py -3.7 -m pip uninstall pythonnet
Uninstalling pythonnet-2.4.0:
  Would remove:
    c:\users\XXXX\appdata\local\programs\python\python37\lib\site-packages\clr.pyd
    c:\users\XXXX\appdata\local\programs\python\python37\lib\site-packages\python.runtime.dll
    c:\users\XXXX\appdata\local\programs\python\python37\lib\site-packages\pythonnet-2.4.0.dist-info\*
Proceed (y/n)? y
  Successfully uninstalled pythonnet-2.4.0
# 再度確認
PS C:\Users\XXXX\workspace\hoge> py -3.7 -m pip freeze
PS C:\Users\XXXX\workspace\hoge>

clrモジュールの使い方

さて、pythonnetがインストールされていれば、clrモジュールを使うことができます。

>>> import clr
>>> dir(clr)
['AddReference', 'FindAssembly', 'GetClrType', 'ListAssemblies', 'Microsoft', 'Python', 'System', '_AtExit', '__class__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', '__version__', '_extras', 'clrModule', 'clrmethod', 'clrproperty', 'e__NativeCall', 'getPreload', 'setPreload']

いろんなサイトを巡回してみると、AddReferenceToFileAndPathを使ってるサイトがありますが、AddReferenceでOK。

import clr
clr.AddReference(r"...\Redist\SolidWorks.Interop.swconst.dll")
from SolidWorks.Interop import swconst
    
print(swconst.swDisplayStateOpts_e.swAllDisplayState)
# 2

stackoverflow.com

clr違い

>>> import clr
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'clr'

上記のエラーを見て、ついpip install clrをしてしまうと、違うclrモジュールをインストールしてしまうので注意が必要です。

pypi.org

(venv) PS C:\Users\XXXX\workspace\clr_test> pip install clr
Collecting clr
  Using cached clr-1.0.3-py2.py3-none-any.whl (4.4 kB)
Installing collected packages: clr
Successfully installed clr-1.0.3
(venv) PS C:\Users\XXXX\workspace\clr_test> py
Python 3.8.1 (tags/v3.8.1:1b293b6, Dec 18 2019, 22:39:24) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import clr
>>> dir(clr)
['StyleBuilder', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__module__', '__name__', '__package__', '__path__', '__spec__', '_styles', 'black', 'blue', 'bold', 'cyan', 'dim', 'green', 'hidden', 'inverse', 'italic', 'key', 'light_black', 'light_blue', 'light_cyan', 'light_green', 'light_magenta', 'light_red', 'light_white', 'light_yellow', 'magenta', 'on_black', 'on_blue', 'on_cyan', 'on_green', 'on_light_black', 'on_light_blue', 'on_light_cyan', 'on_light_green', 'on_light_magenta', 'on_light_red', 'on_light_white', 'on_light_yellow', 'on_magenta', 'on_red', 'on_white', 'on_yellow', 'red', 'strikethrough', 'style_builder', 'sys', 'underline', 'value', 'white', 'yellow']

参考