问题
this is my very first question, so please forgive me, if I forgot something to mention or there's something wrong with it :)
I set up a python(3.5.3)-django(2.1.5) -project on IIS(10)-Windows Server. Everything works great.
Problem
Only wkhtmltopdf(0.12.5) has a strange behavior.
When I run it on localhost the command prompt gives me
Loading pages (1/6)
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
and I can find the generated .pdf-file in my downloads folder as expected.
When I change ALLOWED_HOSTS
to the Server's IP and I call the url to generate a pdf it says there is a
OSError at /pdf/
[WinError 6] The handle is invalid
with the Traceback:
File "C:\my_project\myenv\lib\site-packages\django\core\handlers\exception.py" in inner 34. response = get_response(request)
File "C:\my_project\myenv\lib\site-packages\django\core\handlers\base.py" in _get_response 156. response = self.process_exception_by_middleware(e, request)
File "C:\my_project\myenv\lib\site-packages\django\core\handlers\base.py" in _get_response 154. response = response.render()
File "C:\my_project\myenv\lib\site-packages\django\template\response.py" in render 106. self.content = self.rendered_content
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\views.py" in rendered_content 80. cover_template=self.resolve_template(self.cover_template)
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py" in render_pdf_from_template 237. cover_filename=cover.filename if cover else None)
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py" in convert_to_pdf 166. return wkhtmltopdf(pages=pages, **cmd_options)
File "C:\my_project\myenv\lib\site-packages\wkhtmltopdf\utils.py" in wkhtmltopdf 147. return check_output(ck_args, **ck_kwargs)
File "C:\Program Files\Python35\lib\subprocess.py" in check_output 316. **kwargs).stdout
File "C:\Program Files\Python35\lib\subprocess.py" in run 383. with Popen(*popenargs, **kwargs) as process:
File "C:\Program Files\Python35\lib\subprocess.py" in init 640. errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Program Files\Python35\lib\subprocess.py" in _get_handles 884. errwrite = _winapi.GetStdHandle(_winapi.STD_ERROR_HANDLE)
Exception Type: OSError at /pdf/ Exception Value: [WinError 6] Das Handle ist ungültig
I can see in C:\Users\myapplicationpool\AppData\Local\Temp
-folder that wkhtmltopdf is generating a .html-file called for example wkhtmltopdfgn1s7k5r.html
but somehow the progress gets stuck.
As mentioned here and here others had the same issue, too. But changing
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
process = Popen(stdout=PIPE, *popenargs, **kwargs)
to
if 'stdout' in kwargs:
raise ValueError('stdout argument not allowed, it will be overridden.')
kwargs.pop('stderr', None)
process = Popen(stdout=PIPE, stderr=PIPE, stdin=PIPE, *popenargs, **kwargs)
has no effect. I think this solution only works for the subprocess.py-file of Python 2.7 and I am using Python 3+ and functions of this file changed.
I gave full permissions for IUSR
& IIS_USRS
-users to the wkhtmltopdf-folder where bin-folder & wkhtmltopdf.exe lie as I read that this could help as well, but it doesn't.
Questions
Has anyone any other idea what I could try and help me please?
Does this issue really lie in the subprocesses of wkhtmltopdf & python or do I rather have to change/add handlers of my djangohandler of the FastCgiModule in IIS? How would I do so?
Why is it working when I run it on the server locally as localhost without any problems but not when I call the page via the server's IP? -- as mentioned: everything else works totally fine.
Setup
I added wkhtmltopdf to INSTALLED_APPS
and set it up like so:
settings.py
WKHTMLTOPDF_CMD = 'C:/wkhtmltopdf/bin/wkhtmltopdf'
(as I also read that there often is a problem due to spaces in paths when it is installed in 'Program Files'
.)
urls.py
path('pdf/', views.MyPDFView.as_view(), name='pdfview'),
views.py
from wkhtmltopdf.views import PDFTemplateResponse
class MyPDFView(View):
template_name='mypdfview.html'
def get(self, request):
response = PDFTemplateResponse(request=self.request,
template=self.template_name,
filename='hello' + '.pdf',
context=self.context,
show_content_in_browser=False,
cmd_options={
'margin-top': 50,
},
)
return response
mypdfview.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Hello World</title>
</head>
<body>
<h1>Some headline here.</h1>
</body>
</html>
Edit 1: Somehow my greeting disappeared - added it... Edit 2: It seems I am not allowed to say: "Hi everyone"!?
回答1:
To do the same workaround as proposed for python 2.7, you need to edit the wkhtmltopdf/utils.py file, method wkhtmltopdf()
:
from .subprocess import check_output, PIPE
...
def wkhtmltopdf(pages, output=None, **kwargs):
...
except (AttributeError, IOError):
# can't call fileno() on mod_wsgi stderr object
pass
# add this:
if not ck_kwargs.get('stderr'):
ck_kwargs['stderr'] = PIPE
return check_output(ck_args, **ck_kwargs)
来源:https://stackoverflow.com/questions/55259645/django-wkhtmltopdf-on-iis-winerror-6-the-handle-is-invalid