인쇄도중 windows와 상호작용을 멈추고 닫히는 경우

파이썬으로 인쇄 자동화를 구현하려고 합니다.

hwp.HAction.Execute(“Print”, hwp.HParameterSet.HPrint.HSet)의 실행에서

'인쇄중’까지 열린 후 다음과 같은 경고창이 뜹니다. .
image

윈도우로그를 확인해보니
‘hwp.exe가 Windows와의 상호 작용을 중지하고 닫혔다고 나오네요.’
어떻게 해결해야할까요? 도움을 부탁드립니다

안녕하세요 ^^
혹시 GetDefault를 통해 set의 기본값을 가져오셨을까요 …?
아래는 스크립트로 프린트 액션을 호출하는 샘플 코드입니다.
Set값이 부족하거나 잘못들어가면 오류가 발생할수도 있습니다.

	HAction.GetDefault("Print", HParameterSet.HPrint.HSet);
	with (HParameterSet.HPrint)
	{
		Collate = 1;
		UserOrder = 0;
		PrintToFile = 0;
		UsingPagenum = 1;
		ReverseOrder = 0;
		Pause = 0;
		PrintImage = 1;
		PrintDrawObj = 1;
		PrintClickHere = 0;
		PrintAutoFootnoteLtext = "^f";
		PrintAutoFootnoteCtext = "^t";
		PrintAutoFootnoteRtext = "^P쪽 중 ^p쪽";
		PrintAutoHeadnoteLtext = "^c";
		PrintAutoHeadnoteCtext = "^n";
		PrintAutoHeadnoteRtext = "^p";
		PrintFormObj = 1;
		PrintMarkPen = 0;
		PrintMemo = 0;
		PrintMemoContents = 0;
		PrintRevision = 1;
		PrintBarcode = 1;
		Device = PrintDevice("Printer");
		PrintPronounce = 0;
	}
	HAction.Execute("Print", HParameterSet.HPrint.HSet);

한글 매크로 내의 해당부분을 잘 입력했다고 생각했는데 틀린 부분이 있을지도 모르겠습니다.
해당 코드입니다.

            for file_path in self.file_paths:
                print(file_path)
                self.hwp.Open(file_path)

                self.hwp.HAction.GetDefault("Print", self.hwp.HParameterSet.HPrint.HSet)
                hwp_print = self.hwp.HParameterSet.HPrint
                hwp_print.Collate = 1
                hwp_print.UserOrder = 0
                hwp_print.PrintToFile = 0
                hwp_print.NumCopy = copies
                hwp_print.PrinterName = f"{printer}"
                hwp_print.UsingPagenum = 1
                hwp_print.ReverseOrder = 0
                hwp_print.Pause = 0
                hwp_print.PrintImage = 1
                hwp_print.PrintDrawObj = 1
                hwp_print.PrintClickHere = 0
                hwp_print.PrintAutoFootnoteLtext = "^f"
                hwp_print.PrintAutoFootnoteCtext = "^t"
                hwp_print.PrintAutoFootnoteRtext = "^P쪽 중 ^p쪽"
                hwp_print.PrintAutoHeadnoteLtext = "^c"
                hwp_print.PrintAutoHeadnoteCtext = "^n"
                hwp_print.PrintAutoHeadnoteRtext = "^p"
                hwp_print.PrintFormObj = 1
                hwp_print.PrintMarkPen = 0
                hwp_print.PrintMemo = 0
                hwp_print.PrintMemoContents = 0
                hwp_print.PrintRevision = 1
                hwp_print.PrintBarcode = 1
                #hwp_print.Device = PrintDevice("printer")
                hwp_print.PrintPronounce = 0
                
                # hwp_print.Device = 0


                if paper_option == '공급 용지 인쇄':
                    hwp_print.PrintMethod = 1

                self.hwp.HAction.Execute("Print", self.hwp.HParameterSet.HPrint.HSet)
                
                self.hwp.Run("FileClose")

안녕하세요.

해당 에러는 원인이 다양할 수 있어서 에러 메세지에 대한 로그 파일을 받으면 답변하는데 도움을 드릴 수 있을 것 같습니다.
로그를 수집하기 위해 아래와 같은 설정 파일을 변경한 후에 로그 파일의 내용을 코멘트로 남겨주세요.

1. %appdata%\HNC\User\Common\110\optionInfo.xml파일에서 
EnableExceptionLog value="0" 값을 1로 변경
- `110` 디렉토리 경로는 현재 사용중인 한글 버전에 따라 다를 수 있습니다.
2. 파이썬 스크립트 실행
3. 에러 발생하면 %appdata%\HNC\Log\Hwp 경로에 생성된 ExceptionLog 파일 확인

