1

Windows 10 (x64) Python 3.6.3 cx_Freeze 5.1.1 pypiwin32 223 / pywin32 224

I made a module for printing, the module works fine when launching it as a script. Once passed through cx_Freeze, the print command doesn't work without producing any error message. Here is my setup.py for creating builds (by: python setup.py build)

# -*- coding: utf-8 -*-
import sys,os
from cx_Freeze import setup, Executable

PythonPath = os.path.split(sys.executable)[0] #get python path

includes = []

excludes = []

packages = ["win32print"]

includefiles = ["OptiWeb.ico"]

options = {"includes": includes,
           "excludes": excludes,
           "packages": packages,
           "include_files": includefiles,
           "optimize":2
           }

base=None

if sys.platform == 'win32':
    base = "Win32GUI"
    options["include_msvcr"] = True


executables = [Executable(script="OptiPrint.py",base=base,icon="Optiweb.ico")]

setup(name = "OptiPrint",options = {"build_exe": options},version = "1.0",author = "ND",description = "print test",executables = executables)

And now my code for printing:

# coding: utf8

import win32print

class ZPLLabel(object):
    def __init__(self, printerName):
        self.printerName = printerName
        self.printerDevice = win32print.OpenPrinter(self.printerName)
        self.job = win32print.StartDocPrinter(self.printerDevice, 1, ("Etiquette", None, "RAW"))
        self.eraseAll()
        self.defineFormat()

    def eraseAll(self):
        win32print.StartPagePrinter(self.printerDevice)
        str2print="~JA"
        win32print.WritePrinter(self.printerDevice, str2print.encode("utf8")) #écrit le format d'étiquette
        win32print.EndPagePrinter(self.printerDevice) # indique la fin de ce qu'il y a à imprimer
        self.printerDevice.close() # ferme le canal d'impression et déclenche l'impression de ce qui précède
        #del self.job    
        self.printerDevice=win32print.OpenPrinter(self.printerName)
        self.job = win32print.StartDocPrinter(self.printerDevice, 1, ("Etiquette", None, "RAW"))

    def defineFormat(self):
        margeLeft = 150
        margeTop = 20
        interLine = 39
        shiftLeft = 20
        vDec = 25
        #win32print.StartPagePrinter(p)
        str2print="^XA\n" #debut de format
        str2print+="^CI28"
        #FO origine du champ, 100 pos x du champ en dots, 50 pos y du champ en dots
        # l'imprimantes est 200 dpi (dotsper inch = 7.874 dots par mm, ici 12.7mm, 6.35mm)
        #ADN : A ==> font, D==> font D, N ==> Orientation Normale, 36 hauteur caractère en dots, 20 Largeur caractère en dots
        #FD données à imprimer pour le champ
        #FS fin du champ
        str2print+="^DFFORMAT"
        str2print+="^LH"+str(margeLeft)+","+str(margeTop)
        #un cadre arrondi
        str2print+="^FO0,0^GB500,330,3,B,2^FS"    
        #str2print+="^FO"+str(shiftLeft)+","+str(interLine)+"^ADN,24,12^FDEtiquette de débit Sangle^FS\n" #format de l'étiquette
        str2print+="^FO"+str(shiftLeft)+","+str(1*interLine-vDec) +"^ADN,32,14^FDOF N° : ^FS^FO"+str(shiftLeft+160)+","+str(1*interLine-vDec) +"^ADN,32,14^FN1^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(2*interLine-vDec) +"^ADN,32,14^FDPRODUIT : ^FS^FO"+str(shiftLeft+215)+","+str(2*interLine-vDec) +"^ADN,32,14^FN2^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(3*interLine-vDec) +"^ADN,24,12^FN3^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(4*interLine-vDec) +"^ADN,32,14^FDSANGLE : ^FS^FO"+str(shiftLeft+200)+","+str(4*interLine-vDec) +"^ADN,32,14^FN4^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(5*interLine-vDec) +"^ADN,24,12^FN5^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(6*interLine-vDec) +"^ADN,28,13^FDNombre de coupe : ^FS^FO"+str(shiftLeft+250)+","+str(6*interLine-vDec) +"^ADN,28,13^FN6^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(7*interLine-vDec) +"^ADN,28,13^FDLongueur coupée : ^FS^FO"+str(shiftLeft+250)+","+str(7*interLine-vDec) +"^ADN,28,13^FN7^FS"
        str2print+="^FO"+str(shiftLeft)+","+str(8*interLine-vDec) +"^ADN,24,12^FDEmplacement : ^FS^FO"+str(shiftLeft+160)+","+str(8*interLine-vDec) +"^ADN,24,12^FN8^FS"
        str2print+="^XZ" # fin du format d'étiquette
        win32print.WritePrinter(self.printerDevice, str2print.encode("utf8")) #écrit le format d'étiquette 

    def printLabel(self, orderNum, productSku, productName, webSku, webName, partNum, partLength, emplacement):
        str2print="^XA\n" #debut étiquette
        str2print+="^XFFORMAT" #rappel du format enregistré
        str2print+="^FN1^FD"+orderNum+"^FS"
        str2print+="^FN2^FD"+productSku+"^FS"
        str2print+="^FN3^FD"+productName+"^FS"
        str2print+="^FN4^FD"+webSku+"^FS"
        str2print+="^FN5^FD"+webName+"^FS"
        str2print+="^FN6^FD"+str(partNum)+"^FS"
        str2print+="^FN7^FD"+partLength+"^FS"
        str2print+="^FN8^FD"+emplacement+"^FS"
        str2print+="^XZ" # fin du format d'étiquette 
        win32print.WritePrinter(self.printerDevice, str2print.encode("utf8")) #écrit l'étiquette 

    def endLabel(self):
        self.printerDevice.close() # ferme le canal d'impression et déclenche l'impression de ce qui précède
        del self.job

