ActiveX / OCX를 지금 어떻게 다룰 것인가 - 남길지・감쌀지・교체할지 판단표

· 업데이트: · · COM, ActiveX, OCX, .NET, Windows 개발, 모더나이제이션

수정 이력(3건, 최종 수정 2026년 09월 03일)

이 글에 적용한 변경 사항의 기록입니다. 보관해 둔 수정 전 버전은 DOI가 부여된 고정 URL에서 읽을 수 있습니다.

한국어 전면 재작성에 맞춰 본문 표현을 바로잡았습니다. 기술적인 주장은 일본어판과 같습니다.
일본어 원문의 완역으로 다시 번역했습니다. 기존 한국어판은 원문의 일부만 옮긴 축약본이라 절, 표, Mermaid 그림, 그림 설명, FAQ가 빠져 있었습니다. 일본어 원문에 맞춰 이들을 모두 복원했고, 기술적인 주장은 일본어판과 같습니다. 수정 전 버전 보기 (DOI: 10.5281/zenodo.22170274)
자체 헬퍼 EXE를 만들기 전에 먼저 검토할 선택지로 5.2에 DllSurrogate를 추가했습니다. 대상이 in-proc COM 서버라면 CLSID에 AppID를 붙이고 그 AppID 키에 빈 문자열의 DllSurrogate를 쓰는 것만으로, 이쪽 코드를 한 줄도 쓰지 않고 out-of-proc으로 만들 수 있습니다. 다만 서로게이트가 bitness 차이를 없애 주는 것은 아니며, 사라지는 것은 같은 프로세스에 올려야 한다는 제약뿐이고 호출은 out-of-proc이 되어 마샬링과 프로세스 간 통신 비용이 그대로 붙습니다. 서로게이트로 충분한 경우와 자체 헬퍼 EXE가 필요한 경우의 경계를 표로 정리했고, 참고 자료도 두 건 추가했습니다. 등록 절차 자체는 다른 글에 있으므로 여기서는 링크만 두었습니다. 수정 전 버전 보기 (DOI: 10.5281/zenodo.21635117)
최초 공개
이 글을 인용하기(DOI: 10.5281/zenodo.21635116)

이 글은 Zenodo에 보관되어 있습니다. 항상 최신 버전으로 연결되는 DOI와 지금 보고 있는 버전에 고정된 DOI를 아래에 함께 제시합니다.

小村 豪 (2026). 「ActiveX / OCX를 지금 어떻게 다룰 것인가 - 남길지・감쌀지・교체할지 판단표」. 합동회사 코무라소프트. https://doi.org/10.5281/zenodo.21635116 https://comcomponent.com/ko/blog/activex-ocx-keep-wrap-replace-decision-table/

DOI(최신 버전)
10.5281/zenodo.21635116
DOI(이 버전)
10.5281/zenodo.22217425

ActiveX / OCX라는 말이 나오는 안건은 대개 분위기가 조금 무겁습니다.

  • VB6이나 오래된 C++ / MFC 앱이 아직 현역
  • 산업 기기나 계측기의 SDK가 OCX만 내놓고 있다
  • 사내 Web이 ActiveX 전제라 IE 모드에서 빠져나오지 못한다
  • 32bit에서 64bit로 옮기고 싶은데 OCX 하나가 고개를 젓고 있다

다만 여기서 「오래됐으니 전부 버린다」도 「돌아가고 있으니 영구 보존」도 둘 다 거칠습니다. 중요한 것은 그 ActiveX / OCX가 단순한 UI 부품인지, 아니면 업무 사양이나 기기 사양을 안고 있는 경계면인지를 가려내는 것입니다.

이 글에서는 ActiveX / OCX를 만났을 때, 남길지・감쌀지・교체할지 가운데 무엇을 고를지를 판단하기 쉬운 순서로 정리합니다.

대상은 예를 들어 이런 경우입니다.

  • VB6 / MFC / WinForms 계열의 기존 데스크톱 앱
  • C# / .NET으로의 단계적 이행
  • WebBrowser / IE 모드를 포함하는 레거시 화면
  • 벤더제 ActiveX 컨트롤을 포함하는 Windows 앱

목차

  1. 먼저 결론(한 마디로)
  2. 이 글에서 말하는 ActiveX / OCX
  3. 먼저 볼 판단표
    • 3.1. 전체 그림
    • 3.2. 남기는 판단
    • 3.3. 감싸는 판단
    • 3.4. 교체하는 판단
    • 3.5. 브라우저 의존은 별도로 본다
  4. 판단을 흔들기 쉬운 논점
    • 4.1. UI 부품인가, 사양을 안은 부품인가
    • 4.2. 32bit / 64bit와 프로세스 경계
    • 4.3. 등록, 배포, 권한, 라이선스
    • 4.4. STA / 메시지 루프 / 콜백
    • 4.5. 테스트가 있는가, 관측할 수 있는가
  5. 전형 패턴별 추천
    • 5.1. 지금도 안정적으로 돌아가는 사내 데스크톱 앱
    • 5.2. 32bit OCX를 64bit 측으로 가져가고 싶다
    • 5.3. IE / WebBrowser 전제의 화면
    • 5.4. 기기 제어나 독자 사양을 안은 ActiveX
  6. 흔한 안티패턴
  7. 이행을 시작할 때의 체크리스트
  8. 대략적인 구분
  9. 정리
  10. 이런 상담은 궁합이 좋다
  11. 참고 자료

이 글의 지식 맵

ActiveX는 실무에서 COM 기반 컨트롤과 그 주변 자산을 가리키는 말로 쓰이고, OCX는 그 실체를 담은 파일입니다. in-proc로 동작하는 OCX는 호스트 프로세스와 비트 구성(32bit/64bit)을 맞춰야 하며, 이 제약을 넘으려면 COM LocalServer 같은 별도 프로세스화로 bitness의 벽을 피합니다. 브라우저 쪽에서는 Microsoft Edge 본체가 ActiveX를 지원하지 않고, WebView2도 ActiveX 의존이나 IE DOM 전제의 스크립트를 그대로 이어받을 수 없으므로, IE 모드가 연명책으로 자리매김됩니다. 감싸기 위한 수단으로는 AxHost와 Aximp에 의한 Windows Forms 호스트화, Reg-Free COM에 의한 레지스트리 등록 없는 해결, regsvr32에 의한 OCX 등록이 있으며, 어느 쪽이든 CLSID·ProgID·Type Library라는 식별자와 타입 정보를 전제로 합니다.

ActiveX/OCX의 존속·래핑·교체 판단ActiveX와 OCX가 COM을 토대로 하는 것, bitness 불일치라는 제약과 별도 프로세스화를 통한 회피, 브라우저 의존(Edge·IE 모드·WebBrowser·WebView2)의 비호환 관계, 감싸는 수단(AxHost/Aximp/Reg-Free COM/LocalServer)이 CLSID나 ProgID, Type Library와 어떻게 연결되는지를 보여주는 그림.이용한다구현을 담당한다전제로 한다전제로 한다완화한다이용한다이용한다구현을 담당한다전제로 한다전제로 한다전제로 한다전제로 한다전제로 한다전제로 한다양립하지 않는다이용한다이용한다양립하지 않는다의 후속전제로 한다전제로 한다에서 구성할 수 있다이용한다전제로 한다ActiveXOCXCOM(컴포넌트 오브젝트 모델)COM 아파트먼트 모델(STA/MTA)비트수 일치 요건COM LocalServer(별도 프로세스 COM 서버)AxImp(ActiveX Control Importer)AxHostWindows FormsCLSID(Class ID)ProgID(Programmatic Identifier)Visual Basic 6.0(VB6)타입 라이브러리(TLB)IE 모드Microsoft EdgeWebBrowser 컨트롤Microsoft Edge WebView2Reg-Free COM(등록 불필요 COM)regsvr32MFC(Microsoft Foundation Classes)WebView2 Runtime

