0

Summary

I am trying to use the package pdfkit (version 0.6.1) and wkhtmltopdf (version 0.12.6.0) to convert HTML to PDF.

I can use the script, until I try to convert it to an .exe file using cx_freeze. Then it fails. Using the executable, I get the following error:

Error

Exception in thread Thread-109:
Traceback (most recent call last):
  File "C:\Users\Diego\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "C:\Users\Diego\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\Diego\Pictures\Zona Python\GuideMath\src\interfaz\VentanaExportar.py", line 132, in __exportarHTMLaPDF
    self.__resultado = self.__ctrl.exportarHTMLaPDF(
  File "C:\Users\Diego\Pictures\Zona Python\GuideMath\src\controlador\Controlador.py", line 142, in exportarHTMLaPDF
    return "E" if pdfkit.from_url(
  File "C:\Users\Diego\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pdfkit\api.py", line 26, in from_url
    return r.to_pdf(output_path)
  File "C:\Users\Diego\AppData\Local\Programs\Python\Python38-32\lib\site-packages\pdfkit\pdfkit.py", line 156, in to_pdf
    raise IOError('wkhtmltopdf reported an error:\n' + stderr)
OSError: wkhtmltopdf reported an error:
Loading pages (1/6)
Warning: Javascript alert: Hola
QPainter::begin(): Returned false============================] 100%
Error: Unable to write to destination
Exit with code 1, due to unknown error.

Relevant Code Snippet

pdfConf = pdfkit.configuration(wkhtmltopdf=os.path.join(
            self.__principalPath, "docs/web/PDF/wkhtmltopdf.exe"))

pdfOpti = {
            "window-status": "print",
            "dpi": "90",
            # "quiet": "",
            "page-size": "A4",
            "footer-html": f"{url}/footer.html"
        }
try:
            return "E" if pdfkit.from_url(
                url=f"{url}/document.html",
                output_path=outputPath,
                configuration=pdfConf,
                options=pdfOpti) else "F"
except:
            return "F"

Other

I searched on the internet and I found that the problem might be the destination path. But I am using the complete path: C:\Users\Diego\Desktop\JAA.pdf

Setup File

import sys
from cx_Freeze import setup, Executable

build_exe_options = {"packages": ["ctypes", "os", "wx", "json", "threading", "pdfkit"],
    "excludes": ["tkinter"]}

base = None
if sys.platform == "win32":
    base = "Win32GUI"

setup(name="App",
      version="0.1",
      description="",
      options={"build_exe": build_exe_options},
      executables=[Executable("main.py", base=base, icon="app.ico")])



diego
  • 23
  • 5
  • If you want some help, please at least add relevant parts of the code causing the error (e.g. the method `exportarHTMLaPDF`) to your question. – jpeg Apr 19 '21 at 11:27
  • 1
    Yes, It was my bad, I already added, sorry – diego Apr 21 '21 at 15:47
  • Looking at the source code of the `pdfkit` Python wrapper, it uses `subprocess`, and there are some known issues when using `subprocess` with `cx_Freeze`, see e.g. [this question](https://stackoverflow.com/q/24151539/8516269). Can you please share your setup script? Did you try setting `base=None` in the `Executable` call? – jpeg Apr 22 '21 at 19:02
  • @jpeg I tried to do it with `base=None` and do not work – diego Apr 22 '21 at 21:04

1 Answers1

0

The diagnosis you made is correct (after all, Error: Unable to write to destination is pretty straightforward).

If you can create the output file, but the created EXE file cannot - and we know it couldn't - then this means that either

  • the real destination path is not actually there when the EXE runs. You think you're writing to a given path, but somehow the EXE attempts to write elsewhere.
  • the EXE has no permissions to create the file.

This might be caused by several reasons. The EXE file, for security reasons, might output in a given directory, so when you ask for "C:\somefile", it actually tries to write in "%TEMP%/C:/somefile". Or might refuse to use a full path.

Or you could need to write the file in Unix syntax ("C:/Users/..." instead of "C:\Users...", because e.g. "\Diego" is translated to "0x0Diego" ("iego" with a carriage return prefixed).

You should therefore insert into the EXE file some code to explore the filesystem the EXE is seeing (which might not be the same one you see!), and/or try to write to a different path, perhaps indeed %TEMP% (where permissions should be sufficient).

LSerni
  • 55,617
  • 10
  • 65
  • 107
  • Thank you for your answer, The problem as I mention in the question is that when I run my code without convert in .EXE the wkhtmltopdf works perfectly, but when I convert it to .EXE wkhtmltopdf does not work, even though I tried to print the location of the output and program to find if path was the problem, but I get the exact paths as I assigned * C: \ Users \ Diego \ Desktop \ JAA.pdf * (output) * C: \ Users \ Diego \ Program \ * (program path). – diego Apr 21 '21 at 15:45
  • Okay. Next step is to try and create a file there, with that name, without using wkhtmltopdf - just open the file, write "hello world" and close. After that I'd try and check using PROCMON to see what's really going on, and what the actual error cause is (permissions, etc.). – LSerni Apr 21 '21 at 18:36
  • Other possibility: write to the file "ciccio.pdf" (no path whatsoever). If it does work, try creating a directory wherever the ciccio.pdf file is, call it "hello", then try to create "hello\world1.pdf" and "hello/world2.pdf". If one of them works, then directories are supported; then modify the path one component at a time until you find which component is causing trouble. – LSerni Apr 21 '21 at 18:40
  • I have just tried what you say but still not working, when I tried to create the "hello world" and "ciccio.pdf" file I get the exact same error – diego Apr 22 '21 at 20:58
  • Okay, so the problem is that **the program cannot create files**. The question is: why? Try now executing a program that tells you which effective user the program believes it is. A quick test is also to **run the program as Administrator**. If it works that way, then you need to tell `cx_freeze` to request permissions, or to not drop them in the first place. – LSerni Apr 23 '21 at 07:49
  • Hi @LSerni, sorry I have been so busy. Yes I try the program with **Administrator Privileges** but still not working :( – diego Apr 29 '21 at 00:14
  • @diego let's try to isolate whether it's a cx_freeze problem or not. Try first a simple cx_freeze'd script that just creates a file. Then try a script that runs a command that creates a file - e.g. `touch pippo.txt`. If both work, then it's something to do with wkhtmltopdf. If they don't, it's something with cx_freeze. – LSerni Apr 29 '21 at 07:02
  • Hello thank you for your help, I tried what you said about creating a file with a `cx_freeze` script and It works without any problem, but when I try with a simple script with wkhtmltopdf, it shows the same error – diego May 06 '21 at 00:15