def newPrintLabel():
    zpl = ZPLLabel('Zebra ZP 450 CTP')
    zpl.printLabel("20009999", "1035691", "Harnais Energy TWIN ss porte outil L/XL",
                       "90008318", "SA/SANGLE NOIRE 20 MM", 35, "0.38m", "Bavaroise réglable")
    zpl.endLabel()

if __name__ == '__main__':
    app = newPrintLabel()

I suppose, some package or dll is missing to make it run when frozen. I tried to add win32api, win32com but it doesn't change the result.

Thanks for your help which is for sure welcome.

jpeg
  • 2,372
  • 4
  • 18
  • 31
Pascal
  • 11
  • 3
  • Please include the exact error message / the complete stack trace in your question. Side note: Zebra should support to print via Serial Port and/or TCP, maybe you can try that instead? – Mike Scotty Jan 17 '19 at 15:48
  • As mentionned, there is no error message, that just doesn't print with frozen version (not with py script version) – Pascal Jan 17 '19 at 17:16
  • Have you tried to start your frozen application from within a `cmd` prompt? Do you see any error message in this case? By the way, if I understand you application correctly, you do not have any GUI, so `base=None` would probably be a better choice. Furthermore, the option `include_msvcr` does not seem to work with the current `cx_Freeze` version, see [this issue](https://github.com/anthony-tuininga/cx_Freeze/issues/278). – jpeg Jan 18 '19 at 06:59
  • As written above, there isn't error message, the print instructions doesn't work, that's all what I can say, with the frozen version. At the opposite all works fine with the py script version. – Pascal Jan 18 '19 at 08:11
  • Oups. Sorry for repetition.Yes I tried it from cmd prompt, there isn't error message too and that doesn't work. I notice another thing, from prompt of IDLE python the behaviour of the script is the same as the frozen version. From cmd, it works fine, from Eric it works fine too. – Pascal Jan 18 '19 at 08:22
  • Have you tried changing the optimization level? – Christian K. Jan 23 '19 at 00:57
  • No, I must say that I take my setup from example on the web and don't really know what it does. what value do you advice to put ? – Pascal Jan 24 '19 at 07:31
  • I tried with optimize=0,1,2 without any improvement. – Pascal Jan 24 '19 at 07:50
  • I make a try, using the code as module called by another script, after freeze, I delete the module in the frozen package and replace it by putting the .pyc generated by the scripts (which runs fine). The result is the same. So, I believe that really a dll or a python module is missing when frozen. – Pascal Jan 25 '19 at 10:30

2 Answers2

1

Try to use win32ui and win32con as done in the answers of python win32print not printing.

In this case you should also keep base defined as in your original question (regarding my comment to your question).

jpeg
  • 2,372
  • 4
  • 18
  • 31
  • I added both modules (win32ui & win32con) as recommended ; it always doesn't work. I can add that the job appears in the window obtain by Printers in the control panels. It appears in a "pause" mode and the only action possible is "cancel" (I'm not sure of the exact words, cause my Windows OS is in French, sorry for that). To reply to jpeg, in fact this piece of code is extracted from a bigger program with GUI under Pyside2, with the part of code which reproduces the problem I have. – Pascal Jan 21 '19 at 08:47
0

For those who experiment a such issue. My code was not properly written: To each StartDocPrinter instruction must correspond a EndDocPrinter instruction, apparently this not cause trouble with script but has impact on frozen version. So the correct thread of instructions must be something like:

    self.printerName = printerName
    self.printerDevice = win32print.OpenPrinter(self.printerName)
    self.job = win32print.StartDocPrinter(self.printerDevice, 1, ("Etiquette", None, "RAW"))
    win32print.StartPagePrinter(self.printerDevice)
    str2print="..." # define what you want to print
    win32print.WritePrinter(self.printerDevice, str2print.encode("utf8")) #write
    win32print.EndPagePrinter(self.printerDevice) # end the page
    win32print.EndDocPrinter(self.printerDevice)  # end the doc      
    self.printerDevice.close() # close the printer thread
Pascal
  • 11
  • 3