그림의 실선은 항상 성립하는 관계, 점선은 조건이 붙는 관계입니다(성립 조건은 상세 페이지의 관계별 설명에 적혀 있습니다). 관계 전체 목록(총 24건, 근거와 확신도 포함)과 주요 개념의 정의는 지식 맵 상세 페이지에 정리되어 있습니다(일본어). 데이터: JSON-LD / Turtle

1. 먼저 결론(한 마디로)

  • ActiveX / OCX를 보면, 먼저 판단할 것은 「오래됐는지」가 아니라 그 부품이 무엇을 떠맡고 있는가입니다
  • 단순한 UI 부품이라면 교체는 비교적 수월합니다
  • 기기 제어, 장표, 독자 파일 형식, 오랜 운용 습관을 안고 있다면, 갑자기 재구현하기보다 먼저 감싸는 편이 안전합니다
  • 데스크톱에서 안정적으로 돌아가고 변경 범위가 작다면, 남기는 판단도 충분히 가능합니다
  • 브라우저 위의 ActiveX 의존은 연명은 되어도 앞날이 가늘므로, 교체 우선으로 보는 편이 좋습니다
  • 32bit OCX를 64bit 프로세스에 그대로 로드할 수는 없습니다. 여기는 기합으로는 넘을 수 없습니다
  • 등록, 의존 DLL, 관리자 권한, 라이선스, STA / MTA처럼 구현 이외의 마찰이 난관이 되기 쉽습니다
  • 「일단 전면 리라이트」와 「무서우니까 영구 동결」은 둘 다 사고율이 높습니다

요컨대 판단의 순서는 이렇습니다.

  1. 그 OCX는 무엇을 가지고 있는가
  2. 동일 프로세스에서 쓸 필요가 있는가
  3. 32bit / 64bit, 등록, 브라우저 의존으로 막히지 않는가
  4. 테스트 가능한 경계를 만든 뒤에 교체해야 하는가

이 순서로 보면 상당히 정리하기 쉬워집니다.

판단의 순서그 OCX가 무엇을 가지고 있는지, 동일 프로세스에서 쓸 필요가 있는지, 32bit/64bit나 등록이나 브라우저 의존으로 막히지 않는지, 테스트 가능한 경계를 만든 뒤에 교체해야 하는지의 순서로 본다.그 OCX는 무엇을 가지고 있는가동일 프로세스가 필요한가bitness·등록·브라우저로 막히는가경계를 만든 뒤에 교체하는가

그림1: 「오래됐는지」가 아니라, 이 순서로 보면 남길지·감쌀지·교체할지가 정리하기 쉽다.

2. 이 글에서 말하는 ActiveX / OCX

먼저 이 글에서의 말 쓰임을 잡아 두겠습니다.

이 글에서의 의미
COM Windows의 바이너리 호환 컴포넌트 모델. 공개 인터페이스, 등록, Apartment Model 등의 바탕입니다
ActiveX / OCX 실무에서는 COM 기반 컨트롤과 그 주변 자산을 한데 묶어 가리키는 경우가 많습니다. 특히 .ocx의 UI 컨트롤이나 IE / 컨테이너에 넣는 부품을 포함하는 일이 많습니다
WebBrowser / IE 계열 의존 ActiveX 그 자체가 아니더라도 「IE의 세계관」을 전제로 한 임베드 브라우저나 연동을 포함합니다. 판단상으로는 꽤 가까운 문제가 됩니다

엄밀히는 ActiveX와 COM은 같은 것이 아닙니다. 다만 실무에서 막히는 지점은 꽤 닮아 있습니다.

  • 32bit / 64bit가 맞물리는가
  • 등록이나 의존 DLL을 어떻게 배포하는가
  • 어느 호스트 / 컨테이너에서 동작하는가
  • STA, 메시지 루프, 콜백에서 막히지 않는가
  • 브라우저 의존이 남아 있지 않은가

이 글에서는 이런 실무상의 판단 포인트를 한데 다룹니다.

실무에서 막히는 지점엄밀히는 ActiveX와 COM은 같은 것이 아니지만, bitness의 맞물림, 등록이나 의존 DLL의 배포, 어느 호스트에서 동작하는지, STA나 콜백의 전제, 브라우저 의존이라는 실무에서 막히는 지점은 꽤 닮아 있다.ActiveX / OCX 안건bitness가 맞물리는가등록·의존 DLL의 배포어느 호스트에서 동작하는가STA·콜백의 전제브라우저 의존이 남아 있지 않은가

그림2: ActiveX와 COM은 엄밀히는 별개여도, 실무에서 막히는 지점은 이 근처에 모인다.

이어서 앞으로 당연하다는 듯이 나오는 약어를 먼저 모아 둡니다. 7장의 체크리스트에서 「ProgID와 CLSID를 뽑아낸다」고 해도, 거기가 비면 움직이지 못하기 때문입니다.

용어 읽기·정식명 의미
CLSID Class ID COM 컴포넌트의 구현(클래스)을 유일하게 가리키는 GUID. 레지스트리 등록도 이 값이 열쇠가 됩니다
ProgID Programmatic Identifier CLSID에 붙인, 사람이 읽을 수 있는 이름. Excel.Application 같은 문자열입니다
IID Interface ID COM 인터페이스를 유일하게 가리키는 GUID. CLSID와는 별개입니다
TLB Type Library 인터페이스, 메서드, 인자의 형 같은 형식 정보를 바이너리로 가진 파일. VB6이나 .NET에서 「형 정보를 붙여」 호출할 수 있는 것은 이것이 있기 때문입니다
RegAsm Assembly Registration Tool .NET Framework 부속 도구. .NET 어셈블리를 COM에서 쓸 수 있도록 레지스트리에 등록합니다
AxHost Windows Forms 위에서 ActiveX 컨트롤을 호스트하기 위한 기반 클래스입니다
AxImp ActiveX Control Importer OCX에서 Windows Forms용 래퍼 어셈블리를 생성하는 도구입니다
in-proc / out-of-proc 프로세스 내 / 프로세스 외 호출원과 같은 프로세스에서 동작하는지(DLL이나 OCX), 별도 프로세스에서 동작하는지(EXE 서버)
LocalServer COM 서버를 EXE로 별도 프로세스에서 돌리는 형태. bitness 벽을 넘거나 크래시를 격리할 수 있습니다
Reg-Free COM / side-by-side 등록 불필요 COM 레지스트리 등록 없이, 앱 측 매니페스트에 적은 정보로 COM을 해결하는 구조입니다
design-time / runtime 라이선스 개발 시 / 실행 시 벤더제 컨트롤에서, 개발 기기에 화면을 붙일 때와 배포처에서 실행할 때 라이선스 취급이 나뉘어 있는 경우가 있습니다
adapter / facade 기존의 잘게 나뉜 API를, 우리 쪽에 맞는 굵은 API로 바꾸는 설계상의 형입니다
STA / MTA Single / Multi Threaded Apartment COM의 스레드 모델. 어느 스레드에서 호출해도 되는지의 약속이 달라집니다

3. 먼저 볼 판단표

3.1. 전체 그림

우선 이 표부터 보면 대체로 방침이 정해집니다.

