Windows installer CX#U冻结窗口-属性错误:';非类型';对象没有属性写入

Windows installer CX#U冻结窗口-属性错误:';非类型';对象没有属性写入,windows-installer,cx-freeze,Windows Installer,Cx Freeze,我目前正在使用cx_freeze 6.1(与6.2和6.3有一些不同的问题)为OpenCV python应用程序生成MSI windows安装程序。编译成功并生成了MSI安装程序。 当base设置为“无”或“控制台”时,安装程序工作正常。但是,它会为base=“Win32GUI”抛出错误。 我将基本设置为Win32GUI,因为我不希望用户看到提示窗口或允许他们意外关闭应用程序。 请参阅附件以查看完整错误。我尝试过其他帖子中提到的一些旧解决方案,但没有任何帮助。我试着在排除项中包含“单击”,但也没

我目前正在使用cx_freeze 6.1(与6.2和6.3有一些不同的问题)为OpenCV python应用程序生成MSI windows安装程序。编译成功并生成了MSI安装程序。 当base设置为“无”或“控制台”时,安装程序工作正常。但是,它会为base=“Win32GUI”抛出错误。 我将基本设置为Win32GUI,因为我不希望用户看到提示窗口或允许他们意外关闭应用程序。 请参阅附件以查看完整错误。我尝试过其他帖子中提到的一些旧解决方案,但没有任何帮助。我试着在排除项中包含“单击”,但也没有效果。感谢所有相关回复


经过两天的斗争,我找到了自己的答案。分享,这样可以帮助他人。 base=“Win32GUI”-尝试将所有strerr和stdout消息写入Windows GUI。但是,由于内存有限,它会尝试将这些错误重定向到某个文件,因此在大多数情况下都会失败

最佳方法如下:

将所有stderr和stdout消息重定向到任何文件,例如日志文件。我按照:的说明创建了记录器编写器:

import sys

class LoggerWriter:
def __init__(self, level):
    # self.level is really like using log.debug(message)
    # at least in my case
    self.level = level

def write(self, message):
    # if statement reduces the amount of newlines that are
    # printed to the logger
    if message != '\n':
        self.level(message)

def flush(self):
    # create a flush method so things can be flushed when
    # the system wants to. Not sure if simply 'printing'
    # sys.stderr is the correct way to do it, but it seemed
    # to work properly for me.
    self.level(sys.stderr)
然后在app.py或主烧瓶文件中,创建日志和/或错误文件。下面的示例创建error.log

import configparser
import logging
import sys
from LoggerWriter import LoggerWriter
from pathlib import Path
from logging.handlers import TimedRotatingFileHandler
from threading import Timer

# Create Logger if doesn't exist
Path("log").mkdir(parents=True, exist_ok=True)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler = TimedRotatingFileHandler('log/error.log', when="midnight", 
interval=1, encoding='utf8')
handler.suffix = "%Y-%m-%d"
handler.setFormatter(formatter)
logger = logging.getLogger()
logger.setLevel(logging.ERROR)
logger.addHandler(handler)
sys.stdout = LoggerWriter(logging.debug)
sys.stderr = LoggerWriter(logging.warning)

if __name__ == '__main__':
   app.run()