감사합니다.

.NET CLR TotalMemory : 15724372 Bytes
Gen0 Count : 13
Gen1 Count : 6
Gen2 Count : 2
Virtual Memory Size : 753640 KBytes
Working Set Size : 94488 KBytes

System.Reflection.TargetInvocationException: 호출 대상이 예외를 Throw했습니다. ---> System.DivideByZeroException: 0으로 나누려 했습니다.
   위치: XControl.XControlDialogImpl.Invoke(String stringID, String method, HncParameterSet args, HncParameterSet result)
   위치: Hwp.XControl.DialogHelper.Invoke(String method, HncParameterSet& args, HncParameterSet& result)
   위치: Hwp.XControl.Dialog.InvokeFunc(String id, String method, HncParameterSet args, HncParameterSet result)
   위치: Hwp.XControl.Dialog._Invoke(String id, String method, HncParameterSet& args, HncParameterSet& result)
   위치: Hwp.XControl.Dialog.OnMessage(Message message)
   --- 내부 예외 스택 추적의 끝 ---
   위치: System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
   위치: System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
   위치: System.Delegate.DynamicInvokeImpl(Object[] args)
   위치: System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   위치: System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
.NET CLR TotalMemory : 15648296 Bytes
Gen0 Count : 15
Gen1 Count : 8
Gen2 Count : 4
Virtual Memory Size : 764540 KBytes
Working Set Size : 96580 KBytes

System.NullReferenceException: 개체 참조가 개체의 인스턴스로 설정되지 않았습니다.
   위치: Hwp.XControl.Dialog.PreTranslateMessage(Int32 msg, IntPtr wParam, IntPtr lParam)
   위치: Hwp.XControl.Dialog.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   위치: System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   위치: MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   위치: MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   위치: System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   위치: System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

노고에 감사의 말씀드립니다.

안녕하세요.

남겨주신 로그는 오동작이 발생하는 위치는 확인했습니다.
그래도 내부에서 재현이 안되어 몇 가지 추가 확인 요청 드립니다. :joy:

1. 사용 중인 한글 버전
한글 타이틀바 "?" 선택 > 한글 정보

2. 현재 작성한 코드가 서브 스레드에서 동작하는지 여부
만일 서브 스레드에서 동작시킨다면 메인 스레드로 동작시켜서 확인 필요

3. 복수의 파일에 대해 인쇄하는 동작인데 단일 파일에 대해서도 동일하게 에러가 발생하는지 여부

4. self.hwp.Run("FileClose") -> self.hwp.Clear(1) 변경 후에도 재현되는지 여부

빠르게 도움드리지 못해 죄송합니다. :sob:
감사합니다.

  1. 한글 버전은 11.0.0.8362 입니다.
    2.메인 스레드로 작동합니다.
    3.단일파일에 대해서도 동일하게 에러가 발생합니다.
  2. self.hwp.Clear(1)로 변경해도 동일하게 재현됩니다.
import os
import sys
import win32com.client as win32
import win32print
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QFileDialog, QComboBox, QLabel, QSpinBox