상황 우선 선택 이유
브라우저 위의 ActiveX에 의존하고 있다 교체 쪽 Edge 본체는 ActiveX 비대응이고, IE 모드는 연명책으로서의 위치이기 때문
데스크톱 앱에서 OCX가 안정적으로 돌아가고 변경 범위가 작다 남기는 쪽 지금 무너뜨리는 비용이 더 큰 경우가 많기 때문
주변만 .NET화하고 싶지만 컨트롤의 거동이 읽히지 않는다 감싸는 쪽 먼저 경계를 정리하는 편이 안전하기 때문
32bit OCX를 64bit 프로세스에 그대로 넣고 싶다 감싸기 / 구성 변경 in-proc에서는 넘을 수 없는 경계이기 때문
UI 부품으로만 쓰고 있고 대체가 있다 교체 쪽 표면의 치환으로 끝나는 경우가 많기 때문
벤더 종료, 서명, 등록, 의존 DLL로 매번 사고가 난다 교체 쪽 운용 비용이 기술적 부채로 표면화하고 있기 때문
기기 제어, 장표, 독자 프로토콜을 내포하고 있다 감싸는 쪽 먼저 동작을 고정하지 않으면 치환 비용이 읽히지 않기 때문
아니요아니요아니요아니요아니요ActiveX / OCX가 있다브라우저 의존?교체를 우선IE 모드는 연명책주로 UI 부품?동등한 대체가 있는가?교체를 검토먼저 감싸서 경계를 정리기기 제어·독자 사양·장표 로직을 안고 있는가?먼저 감싼다테스트를 맞춘 뒤 단계 치환등록·bitness·배포가 아픈가?구성을 다시 본다out-of-proc / 별도 프로세스 연동 / Reg-Free COM을 검토남기는 판단도 현실적

그림3: 첫 분기는 브라우저 의존 여부이고, 그다음은 UI 부품인지·대체가 있는지·사양을 안고 있는지에서 방침이 정해진다.

이어서 각 패턴을 순서대로 보겠습니다.

3.2. 남기는 판단

ActiveX / OCX라고 해서 바로 치환 대상이 되는 것은 아닙니다. 이런 조건이 갖춰지면, 남기는 것이 가장 싼 일은 흔히 있습니다.

  • 이용 범위가 닫혀 있고, 사내 배포나 장치 동봉처럼 운용 환경이 고정되어 있다
  • 그 컨트롤이 지금도 안정적으로 돌아가며, 변경 요구가 크지 않다
  • 벤더가 아직 현역이거나, 자사에서 최소한의 보수를 할 수 있다
  • 브라우저 의존이 아니라, 데스크톱의 기존 호스트 위에서 끝난다
  • 32bit / 64bit 전제를 당분간 바꾸지 않아도 된다

여기서 중요한 것은, 남긴다 = 방치가 아니라는 점입니다. 남긴다면 적어도 이 정도는 해 두고 싶습니다.

  • 대응 OS, bitness, 필요한 의존 DLL, 등록 절차를 문장으로 남긴다
  • 설치, 등록, 해제를 사람 손이 가는 메모가 아니라 스크립트나 설치 프로그램으로 옮긴다
  • 클린 환경에서의 스모크 테스트를 마련한다
  • 컨트롤 호출을 앱 전체에 흩뿌리지 말고, 되도록 한곳으로 모은다

가장 나쁜 것은 「돌아가니까 손대지 않는다」를 10년 이어, 전제를 설명할 사람이 없어지는 일입니다. 남기는 선택을 할수록, 전제의 가시화는 중요해집니다.

남기는 판단과 세트로 하는 가시화남기는 판단은 방치가 아니라, 전제의 문서화, 등록 절차의 스크립트화, 클린 환경에서의 스모크 테스트, 호출 위치의 집약을 세트로 한다.남기는 판단전제를 문장으로 남긴다등록 절차를 스크립트화스모크 테스트를 마련호출을 한곳으로 모은다

그림4: 남긴다=방치가 아니라, 남기는 선택을 할수록 전제의 가시화를 세트로 한다.

3.3. 감싸는 판단

실무에서는 이 선택이 가장 일이 됩니다.

여기서 말하는 「감싼다」는 ActiveX / OCX를 좁은 경계 안쪽에 가두고, 주변에서는 새로운 API나 새로운 화면 부품으로 보이게 하는 것입니다.

이것은 꽤 유효합니다. 왜냐하면 오래된 부품의 거동이 읽히지 않는 단계에서 전면 재구현에 들어가면, 사양 발굴과 결함 재현의 이중고가 되기 쉽기 때문입니다. 우선 오래된 부품을 격리하고, 경계만 맞추는 편이 안전합니다.

감싼다는 선택의 구도ActiveX / OCX를 좁은 경계 안쪽에 가두고, 주변에서는 새로운 API나 화면 부품으로 보이게 함으로써, 거동이 읽히지 않는 단계에서의 전면 재구현에 따른 사양 발굴과 결함 재현의 이중고를 피한다.ActiveX / OCX좁은 경계 안쪽에 가둔다새로운 API로 보이게 한다주변은 새로운 창구만 본다사양 발굴과 재현의 이중고를 회피

그림5: 「감싼다」는 오래된 부품의 격리와 새로운 창구 만들기로, 전면 재구현의 전단계로 효과가 있다.

감싸는 방법에는 몇 가지 형이 있습니다.

감싸는 방법 맞는 장면 볼 포인트
WinForms 호스트 + AxHost / Aximp 기존 데스크톱 화면에 넣고 싶다, 소수 화면만 남기고 싶다 STA, 이벤트, 디자인 시 의존, 라이선스
32bit helper EXE / COM LocalServer / 별도 프로세스 다리 64bit 측으로 옮기고 싶다, 크래시를 격리하고 싶다 프로세스 간 통신, 기동 순서, 감시, 배포
.NET 측의 COM 호환 창구 기존 COM 호출원은 남기면서 속을 갱신하고 싶다 IID / CLSID / TLB / 등록 방법 / bitness

방침이 정해진 뒤, 첫걸음이 어디인지도 적어 둡니다.

감싸는 방법 처음에 할 일 자세한 절차
WinForms 호스트 + AxHost Visual Studio에서 도구 상자를 오른쪽 클릭 →「도구 상자 항목 선택」→「COM 구성 요소」탭에서 대상을 고른다. 커맨드라인이면 aximp COM/OCX/ActiveX개발에서 빠지기 쉬운 등록과 bitness의 함정
32bit helper EXE / LocalServer 32bit EXE 측을 COM 서버로 등록하고, 64bit 측에서는 out-of-proc으로 호출한다 COM이 도움이 되는 사례 연구-32bit 앱에서 64bit DLL을 호출하고 싶을 때
Reg-Free COM 앱 측 매니페스트에 filecomClass를 쓰고, 레지스트리 등록 없이 해결시킨다 Reg-Free COM이란 - 등록 없이 COM을 쓰는 구조
.NET 측의 COM 호환 창구 .NET 측을 COM 공개하고, 필요하면 dscom으로 TLB를 생성한다 .NET 8 DLL을 VBA에서 형 정보를 붙여 쓰는 방법 - COM 공개와 dscom TLB

aximp는 Visual Studio의 Developer Command Prompt에서 실행합니다.

aximp C:\path\to\MyControl.ocx

이렇게 하면 COM 형의 runtime callable wrapper와, AxHost에서 파생한 Windows Forms용 래퍼 두 개가 생성됩니다. 파일명은 원래 파일명이 아니라 ProgID에서 정해지므로, 거기만 주의하십시오. Microsoft 문서의 예에서는 msdxm.ocx에서 MediaPlayer.dllAxMediaPlayer.dll이 나옵니다. 후자를 참조에 추가하고, AxMediaPlayer를 폼에 붙이는 형태가 됩니다.

aximp가 생성하는 것aximp에 OCX를 넘기면, COM 형의 runtime callable wrapper와 AxHost 파생의 Windows Forms용 래퍼 두 개가 생성되고, 후자를 참조에 추가해 폼에 붙인다. 파일명은 원래 파일명이 아니라 ProgID에서 정해진다.대상 OCXaximp를 실행COM 형의 래퍼 DLLAxHost 파생의 래퍼 DLL참조에 추가하고 폼에 붙인다파일명은 ProgID에서 정해진다

그림6: aximp의 출력은 DLL 두 개이며, 폼에 붙이는 것은 AxHost 파생 래퍼 쪽이다.

Reg-Free COM의 경우, 앱 측 매니페스트는 최소로 이런 형태입니다.

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="MyApp" version="1.0.0.0" />
  <file name="MyControl.ocx">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      threadingModel="Apartment"
      progid="MyCompany.MyControl.1" />
  </file>
</assembly>

