Microsoft MVP성태의 닷넷 이야기
OCX 로드 관련 질문입니다. [링크 복사], [링크+제목 복사]
조회: 7589
글쓴 사람
링크의 전설
홈페이지
첨부 파일
안녕하세요.


현재 진행중인 프로젝트에서 ActiveX 컨트롤을 동적으로 로드하여 사용해야하는데
구글링(현재 COM 관련 지식이 전무한 상태)해봐도 적절한 해결책을 찾을 수 없어 질문드립니다.


최종 구현 목표
1. .Net 환경에서 동적(n개 ocx를 사용자 선택에 따라)으로 OCX를 로드하여 윈폼에 올림
2. 스크립트(현재는 ClearScript)에서 로드한 OCX 객체의 Property, Method, Event 접근하여 관련 작업을 수행
   ex) axHost.NextDay(); // 스크립트에서 이와 같이 접근하여 사용


step1
아래와 같이 AxHost 상속하여 OCX 로드

class AxHostEx : AxHost
{
     public AxHostEx(string strCLSID)
      : base(strCLSID)
      {
      }

     // 아무런 추가 구현 없음
}

결과 : 로드되고 폼에 올려지며 정상 동작하나 해당 OCX 고유의 Property, Method, Event에 .Net 인터페이스로 접근 불가
       (해보기 전까진 어떤 형태로든 '.Net 님이 다 알아서 해주실꺼야'라고 생각하고 있었습니다)

상태 : 이후 조사해 본바로는 AxHost를 상속받은 클래스에 COM객체와 직접 통신는 코드(기계적?)를 작성하여 해당 멤버들을 직접 구현해야 한다는 것을 알게되었습니다(제대로 이해한 것이 맞다면).
       COM 관련 지식이 전무한 상태라 관련 내용을 살펴봐도 잘 이해가되지 않고
       무엇보다 코드를 직접 구현하고 컴파일해야하는 정적인 방식이라 최종 구현 목표에 부합되지 않아 보류

step2
AxImp.exe 사용 COM Interop 어셈블리와 COM 프록시 어셈블리를 생성하여 어셈블리 로드

결과 : 완전하지 않지만 구현 목표에 부합하며 잘 동작함

상태 : 문제없이 잘 동작 하지만 동작(구현) 방식이 우아(?)하지도 안전(?)하지도 않는데다
       배포되어 사용되는 시점에 모양새가 안타까워 가능한 다른 방법으로 찾고 있음


질문 요약
.Net에서 AxImp.exe를 사용하지 않고 동적으로 로드한 OCX의 인터페이스(Property, Method, Event)를 .Net 인터페이스 형태로 제공하는 것이 가능한가?
(step1의 구현 방식에서 로드한 COM 개체를 분석해 동적으로 멤버를 생성/추가하면되겠다(리플렉션이든 뭐든?)라고 막연히 생각해보는데 이것이 기술적으로 가능한 것인지?
만약 그런 방식으로 구현이 가능하다면 AxImp.exe와 같은 도구를 별도로 제공할필요가 없었텐데하는 의문에 질문하게 되었습니다)

혹은 상기 최종 구현 목표를 달성을 위한 또 다른 방법이 있다면 조언 부탁합니다.



답변 부탁드립니다.

감사합니다.


※ 첨부한 테스트 프로젝트는 용량 관계상 스크립트 라이브러리 패키지(Nuget)를 삭제한 상태입니다.
   OCX 로드 테스트에 사용한 MSCAL.OCX도 첨부했습니다.
   개발환경 : Win7 32bit, VS2015






[최초 등록일: ]
[최종 수정일: 10/12/2015 ]


비밀번호

댓글 쓴 사람
 



2015-10-12 12시44분
결국, AxImp가 작성해 주는 것은 모든 ActiveX에 대한 공통적인 코드일 뿐입니다. 따라서, clsid나 progid를 넘겨주는 부분을 설정할 수 있도록 하기만 하면 AxImp가 작성해 준 코드를 그대로 재사용할 수 있습니다. 즉, aximp.exe를 같이 배포하지 않아도 됩니다.
정성태
2015-10-13 07시26분
[링크의 전설] 답변 감사합니다.

