PyInstaller 3.4
Python 3.7
赢7-64位
我使用.exe
从python代码中制作了PyInstaller
,它具有以下逻辑。目标是在Windows的新控制台窗口中启动http服务器。这是为了避免锁定/阻止主应用程序,并且用户在使用完http服务器后,只需关闭新启动的控制台窗口即可。
p = subprocess.call('start "" python -m http.server --directory {} {} --bind {}'.format(web_server_path, web_server_port, web_bind_ip), shell=True)
这在安装了Python的Windows PC上有效,但在没有Python的PC上自然不可用。
由于目标是将此.exe
分发给没有安装python的用户,有人可以推荐正确的方法来在PyInstaller中使用Python来完成上述行为吗?我知道PyInstaller生成的.exe
实际上正在运行Python解释器,但是我不知道如何使用我的代码来使用它。
UPDATE
要求用户能够设置directory
,port
和address
。理想情况下,只需关闭一个窗口就可以很容易地停止它(因此采用原始的命令行方法),但是可以更改。
进一步更新
是否可以加载python3.dll并以某种方式直接使用其功能?
ctypes.WinDLL('Path:\to\my.dll')
答案 0 :(得分:1)
由于示例代码可能会启动Web服务器而不会阻止脚本的进一步执行,因此您希望在单独的线程上运行Web服务器。
from sys import version_info
import http.server
import socketserver
from threading import Thread
class WebServer(Thread):
@staticmethod
def get_directory_simple_http_request_handler(directory):
_current_only = version_info < (3, 7)
class _DirectorySimpleHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
_current_only = version_info < (3, 7)
def __init__(self, *args, **kwargs):
if not self._current_only:
kwargs['directory'] = directory
super(_DirectorySimpleHTTPRequestHandler, self).__init__(*args, **kwargs)
@property
def current_only(self):
return self._current_only
return _DirectorySimpleHTTPRequestHandler
def __init__(self, address='127.0.0.1', port=8000, directory=''):
self.handler = self.get_directory_simple_http_request_handler(directory)
self.httpd = socketserver.TCPServer((address, port), self.handler)
Thread.__init__(self)
def run(self):
self.httpd.serve_forever()
def join(self, *args, **kwargs):
self.httpd.shutdown()
super().join(*args, **kwargs)
web_server = None
while True:
if web_server is None:
print('Currently not running (type start or exit).')
else:
print('Running on:', web_server.httpd.server_address, '(type stop or exit)')
if web_server.handler.current_only:
print('Serving current directory, Python <3.7 has no `directory` on SimpleHTTPRequestHandler.')
command = input('>')
if command == 'start':
if web_server is None:
web_server = WebServer(directory=r'C:\Temp')
web_server.start()
if command == 'stop':
if web_server is not None:
web_server.join()
web_server = None
if command == 'exit':
exit(0)
请注意,Python 3.7是第一个支持directory
参数的版本,早期版本的Python仅会为该进程提供当前目录。
可以使用工厂静态方法来设置SimpleHTTPRequestHandler
的单独实例,并使用所需目录对其进行初始化。
如果您实际上希望仅启动控制台窗口,请运行Python(测试)Web服务器(或其他外部服务器,如果Python不可用):
import time
from subprocess import Popen, CREATE_NEW_CONSOLE
proc = Popen(['python', '-m', 'http.server', '8000'],
cwd=r'C:\temp',
creationflags=CREATE_NEW_CONSOLE, close_fds=True)
while True:
print('Running')
time.sleep(2)
类似地,如果您喜欢安静的环境,但是不需要访问Web服务器对象,那么它也可以工作:
import time
from subprocess import Popen
proc = Popen(['python', '-m', 'http.server', '8000'], close_fds=True, cwd=r'C:\temp')
while True:
print('Running')
time.sleep(2)