LocalServer 방식이라면, 레지스트리 상으로는 HKEY_CLASSES_ROOT\CLSID\{CLSID}\LocalServer32에 EXE 경로가 들어갑니다. ATL이나 MFC로 만든 EXE 서버라면, 관례로 MyServer.exe /regserver/unregserver로 자기 등록·해제가 되는 경우가 많습니다. 다만 bitness마다 레지스트리 뷰가 나뉘므로, 32bit EXE는 32bit 측 레지스트리에 등록된다는 점은 반드시 의식하십시오.

LocalServer 등록과 레지스트리 뷰LocalServer 방식에서는 CLSID 아래 LocalServer32에 EXE 경로가 들어가고, regserver 관례로 자기 등록할 수 있지만, bitness마다 레지스트리 뷰가 나뉘며 32bit EXE는 32bit 측 레지스트리에 등록된다.32bit64bitEXE 서버LocalServer32에 경로를 등록EXE의 bitness는?32bit 측 뷰에 등록64bit 측 뷰에 등록

그림7: LocalServer의 등록처는 bitness마다 나뉜 레지스트리 뷰에서 정해진다.

특히 중요한 것은, 감쌀 때 오래된 API를 그대로 200개 복사하지 않는 것입니다. 그렇게 하면 오래된 사정을 새 코드로 그대로 수입할 뿐입니다.

감쌀 때는 이 정도를 의식하면 꽤 나아집니다.

  • 굵은 입자의 메서드로 만든다
  • 화면 코드에서 OCX를 직접 건드리지 않게 한다
  • 실패 시 필요한 로그를 경계에서 남긴다
  • 타임아웃, 재시도, 예외 변환의 책무를 경계에서 정한다
  • 장래의 교체처도 같은 인터페이스로 갈아끼울 수 있게 한다

새로운 .NET 측에서 COM 입구만 남기고 싶은 경우도 있습니다. 이때는 「속은 갱신하면서 COM 계약만 유지한다」는 구성이 현실적입니다. 다만 .NET Framework 시절 감각으로 「일단 RegAsm」으로 끝나는 것은 아닙니다. 지금의 .NET의 COM host, TLB, bitness, Registry-Free COM 취급은 먼저 설계해 두는 편이 나중에 편합니다. 이 부근은 .NET 8 DLL을 VBA에서 형 정보를 붙여 쓰는 방법 - COM 공개와 dscom TLBReg-Free COM이란 - 등록 없이 COM을 쓰는 구조에서 각각 절차까지 적어 두었습니다.

경계에서 정하는 책무감쌀 때는 굵은 입자의 메서드로 만들고, 화면 코드에서 OCX를 직접 건드리지 않게 하며, 로그나 타임아웃이나 예외 변환의 책무를 경계에서 정하고, 장래의 교체처도 같은 인터페이스로 갈아끼울 수 있게 한다.감싸는 경계굵은 입자의 메서드로그를 경계에서 남긴다타임아웃과 예외 변환같은 창구로 장래에 갈아끼움오래된 API를 200개 복사하지 않는다

그림8: 감싸는 가치는 경계에 책무를 모으는 데 있으며, 오래된 API를 그대로 베껴서는 그 가치가 나오지 않는다.

3.4. 교체하는 판단

교체에 맞는 것은, 주로 표면의 오래됨이 문제가 되는 경우입니다.

이럴 때는 교체 우선으로 보는 편이 좋습니다.

  • 그 ActiveX가 UI 부품으로만 쓰이고 있다
  • 벤더가 .NET / WPF / WebView2 쪽 후속을 내놓고 있다
  • 브라우저 의존이나 IE 전제가 발목을 잡고 있다
  • 등록, 서명, 관리자 권한, 보안 설정에서 매번 걸린다
  • 대체 구현을 검증할 테스트나 업무 시나리오가 있다

반대로, 겉모습이 오래됐다는 이유만으로 기기 제어나 장표 로직까지 안은 부품을 한꺼번에 버리러 가면, 대개 진창이 됩니다.

교체한다면 우선 UI부터입니다.

  • 그리드
  • 캘린더
  • 트리
  • 브라우저 표시부
  • 단순한 입력 보조

이 부근은 비교적 교체하기 쉽습니다. 한편 UI처럼 보여도 속이 진한 것도 있습니다.

  • 벤더제 기기 제어 ActiveX
  • 인쇄나 장표 생성과 일체화된 컨트롤
  • 독자 파일 형식의 읽기쓰기를 내포한 컨트롤
  • COM 콜백이나 스레드 전제를 안은 컨트롤

이 차이를 놓치면 공수 견적이 한순간에 무너집니다.

교체 판단의 가름UI 부품으로만 쓰이고 대체가 있으면 교체하기 쉽지만, UI처럼 보여도 기기 제어·장표·독자 형식·스레드 전제를 안은 부품은 속이 진하고, 갑자기 버리러 가면 진창이 된다.표면의 오래됨뿐사양의 덩어리를 안고 있다겉모습 뒤에 무엇이 있는가교체하기 쉽다한꺼번에 버리면 진창이 된다먼저 감싸는 쪽 판단으로

그림9: 교체에 맞는지 여부는 「표면의 오래됨」과 「속의 농도」를 가름해서 정해진다.

3.5. 브라우저 의존은 별도로 본다

여기는 꽤 별도 틀입니다.

브라우저 위의 ActiveX는 데스크톱 OCX와 달리, 앞으로도 그대로 늘려 갈 이유가 상당히 약합니다.

이유는 단순합니다. 현대 브라우저 기반이 거기를 주전장으로 삼지 않기 때문입니다. Microsoft Edge 자체는 ActiveX를 지원하지 않습니다. 한편 IE 모드는 설정된 사이트에 IE 계열 엔진을 써서, ActiveX를 포함한 일부 IE 기능을 돌리기 위한 호환 레이어로 쓸 수 있습니다.

즉,

  • 지금 돌리기 위한 연명은 된다
  • 다만 장기 설계로서 앞날이 굵은 것은 아니다

라는 이야기입니다.

브라우저 위 ActiveX의 위치Microsoft Edge 자체는 ActiveX를 지원하지 않고, IE 모드는 설정된 사이트에 IE 계열 엔진을 쓰는 호환 레이어이므로, 지금 돌리는 연명은 되어도 장기 설계로서 앞날이 굵지 않다.브라우저 위의 ActiveXEdge 본체에서는 동작하지 않는다IE 모드로 연명은 된다장기의 앞날은 가늘다교체 우선으로 본다

그림10: 브라우저 의존 ActiveX는 연명과 항구 설계를 나눠 생각하고, 교체 우선으로 본다.

같은 일은 Windows 앱에 넣은 WebBrowser 컨트롤에서도 일어납니다. WebBrowser는 IE 계열의 세계관을 끌어오므로, 단순히 HTML을 표시하고 싶을 뿐이라면, 지금부터의 신규 작업은 WebView2를 첫 후보로 두는 편이 자연스럽습니다.

다만 여기서 주의할 것은, WebView2는 WebBrowser의 완전한 교체 부품이 아니라는 점입니다.

  • IE DOM 전제의 스크립트
  • ActiveX 의존
  • window.external 주변의 전제
  • 보안 영역이나 인트라넷 전제의 거동

이 부근은 그대로는 옮겨지지 않습니다. 교체한다면 그리기 엔진뿐 아니라, 브라우저와 네이티브의 접속면도 다시 설계해야 합니다.

WebView2로 그대로 옮겨지지 않는 것WebView2는 WebBrowser 컨트롤의 완전한 교체 부품이 아니며, IE DOM 전제의 스크립트, ActiveX 의존, window.external 주변 전제, 보안 영역 전제의 거동은 그대로는 옮겨지지 않는다.WebBrowser에서 WebView2로HTML 표시만이라면 첫 후보그대로 옮겨지지 않는 것IE DOM 전제의 스크립트ActiveX 의존window.external 전제보안 영역의 거동

그림11: WebView2는 그리기 엔진의 교환 부품이어도, IE 세계관의 접속면까지는 이어받지 않는다.