class HWPPrinter(QWidget):
    def __init__(self):
        super().__init__()
        self.hwp = win32.gencache.EnsureDispatch('Hwpframe.Hwpobject')
        self.init_ui()

    def init_ui(self):
        self.setWindowTitle('한글 프린터')
        self.setGeometry(100, 100, 400, 150)

        layout = QVBoxLayout()

        # 파일 선택
        file_layout = QHBoxLayout()
        self.file_label = QLabel('파일 선택')
        self.file_button = QPushButton('파일 선택')
        self.file_button.clicked.connect(self.select_files)
        file_layout.addWidget(self.file_label)
        file_layout.addWidget(self.file_button)
        layout.addLayout(file_layout)

        # 프린터 선택
        printer_layout = QHBoxLayout()
        self.printer_label = QLabel('프린터 선택')
        self.printer_combo = QComboBox()
        printers = win32print.EnumPrinters(win32print.PRINTER_ENUM_LOCAL)
        for printer in printers:
            self.printer_combo.addItem(printer[2])
        printer_layout.addWidget(self.printer_label)
        printer_layout.addWidget(self.printer_combo)
        layout.addLayout(printer_layout)

        # 용지 선택
        paper_layout = QHBoxLayout()
        self.paper_label = QLabel('출력 용지')
        self.paper_combo = QComboBox()
        self.paper_combo.addItem('자동 인쇄')
        self.paper_combo.addItem('공급 용지 인쇄')
        paper_layout.addWidget(self.paper_label)
        paper_layout.addWidget(self.paper_combo)
        layout.addLayout(paper_layout)

        # 인쇄 매수 선택
        copies_layout = QHBoxLayout()
        self.copies_label = QLabel('인쇄 매수')
        self.copies_spin = QSpinBox()
        self.copies_spin.setMinimum(1)
        self.copies_spin.setMaximum(100)
        copies_layout.addWidget(self.copies_label)
        copies_layout.addWidget(self.copies_spin)
        layout.addLayout(copies_layout)

        # 인쇄 버튼
        self.print_button = QPushButton('인쇄')
        self.print_button.clicked.connect(self.print_files)
        layout.addWidget(self.print_button)

        self.setLayout(layout)

    def select_files(self):
        # 현재 파일의 절대 경로 가져오기
        current_dir = os.path.dirname(os.path.abspath(sys.argv[0]))

        file_dialog = QFileDialog()
        file_dialog.setDirectory(current_dir)
        file_dialog.setFileMode(QFileDialog.ExistingFiles)
        file_dialog.setNameFilter('HWP Files (*.hwp)')
        if file_dialog.exec_():
            selected_files = file_dialog.selectedFiles()
            self.file_paths = [os.path.normpath(file_path) for file_path in selected_files]

    def print_files(self):
        if not self.file_paths:
            return

        printer = self.printer_combo.currentText()
        paper_option = self.paper_combo.currentText()
        copies = self.copies_spin.value()

        try:
            # 한글 프로그램 백그라운드 실행
            self.hwp.XHwpWindows.Item(0).Visible = False

            # 보안 모듈 실행 뜨지 않도록 하기
            self.hwp.RegisterModule('FilePathCheckDLL', 'FilePathCheckerModule')

            for file_path in self.file_paths:
                print(file_path)
                self.hwp.Open(file_path)

                self.hwp.HAction.GetDefault("Print", self.hwp.HParameterSet.HPrint.HSet)
                hwp_print = self.hwp.HParameterSet.HPrint
                hwp_print.Collate = 1
                hwp_print.UserOrder = 0
                hwp_print.PrintToFile = 0
                hwp_print.NumCopy = copies
                hwp_print.PrinterName = f"{printer}"
                hwp_print.UsingPagenum = 1
                hwp_print.ReverseOrder = 0
                hwp_print.Pause = 0
                hwp_print.PrintImage = 1
                hwp_print.PrintDrawObj = 1
                hwp_print.PrintClickHere = 0
                hwp_print.PrintAutoFootnoteLtext = "^f"
                hwp_print.PrintAutoFootnoteCtext = "^t"
                hwp_print.PrintAutoFootnoteRtext = "^P쪽 중 ^p쪽"
                hwp_print.PrintAutoHeadnoteLtext = "^c"
                hwp_print.PrintAutoHeadnoteCtext = "^n"
                hwp_print.PrintAutoHeadnoteRtext = "^p"
                hwp_print.PrintFormObj = 1
                hwp_print.PrintMarkPen = 0
                hwp_print.PrintMemo = 0
                hwp_print.PrintMemoContents = 0
                hwp_print.PrintRevision = 1
                hwp_print.PrintBarcode = 1
                #hwp_print.Device = hwp_print.PrintDevice("printer")
                hwp_print.PrintPronounce = 0
                
                hwp_print.Device = 0


                if paper_option == '공급 용지 인쇄':
                    hwp_print.PrintMethod = 1

                self.hwp.HAction.Execute("Print", self.hwp.HParameterSet.HPrint.HSet)
                
                self.hwp.Clear(1)

            self.hwp.Quit()

        except Exception as e:
            print(f"오류 발생: {e}")

if __name__ == '__main__':
    app = QApplication([])
    printer = HWPPrinter()
    printer.show()
    app.exec_()

코드 전문 첨부하였습니다.

안녕하세요 ^^
확인해보니 파이썬환경에서 한글 오토메이션 오브젝트가 다르게 동작하는 부분 확인했습니다.
파이썬에서 “self.hwp.HParameterSet.HPrint.HSet” 와 같이 HParameterSet을 이용해 HSet을 생성시 매번 새로운 주소의 Set값이 생성이 되고있습니다.
해당 방법을 이용해서는 원하시는대로 동작이 어려울것 같습니다.

아래와같은 방식으로 action과 set을 이용해야할것 같습니다.
감사합니다.

act = hwp.CreateAction("Print");
set = act.CreateSet();
act.GetDefault(set);
set.SetItem("Collate", 1);
set.SetItem("UserOrder",0);
....
act.Execute(set):
3개의 좋아요

주신 피드백으로 적용해보니 해결되었습니다. 감사합니다.

1개의 좋아요