2020-12-17

pyinstaller打包

##Popen

class subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

在脚本状态下stdout=None, stderr=None时运行不会有任何问题,但经过pyInstall打包成exe后,运行时会出现 ”[Error 6] The handle is invalid” 异常,解决方法如下:

脚本原始调用方法:

Import subprocess

p = subprocess.Popen("myapp.exe", stdin=subprocess.PIPE, stdout=None, stderr=None)
p.stdin.write('xxx')

适配pyInstaller的写法:

Import subprocess

p = subprocess.Popen("x.exe", stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.stdin.write('xxx')
p.stdout.close()
p.stderr.close()

Multiprocessing

代码中直接使用标准库中的multiprocessing.Process和multiprocessing.Pool,在打包成可执行程序后会创建进程失败。

对于pyinstaller的one-directory模式,只要再程序的最开始调用multiprocessing. freeze_support()就可以了,但对于one-file模式,还需要使用下面修改后的Process和Pool。

import multiprocessing.forking
import multiprocessing.pool
import os
import sys
class _Popen(multiprocessing.forking.Popen):
    def __init__(self, *args, **kw):
        if hasattr(sys, 'frozen'):
            # We have to set original _MEIPASS2 value from sys._MEIPASS
            # to get --onefile mode working.
            # Last character is stripped in C-loader. We have to add
            # '/' or '\\' at the end.
            os.putenv('_MEIPASS2', sys._MEIPASS + os.sep)
        try:
            super(_Popen, self).__init__(*args, **kw)
        finally:
            if hasattr(sys, 'frozen'):
                # On some platforms (e.g. AIX) 'os.unsetenv()' is not
                # available. In those cases we cannot delete the variable
                # but only set it to the empty string. The bootloader
                # can handle this case.
                if hasattr(os, 'unsetenv'):
                    os.unsetenv('_MEIPASS2')
                else:
                    os.putenv('_MEIPASS2', '')

class Process(multiprocessing.Process):
    _Popen = _Popen
   
class Pool(multiprocessing.pool):
    Process = Process

模块引用

脚本运行状态下,当需要使用全路径引用py文件时(如当前模块路径的父目录中的.py文件),可以通过添加路径的方法减少引用层数。假设plugins处于代码的根目录下,如果想引用plugins\Demo1\Demo1MainFrame.py,可以用下述方法:

Import  plugin.Demo1. Demo1MainFrame

也可以先在程序最开始执行:

sys.path.append("./Plugins")

然后再使用:

Import  Demo1. Demo1MainFrame

from plugin import *

经过测试:这种方法在pyInstaller打包后的程序中可以使用

##其它

1.打包过程中若遇到临时文件访问权限的问题,可临时禁用杀毒和防火墙功能后再尝试;
2.pyInstall仅支持ascii编码方式,打包后可执行文件数径中不能有中文。

#引用地址:http://blog.csdn.net/dexterchen/article/details/37727539

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值