4. 판단을 흔들기 쉬운 논점

4.1. UI 부품인가, 사양을 안은 부품인가

이것은 가장 중요합니다.

오래된 그리드나 캘린더라면, 겉모습과 이벤트 호환을 보면 이야기가 꽤 진행됩니다. 한편 기기 제어나 장표나 독자 형식을 안은 ActiveX는, 겉모습 뒤에 사양의 덩어리가 있습니다.

같은 「화면 위의 컨트롤」로 보여도, 실제로는 이만큼의 폭이 있습니다.

  • 그저 목록 표시 부품
  • 독자 프로토콜로 장치에 명령을 보내는 부품
  • 내부에서 타임아웃, 재연결, 재전송, 예외 흡수까지 하는 부품
  • 인쇄나 내보내기 형식의 호환을 짊어진 부품

후자를 갑자기 재구현하는 것은, 대개 사양 발굴 프로젝트가 됩니다. 여기는 먼저 감싸는 편이 안전합니다.

UI 부품인가 사양을 안은 부품인가같은 화면 위의 컨트롤로 보여도, 그저 목록 표시 부품과, 장치로의 명령이나 재연결이나 장표 호환까지 안은 부품은 폭이 있고, 후자를 갑자기 재구현하면 사양 발굴 프로젝트가 된다.화면 위의 컨트롤그저 표시 부품사양의 덩어리를 안은 부품호환을 보면 이야기가 진행된다갑자기 재구현하면 사양 발굴화먼저 감싸는 편이 안전

그림12: 가장 중요한 가름. 겉모습이 같아도, 뒤에 사양의 덩어리가 있는지에 따라 진행 방식이 바뀐다.

4.2. 32bit / 64bit와 프로세스 경계

여기는 자주 놓치지만, 꽤 본질입니다.

in-proc OCX는 로드하는 프로세스와 bitness를 맞춰야 합니다. 즉 32bit OCX를 64bit 앱에 그대로 로드할 수는 없습니다.

이때의 현실적인 선택지는 대개 이 세 가지입니다.

  • 당분간 호스트 앱 측도 32bit로 유지한다
  • 32bit 별도 프로세스에 가두고, 64bit 측과는 IPC나 out-of-proc COM으로 연결한다
  • 그 OCX 의존을 뗄 수 있는 곳부터 먼저 교체한다

여기서 「Any CPU니까 어떻게든 되겠지」는 대개 통하지 않습니다. 새로운 .NET 측에서 COM 호환 창구를 만들 때도, managed 코드의 겉모습과 실제 COM host의 bitness는 별문제입니다. 여기를 대충 시작하면, 빌드는 되는데 배포처에서 안 돌아가는, 그 싫은 녀석이 나옵니다.

32bit OCX와 64bit화의 세 갈래32bit OCX는 64bit 프로세스에 in-proc으로 로드할 수 없으므로, 호스트를 32bit로 유지하거나, 32bit 별도 프로세스에 가두고 IPC나 out-of-proc COM으로 연결하거나, 의존을 뗄 수 있는 곳부터 교체하는 세 갈래가 된다.32bit OCX는 in-proc 불가호스트를 32bit로 유지32bit 별도 프로세스에 가둔다뗄 수 있는 곳부터 교체IPC나 out-of-proc COM으로 접속

그림13: bitness 벽은 기합으로는 넘을 수 없고, 현실적인 선택지는 이 세 갈래로 떨어진다.

4.3. 등록, 배포, 권한, 라이선스

기술적으로는 호출할 수 있는데, 배포에서 죽는다. 이것은 ActiveX / OCX에서 꽤 흔합니다.

난관이 되기 쉬운 것은 이 부근입니다.

  • regsvr32 전제가 사람 의존이 되어 있다
  • 의존 DLL 배치가 암묵이 되어 있다
  • 관리자 권한이 필요한데, 운용 절차로 내려가지 않았다
  • 벤더제 컨트롤의 design-time / runtime 라이선스가 나뉘어 있다
  • 개발 기기에서는 돌아가는데, 클린 환경에서는 안 돌아간다

이 부근은 코드를 한 줄도 건드리지 않아도 프로젝트를 멈춥니다.

등록 불필요 구성이나 side-by-side 배치로 편해지는 경우도 있지만, 마법의 가루는 아닙니다. 컨테이너 측이나 배포 방식과의 궁합 확인은 필요합니다.

요컨대 ActiveX / OCX 이행은 구현뿐 아니라 배포 설계이기도 합니다. 여기를 뒤로 미루면, 마지막에 화려하게 넘어집니다.

배포에서 멈추는 난관regsvr32의 사람 의존, 암묵의 의존 DLL 배치, 운용 절차에 내려가지 않은 관리자 권한, design-time과 runtime으로 나뉘는 라이선스는, 코드를 한 줄도 건드리지 않아도 프로젝트를 멈춘다.배포 설계regsvr32가 사람 의존의존 DLL이 암묵관리자 권한이 절차 밖라이선스가 이분코드를 건드리지 않아도 멈춘다

그림14: 기술적으로는 호출할 수 있어도 배포에서 죽는다는 난관은, 구현과 별도로 설계해 둔다.

4.4. STA / 메시지 루프 / 콜백

ActiveX / OCX는 그저 DLL 호출이 아닙니다. COM의 스레드 모델이나 메시지 루프 전제를 가지고 있는 경우가 있습니다.

특히 주의할 것은 다음 같은 경우입니다.

  • UI 스레드 전제에서만 안정된다
  • STA 전제인데 MTA 측에서 대충 호출하고 있다
  • 동기 호출 중에 콜백이 돌아온다
  • 이벤트를 받는 스레드 전제가 애매하다

이 부근은 처음에는 「가끔 굳는다」「가끔 이벤트가 안 온다」는 괴담의 얼굴을 하고 나타납니다. 하지만 속은 대개 전제 위반입니다.

그래서 감쌀 때도 교체할 때도, 어느 스레드에서 생성하고, 어느 스레드에서 호출하고, 어디서 이벤트를 받을지는 먼저 고정하는 편이 좋습니다.

스레드 전제를 먼저 고정한다어느 스레드에서 생성하고, 어느 스레드에서 호출하고, 어디서 이벤트를 받을지를 먼저 고정하지 않으면, 가끔 굳는다·가끔 이벤트가 안 온다는 전제 위반의 괴담이 된다.먼저 고정할 3점어느 스레드에서 생성하는가어느 스레드에서 호출하는가어디서 이벤트를 받는가애매하면 전제 위반의 괴담화

그림15: 「가끔 굳는다」의 속은 대개 전제 위반이며, 스레드 약속을 먼저 고정해서 막는다.

4.5. 테스트가 있는가, 관측할 수 있는가

교체가 어려운 것은 코드가 오래돼서만이 아닙니다. 무엇을 가지고 「같게 돌아갔다」고 말할 수 있는가가 없기 때문입니다.

이런 것만 있어도 꽤 달라집니다.

  • 조작 시나리오별 스모크 테스트
  • 입출력 샘플
  • 화면 캡처나 장표 샘플
  • 오류 패턴과 기대 거동
  • 타임아웃 시나 장치 미접속 시의 로그

특히 기기나 장표가 얽히면, 명세서보다 현물의 거동이 진실이라는 묘한 일이 일어납니다. 여기서 관측 수단이 없으면 교체는 발굴 조사로 바뀝니다.

관측 수단이 교체를 받친다스모크 테스트나 입출력 샘플, 장표 샘플, 오류 패턴과 기대 거동 같은 관측 수단이 없으면, 무엇을 가지고 같게 돌아갔다고 말할 수 있는가가 없고, 교체는 발굴 조사로 바뀐다.있다없다관측 수단이 있는가같게 돌아갔다고 말할 수 있다교체가 발굴 조사화스모크 테스트나 샘플류

그림16: 교체의 어려움은 코드의 오래됨보다, 「같게 돌아갔다」고 말할 수 있는 관측 수단의 유무에서 정해진다.

