enthought / enthought/comtypes
Getting "NULL COM pointer access" when script calls from windows service
- Dominant language
- Python
- Stars
- 345
- Forks
- 105
- PR merge metrics
- No merged PRs in 30d
Description
I'm trying to make a RPC service for calling my script which used **comtypes** package to create a pdf file from docx.
When I call my script on the command line prompt I have no any problem, but when I make calling from windows service I get this error from the output:
This is my script:
```python
import sys
import json
import subprocess
from pathlib import Path
import os
# from ctypes import windll
# SYS Import Local Packages Installed
path = os.path.realpath(os.path.abspath(__file__))
sys.path.insert(0, os.path.dirname(os.path.dirname(path)))
sys.path.append(os.path.join(os.path.dirname(__file__),"."))
sys.path.append(os.path.join(os.path.dirname(__file__),"packages"))
# from packages import comtypes
from packages.comtypes import client
# COINIT_MULTITHREADED = 0x0
try:
# 3.8+
from importlib.metadata import version
except ImportError:
from importlib_metadata import version
def windows(paths, keep_active):
# word = win32com.client.Dispatch("Word.Application")
# windll.ole32.CoInitializeEx(None, COINIT_MULTITHREADED)
word = client.CreateObject("Word.Application")
wdFormatPDF = 17
if paths["batch"]:
docx_files = sorted(Path(paths["input"]).glob("*.docx") or Path(paths["input"]).glob("*.doc"))
for i, docx_filepath in enumerate(docx_files):
pdf_filepath = Path(paths["output"]) / (str(docx_filepath.stem) + ".pdf")
print(f"Converting {docx_filepath} to {pdf_filepath} ({i+1}/{len(docx_files)})")
doc = word.Documents.Open(str(docx_filepath))
doc.SaveAs(str(pdf_filepath), FileFormat=wdFormatPDF)
doc.Close(0)
else:
docx_filepath = Path(paths["input"]).resolve()
pdf_filepath = Path(paths["output"]).resolve()
print(f"Converting {docx_filepath} to {pdf_filepath}")
doc = word.Documents.Open(str(docx_filepath))
doc.SaveAs(str(pdf_filepath), FileFormat=wdFormatPDF)
doc.Close(0)
if not keep_active:
word.Quit()
# comtypes.CoUninitialize()
def resolve_paths(input_path, output_path):
input_path = Path(input_path).resolve()
output_path = Path(output_path).resolve() if output_path else None
output = {}
if input_path.is_dir():
output["batch"] = True
output["input"] = str(input_path)
if output_path:
assert output_path.is_dir()
else:
output_path = str(input_path)
output["output"] = output_path
else:
output["batch"] = False
assert str(input_path).endswith(".docx") or str(input_path).endswith(".doc")
output["input"] = str(input_path)
if output_path and output_path.is_dir():
output_path = str(output_path / (str(input_path.stem) + ".pdf"))
elif output_path:
assert str(output_path).endswith(".pdf")
else:
output_path = str(input_path.parent / (str(input_path.stem) + ".pdf"))
output["output"] = output_path
return output
def convert(input_path, output_path=None, keep_active=False):
paths = resolve_paths(input_path, output_path)
windows(paths, keep_active)
def cli():
import textwrap
import argparse
description = textwrap.dedent(
"""
Example Usage:
Convert single docx file in-place from myfile.docx to myfile.pdf:
docx2pdf myfile.docx
Batch convert docx folder in-place. Output PDFs will go in the same folder:
docx2pdf myfolder/
Convert single docx file with explicit output filepath:
docx2pdf input.docx output.docx
Convert single docx file and output to a different explicit folder:
docx2pdf input.docx output_dir/
Batch convert docx folder. Output PDFs will go to a different explicit folder:
docx2pdf input_dir/ output_dir/
"""
)
formatter_class = lambda prog: argparse.RawDescriptionHelpFormatter(
prog, max_help_position=32
)
parser = argparse.ArgumentParser(
description=description, formatter_class=formatter_class
)
parser.add_argument(
"input",
help="input file or folder. batch converts entire folder or convert single file",
)
parser.add_argument("output", nargs="?", help="output file or folder")
parser.add_argument(
"--keep-active",
action="store_true",
default=False,
help="prevent closing word after conversion",
)
if len(sys.argv) == 1:
parser.print_help()
sys.exit(0)
else:
args = parser.parse_args()
convert(args.input, args.output, args.keep_active)
if __name__ == "__main__":
cli()
```
I call my script with this:
```python .\\w2PDF .\\word.docx .\\word.pdf```
I get this on windows service output:
```Traceback (most recent call last):\r\n File \"\", line 198, in _run_module_as_main\r\n File \"\", line 88, in _run_code\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\__main__.py\", line 3, in \r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\Word2PDF_Python.py\", line 127, in cli\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\Word2PDF_Python.py\", line 76, in convert\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\Word2PDF_Python.py\", line 41, in windows\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\packages\\comtypes\\_meta.py\", line 14, in _wrap_coclass\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\packages\\comtypes\\_post_coinit\\unknwn.py\", line 520, in QueryInterface\r\nValueError: NULL COM pointer access```
I couldn't find the problem, When I change the user log on to `Network Service` or `Local Service` above error changes to access is denied :
```Traceback (most recent call last):\r\n File \"\", line 198, in _run_module_as_main\r\n File \"\", line 88, in _run_code\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\__main__.py\", line 3, in \r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\Word2PDF_Python.py\", line 127, in cli\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\Word2PDF_Python.py\", line 76, in convert\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\Word2PDF_Python.py\", line 26, in windows\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\packages\\comtypes\\client\\__init__.py\", line 273, in CreateObject\r\n File \"D:\\Word2PDF-Service\\WindowsService1\\bin\\Debug\\Word2PDF\\packages\\comtypes\\_post_coinit\\misc.py\", line 149, in CoCreateInstance\r\n File \"_ctypes/callproc.c\", line 1008, in GetResult\r\nPermissionError: [WinError -2147024891] Access is denied```
Contributor guide
Assessment
This issue has not been assessed yet.