使用我的应用程序分发 Python.Net:在线安装还是离线安装?

问题描述

我正在寻找一些关于将 Python.Net 与我的应用程序一起分发的最佳方式的建议。 看来我有两个选择:

1.我的应用程序安装程序运行 pip install pythonnet

缺点是客户需要在安装时访问互联网。

2.将 Python.Net 文件与我的应用程序捆绑在一起以允许离线安装

我喜欢可以离线运行的“独立”安装程序的想法,但是这是个好主意吗? 它需要安装与客户安装的 Python 版本匹配的正确版本的 Python.Net。

我尝试了以下步骤:

C:\mkdir download pythonnet
cd download pythonnet
pip download pythonnet     <-- this gets two files: pythonnet-2.5.2.tar.gz and pycparser-2.20-py2.py3-none-any.whl

<disconnect from the internet>

pip install C:\pythonnet_download\pythonnet-2.5.2.tar.gz

然而,这给出了错误

Processing c:\pythonnet_download\pythonnet-2.5.2.tar.gz
Requirement already satisfied: pycparser in c:\program files\python39\lib\site-packages (from pythonnet==2.5.2) (2.20)
Building wheels for collected packages: pythonnet
  Building wheel for pythonnet (setup.py) ... error
  ERROR: Command errored out with exit status 1:
   command: 'c:\program files\python39\python.exe' -u -c 'import sys,setuptools,tokenize; sys.argv[0] = '"'"'C:\\Users\\vincluff\\AppData\\Local\\Temp\\pip-req-build-bgue1v76\\setup.py'"'"'; __file__='"'"'C:\\Users\\vincluff\\AppData\\Local\\Temp\\pip-req-build-bgue1v76\\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\vincluff\AppData\Local\Temp\pip-wheel-s9qap8ze'
       cwd: C:\Users\vincluff\AppData\Local\Temp\pip-req-build-bgue1v76\
  Complete output (44 lines):
  running bdist_wheel
  running build
  running build_ext
  Checking for updates from https://www.nuget.org/api/v2/.
  The remote name Could not be resolved: 'www.nuget.org'
  Traceback (most recent call last):
    File "<string>",line 1,in <module>
    File "C:\Users\vincluff\AppData\Local\Temp\pip-req-build-bgue1v76\setup.py",line 630,in <module>
      setup(
    File "c:\program files\python39\lib\site-packages\setuptools\__init__.py",line 165,in setup
      return distutils.core.setup(**attrs)
    File "c:\program files\python39\lib\distutils\core.py",line 148,in setup
      dist.run_commands()
    File "c:\program files\python39\lib\distutils\dist.py",line 966,in run_commands
      self.run_command(cmd)
    File "c:\program files\python39\lib\distutils\dist.py",line 985,in run_command
      cmd_obj.run()
    File "C:\Users\vincluff\AppData\Local\Temp\pip-req-build-bgue1v76\setup.py",line 612,in run
      return bdist_wheel.bdist_wheel.run(self)
    File "C:\Users\vincluff\AppData\Roaming\Python\python39\site-packages\wheel\bdist_wheel.py",line 290,in run
      self.run_command('build')
    File "c:\program files\python39\lib\distutils\cmd.py",line 313,in run_command
      self.distribution.run_command(command)
    File "c:\program files\python39\lib\distutils\dist.py",in run_command
      cmd_obj.run()
    File "c:\program files\python39\lib\distutils\command\build.py",line 135,in run
      self.run_command(cmd_name)
    File "c:\program files\python39\lib\distutils\cmd.py",in run_command
      cmd_obj.run()
    File "c:\program files\python39\lib\distutils\command\build_ext.py",line 340,in run
      self.build_extensions()
    File "c:\program files\python39\lib\distutils\command\build_ext.py",line 449,in build_extensions
      self._build_extensions_serial()
    File "c:\program files\python39\lib\distutils\command\build_ext.py",line 474,in _build_extensions_serial
      self.build_extension(ext)
    File "C:\Users\vincluff\AppData\Local\Temp\pip-req-build-bgue1v76\setup.py",line 249,in build_extension
      self._install_packages()
    File "C:\Users\vincluff\AppData\Local\Temp\pip-req-build-bgue1v76\setup.py",line 438,in _install_packages
      subprocess.check_call(cmd,shell=use_shell)
    File "c:\program files\python39\lib\subprocess.py",line 373,in check_call
      raise CalledProcessError(retcode,cmd)
  subprocess.CalledProcessError: Command 'tools\nuget\nuget.exe update -self' 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:\program files\python39\python.exe' -u -c 'import sys,'"'"'exec'"'"'))' install --record 'C:\Users\vincluff\AppData\Local\Temp\pip-record-lcx9op7p\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\program files\python39\Include\pythonnet'
         cwd: C:\Users\vincluff\AppData\Local\Temp\pip-req-build-bgue1v76\
    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:\program files\python39\python.exe' -u -c 'import sys,'"'"'exec'"'"'))' install --record 'C:\Users\vincluff\AppData\Local\Temp\pip-record-lcx9op7p\install-record.txt' --single-version-externally-managed --compile --install-headers 'c:\program files\python39\Include\pythonnet' Check the logs for full command output
  • 为什么上述步骤会失败?
  • 如果我让它工作,它是否允许创建与安装的 Python 版本匹配的 Python.Net 轮子?

注意:我能够通过以下步骤进行离线安装,但这是使用特定于我安装的 Python 版本的轮子。我希望它适用于客户拥有的任何 Python 版本。

pip install pythonnet

< search in C:\Users\vince\AppData\Local\pip\cache\wheels for pythonnet-2.5.2-cp39-cp39-win_amd64.whl and copy it to C:\copy_of_pythonnet_wheel >

pip uninstall pythonnet
pip install C:\copy_of_pythonnet_wheel\pythonnet-2.5.2-cp39-cp39-win_amd64.whl

Python.Runtime.dll 相关问题:

如果我使用在线安装程序(pip install pythonnet),它会将 Python.Runtime.dll 放在 site-packages 目录中,例如:C:\Program Files\python39\Lib\site-packages。我的 .Net 应用程序应该加载这个 Python.Runtime.dll,还是应该使用我编译我的 .Net 项目所针对的 Python.Runtime.dll,所以它已经安装在 C:\Program Files\MyDotNetExeLocation 中?

如果是前者,如何指定Python.Runtime.dll的位置?位置取决于用户决定安装 Python 的位置,所以我不知道在哪里可以找到它。 我能想到的一种解决方案:在我的安装程序安装 Python.Net 后,它使用以下命令检查站点包的位置:

py.exe -c "import site; print(next(item for item in site.getsitepackages() if 'site-packages' in item))"

然后将 Python.Runtime.dll 从此目录复制到 C:\Program Files\MyDotNetExeLocation

解决方法

无需使用 pip 安装即将推出的 Python.NET 3.0 即可将 Python 嵌入到 .NET 项目中。您可以从 GitHub src/runtime 目录构建它或获取最新的每月 preview build from NuGet.org

您的应用程序需要将 Runtime.PythonDLL 设置为 python39.dll 的完整路径,将 PythonEngine.PythonHome 设置为 Python 主目录(在 Windows 上,这通常是 python39.dll 所在的目录) ).