5. 전형 패턴별 추천

5.1. 지금도 안정적으로 돌아가는 사내 데스크톱 앱

추천은 남기는 쪽입니다.

이런 조건이라면 무리해서 벗기지 않는 편이 좋은 경우가 많습니다.

  • 사내 한정으로 쓰고 있다
  • 대상 단말이나 OS가 어느 정도 고정되어 있다
  • 그 OCX는 몇 화면에서만 쓰고 있다
  • 수정 요구는 작고, 수명도 읽힌다

다만 그대로 헐벗은 채로 두지 말고, 호출 위치만이라도 모아 두는 편이 나중에 효과가 있습니다.

즉 방침은 이렇습니다.

  • 지금은 남긴다
  • 다만 경계만 맞춘다
  • 교체가 필요해졌을 때 거기서 착수할 수 있는 형태로 둔다

이 3단 구성이 솔직합니다.

5.2. 32bit OCX를 64bit 측으로 가져가고 싶다

추천은 감싸기 / 구성 변경입니다.

여기는 정면으로 가면 막힙니다. 32bit OCX를 64bit 프로세스에 in-proc으로 넣을 수 없기 때문입니다.

현실적으로는 32bit 헬퍼 프로세스나 LocalServer 측에 가두고, 64bit 앱과는 굵은 API로 통신하는 구성이 다루기 쉽습니다.

32bit OCX32bit 헬퍼 / LocalServer64bit .NET 앱32bit OCX32bit 헬퍼 / LocalServer64bit .NET 앱굵은 API로 의뢰in-proc 호출결과 / 이벤트변환된 결과

그림17: 32bit 헬퍼에 가둔 OCX를, 64bit 앱에서 굵은 API 너머로 쓰는 구성.

여기서의 포인트는, 세세한 메서드를 전부 그대로 중계하지 않는 것입니다. 프로세스 간 경계는 세세한 호출을 대량으로 흘리면 바로 힘들어집니다.

  • 1 조작 = 1 요청 정도의 입자로 모은다
  • 반환값이나 오류를 의미 있는 단위로 다듬는다
  • 로그를 경계에서 남긴다

이 형태로 두면, 나중에 속을 정말로 교체할 때도 편합니다.

여기까지는 자체 헬퍼 EXE를 전제로 적었지만, 그 앞에 한 단 더, 먼저 확인해 두고 싶은 선택지가 있습니다.

그 OCX / DLL이 in-proc COM 서버, 즉 InprocServer32로 등록할 수 있는 것이라면, Windows 부속 서로게이트 프로세스에 올려 out-of-proc Local Server로 내보낼 수 있습니다. CLSID에 AppID를 붙이고, 그 AppID 키에 빈 문자열의 DllSurrogate를 쓰기만 하면, 이쪽 코드는 한 줄도 필요 없습니다. 등록 절차는 COM/OCX/ActiveX개발에서 빠지기 쉬운 등록과 bitness의 함정의 3.5에 정리해 두었습니다.

다만 서로게이트가 bitness 차이를 없애 주는 것은 아닙니다. 사라지는 것은 같은 프로세스에 올려야 한다는 제약뿐이고, 호출은 out-of-proc이 되며, 마샬링과 프로세스 간 통신 비용은 그대로 붙습니다.

어느 쪽을 고를지는 대개 이 표로 정해집니다.

상황 고르는 것 이유
메서드 호출과 이벤트로 끝나는 자동화 객체 우선 서로게이트 등록만으로 out-of-proc화할 수 있고, 쓸 코드가 없기 때문
주고받는 형이 IDispatch나 등록된 proxy / stub으로 마샬링할 수 있다 우선 서로게이트 경계를 넘는 준비가 이미 있기 때문
그 CLSID에 LocalServer32 같은 EXE 등록이 이미 있다 서로게이트는 자리 없음 EXE 서버나 서비스 기동이 항상 우선되기 때문
폼에 붙여 그리게 하는 비주얼 컨트롤로 쓰고 싶다 다른 구성을 생각한다 창은 호스트 프로세스 안에 있다는 전제이기 때문
세세한 호출이 고빈도로, 그대로 중계하면 무겁다 자체 헬퍼 EXE 굵은 API로 묶는 층을 직접 가져야 하기 때문
독자 인터페이스에 마샬러가 없다 자체 헬퍼 EXE proxy / stub을 마련하거나, 경계의 형을 직접 정하는 편이 빠르기 때문
초기화 순서, 재연결, 타임아웃, 로그를 직접 쥐고 싶다 자체 헬퍼 EXE 서로게이트의 프로세스 수명은 COM에 맡기기 때문

즉 서로게이트는 먼저 시도할 가치가 있는 최소 손이고, 자체 EXE는 경계를 직접 설계하고 싶을 때의 손입니다. 3.1 표의 「32bit OCX를 64bit 프로세스에 그대로 넣고 싶다 → 감싸기 / 구성 변경」은 바뀌지 않습니다. 그 「감싸기」 안에 2단이 있다고 읽어 주십시오.

5.3. IE / WebBrowser 전제의 화면

추천은 교체 우선입니다.

여기는 「지금 돌아간다」와 「앞으로도 편하게 유지할 수 있다」가 맞기 어려운 영역입니다. IE 모드는 호환을 위해 꽤 도움이 되지만, 그래도 전제는 IE 계열 그대로입니다.

그래서 생각법은 이렇게 나누는 편이 알기 쉽습니다.

  • 사내 업무를 멈추지 않기 위해 IE 모드로 연명한다
  • 다만 연명과 항구 설계를 혼동하지 않는다
  • 교체처는 WebView2, 순수 Web, 네이티브 UI + Web 하이브리드 등에서 고른다

연명 측의 구체적인 조치도 적어 둡니다. IE 모드는 「Edge를 넣으면 저절로 먹히는」 것이 아니라, 대상 사이트를 정책으로 지정해야만 IE 계열 엔진으로 열립니다. 설정의 입구는 이 세 가지입니다.

방법 설정 보충
사이트를 열거한다 Microsoft Edge 78 이후의 그룹 정책 「Configure the Enterprise Mode Site List」에, 엔터프라이즈 모드 사이트 목록 XML의 위치를 지정한다 가장 기본적인 형태입니다
구 IE 측 목록을 재사용한다 Internet Explorer의 정책 「Use the Enterprise Mode IE website list」 Edge 측 정책이 있으면 그쪽이 우선됩니다
인트라넷 전체를 돌린다 Microsoft Edge 77 이후의 그룹 정책 「Send all intranet sites to Internet Explorer」를 사용으로 한다 대상이 넓어지므로, 재고 조사의 대신이 되지는 않습니다

전제로, Windows와 Edge에 최신 업데이트가 들어가 있을 것, Microsoft Edge 관리용 템플릿이 도입되어 있을 것, Windows 기능에서 Internet Explorer 11이 사용으로 되어 있을 것이 필요합니다. 여기가 빠지면 IE 모드는 실패합니다.

참고로 IE 모드에서는 ActiveX 컨트롤이나 Browser Helper Object가 동작합니다. 즉 연명은 정말로 됩니다. 그래서 종료 조건을 정하지 않고 계속 쓰면 빠져나오지 못하게 됩니다. 벗기는 이야기는 IE 모드 의존 시스템에서 벗어나기 가이드에 정리해 두었습니다.

IE 모드 연명의 생각법IE 모드는 대상 사이트를 정책으로 지정해야만 먹고, ActiveX도 동작하므로 연명은 정말로 되지만, 연명과 항구 설계를 혼동하지 말고, 종료 조건을 정해 쓰지 않으면 빠져나오지 못하게 된다.대상 사이트를 정책으로 지정IE 모드로 열린다ActiveX 포함해 연명할 수 있다종료 조건을 정해 쓴다정하지 않으면 빠져나오지 못한다

그림18: IE 모드 연명은 「정말로 먹히기」 때문에, 종료 조건과 세트로 쓴다.

