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

Python.Net distribution with my application: online or offline install?

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

1.我的应用程序安装程序 运行s 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", line 985, 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", line 313, in run_command
      self.distribution.run_command(command)
    File "c:\program files\python39\lib\distutils\dist.py", line 985, 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, 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'"'"'))' 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, 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'"'"'))' 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 版本一起使用。

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 放置在站点包目录中,例如: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:\ProgramFiles\MyDotNetExeLocation

即将推出的 Python.NET 3.0 无需使用 pip 安装即可将 Python 嵌入到 .NET 项目中。您可以从 GitHub src/runtime directory or get the latest monthly preview build from NuGet.org.

构建它

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