Paramiko SSHClient.connect(...) 在 Windows 上与 Pyinstaller 打包时失败
Paramiko SSHClient.connect(...) fails when packaged with Pyinstaller on Windows
Paramiko 的 SSHClient.connect(...)
方法在使用 Pyinstaller 打包时会引发异常,但在不打包时会 运行 正常。
这会使用 Pyinstaller 标志 --onedir
和 --onefile
。我已经尝试了 Pyinstaller 版本 3.5
和当前最新的开发版本 4.0.dev0+ce887b462
。 --noupx
没有明显的效果。
我的 Paramiko 版本是 2.6.0
。
我当前的 Python 版本是 2.7.15
我的 OS 是 Windows 10 Pro,版本 10.0.17134,内部版本 17134。
这个问题似乎是由于 Paramiko 在 kernel32.dll
中调用 C 函数造成的,意外地 returns null
只有在打包时才如此。
最小示例:
import paramiko
# The nature of this issue unfortunately requires
# a server that responds to SSH connections to test
host = None # Put a valid hostname here
port = 22 # Put a valid port here
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(
hostname=host,
port=port,
username=None,
password=None,
timeout=5
)
我希望 Pyinstaller 打包版本 运行 与未打包版本完全相同——在这种情况下,启动 SSH 连接,然后失败并出现 AuthenticationException,因为 username
和password
是 None
:
> virtualenv venv
> venv\Scripts\activate.bat
> pip install pyinstaller==3.5 paramiko==2.6.0
[output truncated for brevity]
> pyinstaller minimal-paramiko-example.py
[output truncated for brevity]
> dist\minimal-paramiko-example\minimal-paramiko-example.exe
Traceback (most recent call last):
File "minimal-paramiko-example.py", line 16, in <module>
timeout=5
File "site-packages\paramiko\client.py", line 446, in connect
File "site-packages\paramiko\client.py", line 691, in _auth
File "site-packages\paramiko\agent.py", line 379, in __init__
File "site-packages\paramiko\agent.py", line 65, in _connect
File "site-packages\paramiko\agent.py", line 82, in _send_message
File "site-packages\paramiko\win_pageant.py", line 129, in send
File "site-packages\paramiko\win_pageant.py", line 96, in _query_pageant
File "site-packages\paramiko\_winapi.py", line 179, in write
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
[16768] Failed to execute script minimal-paramiko-example
> python minimal-paramiko-example.py # Will result in an AuthenticationException, since username and password are None; this is expected and normal
[output truncated for brevity]
此问题是由与 PuTTY Pageant 交互引起的。关闭 PuTTY Pageant 不会导致此错误发生。出于某种原因,它只出现在以下极端情况下:
- 使用 Pyinstaller
- 运行 PuTTY 选美
不满足这两个要求不会触发问题。
Paramiko 的 SSHClient.connect(...)
方法在使用 Pyinstaller 打包时会引发异常,但在不打包时会 运行 正常。
这会使用 Pyinstaller 标志 --onedir
和 --onefile
。我已经尝试了 Pyinstaller 版本 3.5
和当前最新的开发版本 4.0.dev0+ce887b462
。 --noupx
没有明显的效果。
我的 Paramiko 版本是 2.6.0
。
我当前的 Python 版本是 2.7.15
我的 OS 是 Windows 10 Pro,版本 10.0.17134,内部版本 17134。
这个问题似乎是由于 Paramiko 在 kernel32.dll
中调用 C 函数造成的,意外地 returns null
只有在打包时才如此。
最小示例:
import paramiko
# The nature of this issue unfortunately requires
# a server that responds to SSH connections to test
host = None # Put a valid hostname here
port = 22 # Put a valid port here
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(
hostname=host,
port=port,
username=None,
password=None,
timeout=5
)
我希望 Pyinstaller 打包版本 运行 与未打包版本完全相同——在这种情况下,启动 SSH 连接,然后失败并出现 AuthenticationException,因为 username
和password
是 None
:
> virtualenv venv
> venv\Scripts\activate.bat
> pip install pyinstaller==3.5 paramiko==2.6.0
[output truncated for brevity]
> pyinstaller minimal-paramiko-example.py
[output truncated for brevity]
> dist\minimal-paramiko-example\minimal-paramiko-example.exe
Traceback (most recent call last):
File "minimal-paramiko-example.py", line 16, in <module>
timeout=5
File "site-packages\paramiko\client.py", line 446, in connect
File "site-packages\paramiko\client.py", line 691, in _auth
File "site-packages\paramiko\agent.py", line 379, in __init__
File "site-packages\paramiko\agent.py", line 65, in _connect
File "site-packages\paramiko\agent.py", line 82, in _send_message
File "site-packages\paramiko\win_pageant.py", line 129, in send
File "site-packages\paramiko\win_pageant.py", line 96, in _query_pageant
File "site-packages\paramiko\_winapi.py", line 179, in write
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int'
[16768] Failed to execute script minimal-paramiko-example
> python minimal-paramiko-example.py # Will result in an AuthenticationException, since username and password are None; this is expected and normal
[output truncated for brevity]
此问题是由与 PuTTY Pageant 交互引起的。关闭 PuTTY Pageant 不会导致此错误发生。出于某种原因,它只出现在以下极端情况下:
- 使用 Pyinstaller
- 运行 PuTTY 选美
不满足这两个要求不会触发问题。