특히 WebBrowser 컨트롤을 그저 HTML 뷰어로만 쓰고 있다면, 교체 우선도는 높습니다.

한편 브라우저 안의 ActiveX가 로컬 파일, 장치, 서명, 독자 애드온 같은 역할까지 가지고 있다면, 그것은 그리기 엔진 교환이 아니라 네이티브 연동의 재설계입니다. 여기는 이야기가 조금 무거워집니다.

5.4. 기기 제어나 독자 사양을 안은 ActiveX

추천은 먼저 감싸는 것입니다.

이 유형은 겉모습보다 속이 진합니다. SDK 자료가 얇아도, 현장에서 오래 돌아가 온 결과로, 이런 거동이 암묵으로 쌓여 있는 경우가 있습니다.

  • 연결 실패 시의 기다리는 방식
  • 타임아웃 후의 재시도
  • 이벤트 순서
  • 실기의 버릇을 흡수하는 회피 처리
  • 예외나 오류 코드의 해석

이런 부품을 「어차피 오래됐으니까」로 다시 만들면, 꽤 높은 확률로 현장 시험이 탑니다.

그래서 우선 여기서 시작하는 것이 안전합니다.

  1. 기존 부품을 경계 안쪽으로 가둔다
  2. 로그를 더해, 무엇이 일어나는지 보이게 한다
  3. 테스트 시나리오와 실기 패턴을 모은다
  4. 그다음에 교체 가능한 범위를 잘라 낸다

화려함은 없지만, 실무에서는 이것이 가장 효과가 있습니다.

사양을 안은 ActiveX의 진행 방식기존 부품을 경계 안쪽으로 가두고, 로그를 더해 무엇이 일어나는지 보이게 하고, 테스트 시나리오와 실기 패턴을 모은 뒤, 그다음에 교체 가능한 범위를 잘라 내는 순서로 진행한다.경계 안쪽으로 가둔다로그를 더해 가시화시나리오와 실기 패턴 수집교체 가능한 범위를 잘라 낸다

그림19: 기기 제어나 독자 사양을 안은 부품은, 이 순서로 진행하면 현장 시험이 타기 어렵다.

6. 흔한 안티패턴

안티패턴 무엇이 힘든가 우선 고치는 법
ActiveX가 있으니 전면 리라이트 사양 누락과 공수 폭발이 일어나기 쉽다 먼저 재고 조사와 경계 잘라 내기
32bit OCX를 64bit 앱에 그대로 넣으려 한다 원리적으로 불가능 32bit 측으로 격리하거나 구성을 바꾼다
컨트롤 API를 화면 곳곳에서 직접 호출하고 있다 교체 불능이 되기 쉽다 adapter / facade로 모은다
regsvr32 절차를 사람 손으로 운용하고 있다 환경 차이로 매번 사고가 난다 설치 프로그램, 스크립트, 매니페스트화를 검토
IE 모드가 있으니 안심한다 연명과 항구 대응을 혼동하기 쉽다 교체 계획과 종료 조건을 정한다
교체 전에 동작을 기록하지 않았다 완성 판정이 안 된다 스모크 테스트, 샘플 데이터, 로그를 맞춘다

이 가운데 실무에서 특히 자주 보는 것은 세 가지입니다.

  1. 전면 리라이트를 서두른다
  2. bitness 벽을 가볍게 본다
  3. API를 앱 전체에 흩뿌린다

이 세 가지만 피해도 사고율은 꽤 내려갑니다.

특히 자주 보는 세 가지 안티패턴전면 리라이트를 서두르기, bitness 벽을 가볍게 보기, 컨트롤 API를 앱 전체에 흩뿌리기의 세 가지를 피하기만 해도 사고율은 꽤 내려간다.전면 리라이트를 서두른다이 세 가지를 피한다bitness 벽을 가볍게 본다API를 전체에 흩뿌린다사고율이 꽤 내려간다

그림20: 안티패턴 가운데서도 조우율이 높은 것은 이 세 가지이며, 피하기만 해도 효과가 크다.

7. 이행을 시작할 때의 체크리스트

ActiveX / OCX 안건은 갑자기 구현으로 들어가기보다, 먼저 재고 조사를 하는 편이 잘 됩니다. 순서는 대개 이렇습니다.

  1. 쓰고 있는 OCX / DLL을 뽑아낸다
    • 파일명, 버전, ProgID, CLSID, 벤더, 라이선스 유무
  2. 어디서 쓰고 있는지를 뽑아낸다
    • 화면, 기능, 장표, 장치, 배치 작업, Office 연동 등
  3. bitness와 호스트 조건을 확인한다
    • 32bit / 64bit, in-proc / out-of-proc, STA 전제, 브라우저 의존
  4. 배포 조건을 확인한다
    • 등록 방법, 의존 DLL, 관리자 권한, 사일런트 설치, 클린 환경 재현
  5. 스모크 테스트를 만든다
    • 정상 경로뿐 아니라 실패 시, 미접속 시, 타임아웃 시까지 포함한다
  6. 경계를 만든다
    • adapter, service, facade, 별도 프로세스 다리 등
  7. 1 화면, 1 기능, 1 장치처럼 작은 단위로 시험한다
  8. 잘된 경계부터 순서대로 남기기 / 감싸기 / 교체를 넓힌다

이 절차를 건너뛰면, 나중에 「무엇이 어려웠는지」조차 설명하기 어려워집니다.

8. 대략적인 구분

상황 우선 고르는 것
사내 한정으로 안정 가동, 변경도 작다 남긴다
주변만 .NET화하고 싶다 감싼다
32bit / 64bit가 부딪힌다 감싸기 / 구성 변경
IE / WebBrowser / 브라우저 ActiveX 의존 교체한다
단순한 UI 부품이고 대체가 있다 교체한다
기기 제어, 장표, 독자 사양을 안고 있다 감싼다
등록이나 배포에서 매번 넘어진다 감싸거나 교체한다

막히면, 우선 UI 부품인지, 사양을 안은 경계면인지를 가려내면 꽤 빗나가기 어려워집니다.

9. 정리

ActiveX / OCX를 어떻게 다룰지는, 레거시니까 싫어한다, 로 정하는 이야기가 아닙니다.

먼저 볼 포인트는 네 가지입니다.

  1. 그 부품은 단순한 UI인가, 아니면 사양을 안은 경계면인가
  2. 동일 프로세스에서 쓸 필요가 있는가
  3. 32bit / 64bit, 등록, 브라우저 의존, 라이선스로 막히지 않는가
  4. 교체 전에 동작을 관측할 수 있는가

이 네 가지가 보이면 대개 이렇게 정리할 수 있습니다.

  • 안정적으로 돌아가고 수명도 읽히면, 남긴다
  • 주변만 현대화하고 싶으면, 감싼다
  • UI 부품이나 브라우저 의존이면, 교체한다
  • 사양의 덩어리를 안은 부품은, 먼저 감싼 뒤 단계 치환한다

레거시 기술은 웃을 대상이 아니라, 역사와 계약이 담긴 현물입니다. 다만 현물을 다루기 위한 경계 설계는 필요합니다.

「남길지・감쌀지・교체할지」를 섞어 생각할 수 있게 되면, ActiveX / OCX 안건은 갑자기 다룰 수 있는 문제로 바뀌어 옵니다.

정리의 구분안정 가동이고 수명이 읽히면 남기고, 주변만 현대화하고 싶으면 감싸고, UI 부품이나 브라우저 의존이면 교체하고, 사양의 덩어리를 안은 부품은 먼저 감싼 뒤 단계 치환한다는 정리를 나타낸다.ActiveX / OCX의 취급안정 가동이면 남긴다주변의 현대화면 감싼다UI나 브라우저 의존은 치환사양의 덩어리는 감싼 뒤 단계 치환

그림21: 먼저 볼 네 가지 포인트가 보이면, 남길지·감쌀지·교체할지는 이 형태로 정리할 수 있다.

10. 이런 상담은 궁합이 좋다