답변해주신 내용중에 "AxImp가 작성해 준 코드를 그대로 재사용할 수 있습니다"가 구체적으로 어떤 내용인지 잘 이해되지 않습니다.


우선 제가 테스트 한 내용(step2)을 좀더 자세히 설명하면
1. 첨부 파일에 첨부한 MSCAL.OCX를 아래와 같은 명령으로 변환했습니다(예제는 MSCAL.OCX로 한정하여 작성했지만 실제로 대상 OCX는 런타임에 사용자가 결정).
aximp.exe mscal.ocx

변환 결과 아래 두 파일이 생성됩니다.

AxMSACAL.dll(윈폼 래퍼(프록시))
MSACAL.dll(RCW)

2. .Net 클라이언트에서는 AxMSACAL.dll 로드 후 clsid로 Type(AxCalendar)을 객체를 생성/사용했습니다.
   (.Net 클라이언트에서 macal.ocx의 고유의 모든 PME에 .Net 형식의 인터페이스로 접근)

코드를 그대로 재사용하라는 의미가 위의 MSACAL.dll 코드를 참조하여 AxHost를 상속받아 적절하게 구현하여 사용하라는 말씀인가요?
아니면 다른 의미인가요?

제가 질문드린 내용을 다시 한번 정리하면
프로그램 런타임에 특정 ocx가 주어졌을때 aximp.exe로 변환하여 생성되는 윈폼래퍼(위 예에서 AxMSACAL.dll)가 제공하는 수준의 타입(정보(PME))을
aximp.exe를 사용하지 않고
프로그래밍적인 방법으로 클라이언트에게 제공하는 것이 가능한가? 였습니다. 답변해주신 내용이 핀트가 어긋난것은 아닌지 확인차 댓글 달아봅니다.
[손님]
2015-10-13 08시29분
[spowner] 정태님 말은
로딩하고자 하는 n개의 ocx들이 모두 동일한 인터페이스(Property, Method, Event)를 가지고 있는 경우 AxImp를 이용해 한번만 레퍼 클레스를 생성한 후, clsid나 progid를 넘겨주는 식으로 설정만 할 수 있다면
"동일한 인터페이스"로 각각의 ocx에 aximp.exe 없이 사용가능하다는 얘기로 이해합니다.

어쩌면 AxHost클래스를 이용해 각각의 Property, Method, Event에 대한 레핑을 만든 후 사용한다라면 AxHostEx로도 사용 가능할 것 같은데요..
만약, 각각의 ocx에서 제공하는 Property, Method, Event가 동일한 인터페이스가 아니라면 역시 AxHost에 관련 호출 가능한 invoke 기능이 제공할 것도 같습니다.

한번 첨부파일을 받아 저도 한번 테스트를 해봐야겠습니다 하하
[손님]
2015-10-13 11시37분
아... 제가 실수했습니다. 부분적으로만 보고 답변을 드렸군요. 원하시는 것이 로드뿐만 아니라 해당 ocx에 포함된 멤버(Method, Event...)도 동적으로 알고 싶다고 하셨는데, 이것이 가능하려면 COM의 TypeLibrary를 해석해야 합니다. (TypeLibrary는 닷넷의 메타데이터라고 보시면 됩니다.) 다행히 이런 기능을 이미 mscorlib 어셈블리에 TypeLibConverter.ConvertTypeLibToAssembly라는 메서드로 제공하고 있는데요. 사실 AxImp.exe도 .NET Reflector로 보면 결국 저 메서드를 내부적으로 호출하고 있습니다.

자세한 것은 제 설명보다는 AxImp.exe를 .NET Reflector로 보시고 필요한 코드만 가져가 사용하시면 될 듯 합니다.

