오류 해결 과정

캐시 생성 에러 (module 'win32com.gen_py.7D2B6F3C-1D95-4E0C-BF5A-5EE564186FBCx0x1x0' has no attribute 'CLSIDToClassMap')

필만이 2024. 8. 22. 18:44

배경

  • 프로토타입 완성후 테스트를 며칠하고 있는데 오류발생

  • 오류 내용

    AttributeError: module 'win32com.gen_py.7D2B6F3C-1D95-4E0C-BF5A-5EE564186FBCx0x1x0' has no attribute 'CLSIDToClassMap'
  • 어제됐던 똑같은 코드로 오늘 했는데 실패한게 놀라움

해결과정

  1. GPT 검색 결과 gen_py 캐시 폴더의 손상으로 인해 발생한 것이라는 의견
  2. C:\Users\makenow\AppData\Local\Temp\gen_py 경로의 캐시 폴더(gen_py)를 수동으로 삭제해봄
  3. 삭제후 코드에서 캐시를 재생성하니 정상작동
  4. 이 과정을 자동화할 필요를 느끼고, 코드 초기에 캐시에 이상이 있으면 삭제하고 재생성하는 함수를 만듦
def ensure_hwp_dispatch():
    try:
        # COM 객체를 생성하려고 시도합니다.
        # 이 때, 'HWPFrame.HwpObject'라는 COM 서버를 불러옵니다.
        # EnsureDispatch는 COM 객체가 존재하지 않으면 자동으로 생성하고, 존재하면 해당 객체를 반환합니다.
        hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
        return hwp  # 성공적으로 COM 객체를 생성하면 이를 반환합니다.
    except AttributeError as e:
        # AttributeError 예외가 발생하면, 이는 주로 gen_py 캐시가 손상된 경우에 발생합니다.
        # 이 경우 캐시를 재생성해야 합니다.
        logging.warning("AttributeError detected: %s. Rebuilding cache...", str(e))

        # 캐시 폴더 경로를 가져옵니다.
        # 일반적으로 캐시는 'C:\Users\{사용자명}\AppData\Local\Temp\gen_py' 폴더에 저장됩니다.
        cache_dir = os.path.join(os.environ['LOCALAPPDATA'], 'Temp', 'gen_py')

        # 캐시 폴더가 존재하는지 확인한 후, 존재하면 폴더를 삭제합니다.
        # 이를 통해 손상된 캐시 파일을 제거합니다.
        if os.path.exists(cache_dir):
            shutil.rmtree(cache_dir)  # 캐시 폴더 및 하위 디렉터리를 삭제합니다.
            logging.info("Deleted gen_py cache directory: %s", cache_dir)

        # pywin32 모듈의 gencache를 사용하여 캐시를 다시 생성합니다.
        # is_readonly를 False로 설정하여 캐시의 읽기 전용 속성을 해제한 후, Rebuild()를 호출하여 캐시를 재생성합니다.
        win32.gencache.is_readonly = False
        win32.gencache.Rebuild()

        # 캐시를 재생성한 후, 다시 COM 객체를 생성하려고 시도합니다.
        try:
            hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
            logging.info("Successfully created COM object after cache rebuild.")
            return hwp  # 성공적으로 COM 객체를 생성하면 이를 반환합니다.
        except Exception as e2:
            # 캐시를 재생성한 후에도 COM 객체 생성에 실패하면, 예외를 로깅하고 다시 발생시킵니다.
            logging.error("Failed to create COM object after cache rebuild: %s", str(e2))
            raise  # 예외를 다시 발생시켜 문제를 상위 코드로 전달합니다.

# HWPFrame.HwpObject의 COM 객체를 얻음
hwp = ensure_hwp_dispatch()