1

I am currently using cx_freeze 6.1 (had some different issues with 6.2 and 6.3) to generate MSI windows installer for an OpenCV python application. Compilation was successful and generated MSI installer. Installer works fine when base is set to "None" or "Console". However, it throws error for base = "Win32GUI". I am setting the base to Win32GUI because I don't want the users to see the prompt windows or allow them to accidentally close the application. Refer the attachment to see the complete error. I have tried few old solutions as mentioned in other posts but nothing helped. I tried including 'click' in excludes, it didn't help as well. Appreciate any relevant responses.

Error in Windows GUI

Manoj K
  • 21
  • 4

1 Answers1

1

After struggle of two days, I found my own answer. Sharing so it can help others. base="Win32GUI" - This try writing all strerr and stdout messages to Windows GUI. However, with limited memory, it will fail most of the times as it will try redirecting those errors to some file.

Best approach is the following:

Redirect all stderr and stdout messages to any file, e.g. log file. I followed instructions of: How to redirect stdout and stderr to logger in Python and created logger writer:

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)

Then in app.py or your main flask file, create log and/or error file(s). Example below creates 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()
Manoj K
  • 21
  • 4