이 주제는 갑자기 개발에 들어가기 전의 방침 정리만으로도 가치가 나오기 쉽습니다.

예를 들어 이런 상담은 꽤 궁합이 좋습니다.

  • 어느 OCX를 정말로 교체해야 하는지 재고 조사하고 싶다
  • 32bit / 64bit의 막히는 곳만 먼저 정리하고 싶다
  • .NET으로 옮기고 싶지만 COM 입구만은 남기고 싶다
  • 벤더가 끝난 ActiveX의 연명책과 철수전을 비교하고 싶다
  • IE / WebBrowser 의존을 어디서 벗길 수 있는지 보고 싶다
  • 우선 1 화면, 1 기능만 안전하게 분리하고 싶다

ActiveX / OCX 안건은 구현보다 먼저 경계를 어떻게 자를지가 승부가 되는 경우가 많습니다. 전면 개편의 전단계로, 현황 정리, 구성 비교, 이행 순서 설계부터 들어가기만 해도 꽤 의미가 있습니다.

11. 참고 자료

  • Microsoft Learn: AxHost Class (System.Windows.Forms)
    • https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.forms.axhost
  • Microsoft Learn: Aximp.exe (Windows Forms ActiveX Control Importer)
    • https://learn.microsoft.com/ja-jp/dotnet/framework/tools/aximp-exe-windows-forms-activex-control-importer
  • Microsoft Learn: How to: Add ActiveX Controls to Windows Forms
    • https://learn.microsoft.com/en-us/dotnet/desktop/winforms/controls/how-to-add-activex-controls-to-windows-forms
  • Microsoft Learn: Expose .NET Core components to COM
    • https://learn.microsoft.com/en-us/dotnet/core/native-interop/expose-components-to-com
  • Microsoft Learn: Registration-Free COM Interop
    • https://learn.microsoft.com/en-us/dotnet/framework/interop/registration-free-com-interop
  • Microsoft Learn: DllSurrogate
    • https://learn.microsoft.com/en-us/windows/win32/com/dllsurrogate
  • Microsoft Learn: Registering the DLL Server for Surrogate Activation
    • https://learn.microsoft.com/en-us/windows/win32/com/registering-the-dll-server-for-surrogate-activation
  • Microsoft Learn: Microsoft Edge에 관해 자주 묻는 질문
    • https://learn.microsoft.com/ja-jp/deployedge/microsoft-edge-frequently-asked-questions
  • Microsoft Learn: What is Internet Explorer (IE) mode?
    • https://learn.microsoft.com/en-us/deployedge/edge-ie-mode
  • Microsoft Learn: WebBrowser Class (System.Windows.Forms)
    • https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.webbrowser
  • Microsoft Learn: Introduction to Microsoft Edge WebView2
    • https://learn.microsoft.com/en-us/microsoft-edge/webview2/
  • KomuraSoft Blog: COM의 STA/MTA에서 hang을 피하기 위한 기초 지식
    • https://comcomponent.com/blog/2026/01/31/000-sta-mta-com-relationship/
  • KomuraSoft Blog: C++ 네이티브 DLL을 C#에서 쓸 때 C++/CLI로 래퍼를 만드는 편이 좋은 이유
    • https://comcomponent.com/blog/2026/03/07/000-cpp-cli-wrapper-for-native-dlls/
  • KomuraSoft Blog: COM이 도움이 되는 사례 연구-32bit 앱에서 64bit DLL을 호출하고 싶을 때
    • https://comcomponent.com/blog/2026/01/25/002-com-case-study-32bit-to-64bit/
  • KomuraSoft Blog: COM / ActiveX / OCX란 무엇인가 - 차이와 관계를 모아 해설
    • https://comcomponent.com/blog/2026/03/13/000-what-is-com-activex-ocx/
  • KomuraSoft Blog: .NET 8 DLL을 VBA에서 형 정보를 붙여 쓰는 방법 - COM 공개와 dscom TLB
    • https://comcomponent.com/blog/2026/03/16/007-dotnet8-dll-typed-vba-com-dscom-tlb/
  • KomuraSoft Blog: Reg-Free COM이란 - 등록 없이 COM을 쓰는 구조
    • https://comcomponent.com/blog/2026/03/16/011-what-is-reg-free-com/
  • KomuraSoft Blog: COM/OCX/ActiveX개발에서 빠지기 쉬운 등록과 bitness의 함정
    • https://comcomponent.com/blog/2026/04/15/001-com-ocx-activex-pitfalls-visual-studio-bitness-admin-rights/
  • KomuraSoft Blog: IE 모드 의존 시스템에서 벗어나기 가이드
    • https://comcomponent.com/blog/2026/04/25/003-ie-mode-internal-web-system-life-extension-and-exit/
  • KomuraSoft Blog: IE 모드 다음은 WebView2면 되는가 ── ActiveX가 동작하지 않는 제약과 현실적인 이행 설계
    • https://comcomponent.com/blog/webview2-embed-web-ui-in-windows-apps/

같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.

이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.

ActiveX 이관

COM / ActiveX / OCX 자산을 유지할지, 감쌀지, 교체할지의 단계적 판단을 정리한 토픽 페이지입니다.

이 기사는 다음 서비스 페이지로 이어집니다. 가까운 입구부터 확인해 주세요.

자주 묻는 질문

이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.

ActiveX / OCX는 교체해야 하나요?
「오래됐는지」가 아니라, 그 부품이 무엇을 떠맡고 있는지로 판단합니다. 단순한 UI 부품이고 대체가 있으면 교체하고, 기기 제어·장표·독자 파일 형식을 안고 있다면 먼저 감싸서 경계를 정리하며, 안정적으로 돌아가고 변경 범위가 작다면 남기는 판단도 현실적입니다. 「일단 전면 리라이트」와 「무서우니까 영구 동결」은 둘 다 사고율이 높은 선택입니다.
32bit OCX를 64bit 앱에서 사용할 수 있나요?
in-proc에서는 사용할 수 없습니다. OCX는 로드하는 프로세스와 bitness를 맞춰야 하며, 이는 원리상의 제약입니다. 현실적인 선택지는 당분간 호스트 앱도 32bit로 유지하거나, 32bit 별도 프로세스(헬퍼 EXE나 COM LocalServer)에 가두고 64bit 측과는 IPC나 out-of-proc COM으로 연결하거나, 그 OCX 의존을 뗄 수 있는 곳부터 먼저 교체하는 세 가지입니다.
브라우저의 ActiveX 의존은 어떻게 해야 하나요?
교체 우선으로 보는 편이 좋습니다. Microsoft Edge 자체는 ActiveX를 지원하지 않으며, IE 모드는 연명책으로서의 위치입니다. WebBrowser 컨트롤도 마찬가지로 IE 계열의 세계관을 끌어오기 때문에, 단순히 HTML을 표시하고 싶을 뿐이라면 WebView2가 첫 후보입니다. 다만 WebView2는 완전한 교체 부품이 아니어서, IE DOM 전제의 스크립트나 window.external 주변 전제는 그대로는 옮겨지지 않습니다.
ActiveX / OCX를 「감싼다」는 것은 구체적으로 무엇을 하는 건가요?
ActiveX / OCX를 좁은 경계 안쪽에 가두고, 주변에서는 새로운 API나 화면 부품으로 보이게 하는 것입니다. WinForms 호스트+AxHost, 32bit 헬퍼 EXE나 LocalServer로 별도 프로세스 다리를 놓는 방식, .NET 측의 COM 호환 창구 같은 형이 있습니다. 감쌀 때는 오래된 API를 그대로 대량 복사하지 말고 굵은 입자의 메서드로 만들며, 경계에서 로그·타임아웃·예외 변환의 책무를 정하고, 장래의 교체처도 같은 인터페이스로 갈아끼울 수 있는 형태로 둡니다.

저자 프로필

기사 저자의 프로필 페이지입니다.

Go Komura

합동회사 코무라소프트 대표

Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.

블로그 목록으로 돌아가기