하지만, 차라리 그러느니 그냥 AxImp.exe를 사용하시는 것이 속편할지도 모릅니다. 첨부하신 소스코드에 보면 "간헐적으로 에러가 난다"고 했는데요. 그 부분의 코드를 File.Exists로 하지 말고 process.WaitForExit()로 바꿔서 처리하시면 좀더 안정적으로 동작할 것입니다.
정성태
2015-10-14 12시56분
[링크의 전설]

어둠이 걷히고 빛이 보이네요!!

AxImp.exe를 리플렉터로 까보면되는군요(아...생각해보면 당연한건데 답변을 보기전까진 미처 생각지 못했습니다;;하하).

아무튼 이제 어떻게든 해볼 수 있을 것 같습니다(일단은 시간 관계상 AxImp.exe를 사용할 것 같습니다만).

답변해주신 두분 정말 감사합니다.
[손님]

... 16  17  18  19  20  21  22  23  24  25  26  27  [28]  29  30  ...
NoWriterDateCnt.TitleFile(s)
3655iwc11/30/20154161    답변글 [답변]: C# Lock 관련해서 질문드립니다.
3631강준10/26/20155979iis 8.5 preload 기능에 대해 질문이 있습니다. [11]
3630김정훈10/25/20154468몬티홀 게임 관련 질문 [1]
3629pooq10/23/20155062리플렉션 관련해서 질문 입니다. [3]
3628최영민10/22/20154363스마트 클라이언트 로딩속도 문의입니다. [3]
3627양주호10/22/20154647C#으로 컨버팅 하려고 하는데요... [1]
3626조성진10/21/20155390책보고 첫번째 예제부터 문제가 생기네요 ^^; [4]파일 다운로드1
3623Beren Ko10/19/20154734질문이라기 보단... [2]
3625Beren Ko10/20/20154848    답변글 [답변]: 질문이라기 보단... [2]파일 다운로드1
3621힘찬도약10/18/20154855[C# 6.0]multi threading과 ui control [9]
3624힘찬도약10/19/20155401    답변글 [답변]: [C# 6.0]multi threading과 ui control [6]파일 다운로드1
3620popo10/13/20154302WPF의 datagrid, listview 컨트롤 관련 질문 입니다. [1]
3619링크의 전설10/12/20157589OCX 로드 관련 질문입니다. [5]파일 다운로드1
3616수요일밥시간10/7/20157525몇 가지 오류 (2) [6]
3615김응규10/7/20154434다시한번 질문 드립니다. (이번엔 자세하게 기술했습니다.) [1]
3614김응규10/6/20153620안녕하세요. wcf net.tcp 관련 질문 하나만 올려요~~ [4]
3613강준10/5/20156445IIS Application Pool 시작/중단 에 대한 이벤트 로그는 어디에 남나요??? [2]
3612심심한일요일10/4/20157392몇 가지 오류 [4]
3611나그네9/30/20153893안녕하세요 답글을 이제 보았습니다. [3]
3608기차니9/21/20154677컬럼이 많은 데이터그리드에서 정렬 할 때 속도가 느립니다. [3]
3609기차니9/22/20154733    답변글 [답변]: 컬럼이 많은 데이터그리드에서 정렬 할 때 속도가 느립니다. [1]파일 다운로드1
3610기차니9/23/20154713        답변글 [답변]: [답변]: 컬럼이 많은 데이터그리드에서 정렬 할 때 속도가 느립니다. [5]파일 다운로드1
3606손님9/20/20154565확장 클래스 네이밍 규칙은 어떻게 하시나요? [1]
3605spowner9/18/20154253익명형식을 다른 클래스의 인스턴스로 전달하고 싶습니다. [1]
3604popo9/11/20154331[C#] Singleton 을 사용하면서 궁금한점이 있어 질문 남깁니다. [2]
3603강준9/11/20153644xamarin 을 시작하려고 하는데 혹시 도움이 될만한 사이트나 정보 있으면 공유해 주세요~~ [1]
... 16  17  18  19  20  21  22  23  24  25  26  27  [28]  29  30  ...