15년이 지났지만, 여전한 기괴함


얼마전에 인터넷 결제를 해야할 일이 있었습니다. 이런 일이 있을때 마다 느끼는 것이지만, 왜 이래야만 하는건지 참 답답합니다.


은행에서 사고 발생시 책임을 사용자들에게 돌리기 위해 쓸데없이 절차를 복잡하게 만들어 놓은 것이 아닌가 하는 생각이 모락모락. 뭐, 보안사고 방지를 위한 안전장치 좋습니다. 하지만, 시스템의 보안을 강화하기 보다는 사용자가 개입해야 하는, 뭔가 인증절차를 더 많이 자주 거쳐야 하는 방향으로만 진화하는 것 같아 슬프네요.




패스워드, 암호, 또 패스워드


무슨 암호를 그리도 자주 입력하라고 만들어 놨는지. 이거 메모 안해두면 아주 사이트마다 비밀번호 새로 갱신하느라 시간 다 보냅니다. 암호 규칙도 사이트마다 다 달라서 어떤 놈은 숫자만 8자리 입력해라, 어떤 놈은 특수문자에 대소문자 구분까지 해서 넣어라. 암호를 통일 시키고 싶어도 시킬 수가 없습니다.


매번 비밀번호 찾기를 해서 다시 설정하느라 시간은 두배 ㅠㅠ





이번에는 하나카드의 거지 같은 비밀번호 관리방침 때문에 몇시간을 삽질을 했습니다. 패스워드를 바꾸려는데, 아무리 입력을 해도 입력한 비밀번호가 서로 다르다며 제대로 입력하라고 나오는 바람에 깊은 빡침을 간만에 느껴 봤습니다.





알고보니 하나카드는 비밀번호에 특수문자를 넣으면 안된다는 제약이 있었습니다.

하지만, 결제 화면에서는 해당 메시지가 표시되지 않았으며, 하나카드 홈페이지 웹사이트에 가야 이런 메시지가 제대로 나타납니다.


패스워드 정책이야 각자 지들 마음이니 뭐라 할 수는 없지만, 참 혈압 오르는 경험이었습니다.

패스워드에 특수문자를 넣으면 안되는 사이트는 정말 오랜만에 만나 보는 것 같습니다.

특수문자 대신에 영문 대문자 하나, 소문자 하나를 꼭 조합해서 패스워드를 만들어야 하네요. ㅠㅠ 




왜 이리 많은 프로그램을 설치해야 할까요?


왜 필요한지 모르겠으나 설치하지 않으면 원하는 기능을 사용할 수 없으니 설치하긴 하는데..





이 많은 프로그램들을 왜 매번, 사이트마다 설치해야 하는 걸까요? 설치하고 또 설치하고. 얼마전에 사용한 사이트를 다시 방문해도 또 설치를 해야 합니다.

아, 한번 설치하면 다음 업데이트 때까지 다시 설치 안하면 안될까요? 





아.. 설치중 웹브라우저들 모두 날려버리는 이 멋진 설치 프로그램. 왜 그래야 하는지는 이해를 하지만 (네, 저도 왕년에는 ActiveX 참 많이 만들어 봤습니다. 사실 좀 더 신경쓰면 웹브라우저 모두 닫지 않고 업데이트 되도록 만들 수도 있습니다.) 이거 너무 불편합니다. 

특히, 웹브라우저 여러개 열어두고 작업하는 저 같은 경우는.. 아.. 빡칩니다. 인정사정 없이 사정없이 다른 일로 열어둔 모든 브라우저 다 닫아 버립니다. ㅠㅠ


가장 좋은 방법은 외국 사이트들처럼 아무것도 설치 안하고도 인터넷결제가 잘 되는 것 입니다.




요즘 책은 전자책으로 구매를 하기 때문에 리디북스와 아마존에서 주로 책을 구입합니다.

안타깝게도 리디북스에서는 컴퓨터 관련 기술서적들이 거의 전무한 관계로 기술서적은 별 수 없이 아마존에서 구매하고 있습니다.


덕분에 국내 사이트와 해외 사이트의 구매과정을 자주 비교하게 되는데..

참 달라도 너무 다릅니다.


아마존이야 해외에서도 성공사례로 인정 받는 원클릭 덕분에 클릭 한번만 하면 구매가 됩니다. 더구나 아무런 부가적인 프로그램 설치도 없습니다.

해외에서는 이렇게 간단한 구매가 우리나라에서는 왜 이렇게 복잡해야 할까요?


세계 정상급의 아마존과 대한민국 변방의 인터넷 쇼핑몰과 비교하는건 어불성설인가요?

에이, 그렇지 않습니다. 국내 사이트들도 잘 만들 수 있습니다. 대한민국 법이 그렇게 생겨먹어 강제로 공인인증서 써야하고, 각종 보안모듈 덕지 덕지 발라야 하는 것이죠.




최근엔 핸드폰 소액결제를 자주 이용합니다.


요즘은 모바일 덕분에 구매가 좀 더 쉬워지기도 했습니다. 핸드폰이라는게 본인 신분을 증명해주는 수단이기 때문에 더 편리한 방법들이 가능할 것 일까요?


핸드폰으로 이렇게 쉬운 결제가 왜 노트북 웹브라우저에서는 이렇게 어렵고 복잡해야 하는지 모르겠습니다. 아마존 같이 간단하게 하면 왜 안될까요?

핸드폰 결제는 왜 소액결제 밖에 안될까요?

수백만원이나 수십만원 짜리를 사는 것도 아닌데 말입니다.




PC에서의 인터넷 결제를 계속 이렇게 사용하기 힘들게 만들거면 

핸드폰 소액결제 한도 금액이라도 좀 올려줬으면 좋겠네요.


인터넷 결제 할때마다 이 불쾌한 경험, 언제나 없어질런지.

천송이 코트 사건으로 국내 인터넷 결제 방식이 좀 진화를 하려나 기대를 했지만, 여전한 것으로 보아 언제 나아질런지 기약이 없어 보이긴 합니다.

개선책이라고 내 놓은 것이 ActiveX를 exe 방식으로 바꾸겠다고 하고 있으니 속 터지죠. ㅠㅠ


그래도 많은 분들이 이건 아니다 생각하는 만큼 곧 변화가 일어날 것이라 소망해 봅니다.

인터넷 결제 하느라 소중한 제 시간을 계속 낭비하고 싶지 않습니다.

Posted by 미친병아리
몇년전에 몇번 만들어보고는 만들일이 없었는데, 최근에 ASP에서 호출하여 쓸 수 있도록 하는 콤포넌트를 만들게 되었다.. 오랜만에 새로 만들어 보려니 예전 소스를 봐도 기억도 안나고 삽질의 연속.. 아~ 이래서 기록을 남겨둬야 한다니깡.. 워드 프로세서 문서가 저장된 BLOB 필드를 읽어 웹브라우저에서 보여줄 수 있는 png 이미지 파일로 저장하는 기능을 하는 녀석이었는데, 다른 기능은 어렵지 않게 구현이 가능했는데 COM에 관련된 내용 때문에 삽질이 많았다.. 몇년전에 보고 책꽂이에 먼지만 쌓이던 책을 오랜만에 꺼내 찾기도 하고, 인터넷 검색도 하면서 찾은 내용들을 정리해보자.. VC++ 6.0 기준이라 좀 그렇긴 하다만..

아래 내용의 개발환경은 VC++ 6.0 with SP6 and Platform SDK 2001 Feb, Windows XP Professional with SP2, IIS 5.0에서 이루어졌다..



콤포넌트 만들기
IIS용 컴포넌트는 ATL COM 컴포넌트로 만든다.. 먼저 프로젝트를 생성해야 하는데, 다음과 같은 순서로 따라하면 된다.. 프로젝트 생성후 문제가 없는지 빌드해서 점검해본다..
  1. File 메뉴 > new > Projects 탭에서 ATL COM AppWizard 선택..
  2. Location에서 저장할 경로를 지정하고, Project name에 원하는 이름 입력 후 OK 클릭..
  3. 다음 화면에서 IIS의 ASP 프로그래밍에 사용할 것이므로 DLL로 선택..
  4. 3번 화면에서 MFC를 사용하고 싶다면 Support MFC를 체크한다.. UI에 관련된 클래스들은 아무런 소용이 없지만, CString 등 자료구조 및 유틸리티성 클래스들을 활용하고 싶다면 클릭해야 한다.. 나중에 프로젝트 만들고 나서 MFC를 사용할 수 있도록 만드는 방법도 있을텐데, 찾아보덜 않아 모르겠다.. 난 그냥 무조건 클릭한다.. MFC 관련 클래스들 사용하고 싶어서..
  5. 빌드는 주로 Debug와 Release MinDependency, 이렇게 2개를 주로 사용한다.. 물론, 상황에 따라서는 다른 옵션도 사용하게 되고, 유니코드를 고려한 코딩을 하게 되면 유니코드로 빌드할 수 있다.. 특히, 서버 컴포넌트의 경우 서버에서 실행되는 코드로 조금의 성능향상도 중요할 수 있기 때문에 유니코드로 빌드하면 좋다.. WinNT 계열 (NT를 포함하여 이후 버젼.. 2000, XP, 2003 서버, Vista 등)에서는 유니코드가 기본이며, 하위호환을 위해 다른 인코딩 방식을 지원하는 것이므로 아무리 작은 오버헤드라도 줄이는 것이 중요한 서버에서는 유니코드로 작성하는 것이 좋다.. MinSize와 MinDependency의 차이는 잘 모르겠다..

이렇게 만들어진 코드는 초기화 등의 경우 외에는 실제 코드가 들어가는 것은 적고, 실제 기능 및 동작을 위해서는 소스코드를 추가해야 한다.. 이 클래스가 실제 동작을 담당하는 코드이다..

  1. Insert 메뉴에서 New ATL Object를 선택한다..
  2. Category에서 Objects를 선택하고, Objects에서는 ActiveX Server Component를 선택한다..
  3. 클래스 이름을 입력한다.. Prog ID에 나타난 값이 ASP에서 Server.CreateObject로 생성시 넘기는 값이된다.. Prog ID 값을 잘 기억해 두도록 한다.. 물론, 잊어버려도 "프로젝트명.클래스명 "으로 조합하면 된다.. 최악의 경우에는 GUID를 가지고 레지스트리 편집기에서 검색을 해보면 Prog ID 문자열 값을 알아낼 수도 있다..

    사용자 삽입 이미지


  4. Attributes, ASP 탭 부분은 디폴트로 옵션을 체크한 후 마친다..

사용자 삽입 이미지

사용자 삽입 이미지


이렇게 추가된 클래스에 필요한 메쏘드, 프로퍼티를 추가하게 된다.. 일반적인 함수 및 멤버함수 등을 추가하면 된다.. 필요하다면 이런 클래스를 필요한 만큼 컴포넌트에 계속해 추가해 넣을 수 있다.. 이런 경우 DLL은 하나지만, Server.CreateObject를 분리하여 호출할 수 있게된다..



메쏘드와 프로퍼티 추가
ASP 페이지에서 호출할 수 있도록 메쏘드와 프로퍼티를 추가한다.. 메쏘드는 함수호출을 위해, 프로퍼티는 약속된 값에 접근하는데 편의성을 제공하기 위해 사용된다.. 특정 단위기능을 수행하기 위해서는 메쏘드 호출을, 상태값이나 특정 기능 수행후 결과값을 접근하기 위해서 프로퍼티를 사용한다.. 클래스에서의 멤버함수와 멤버변수와 비슷하다 생각할 수 있다..


메쏘드 추가/수정/삭제하는 방법
클래스 뷰 트리에서 ATL 객체를 추가해 넣을때 입력했던 클래스 이름이 C로 시작하는 것이 있을 것이고, I로 시작하는 것이 보인다.. C로 시작하는 클래스 트리를 펼쳐보면 그 안에 다시 I로 시작하는 인터페이스가 보이는데, 트리상에서 최상단에 I로 시작하는 인터페이스도 같이 보이니 그리로 접근한다.. 물론, C로 시작하는 클래스 밑에서 똑같은 작업을 해도 동일한 작업을 수행할 수 있다..
  1. 마우스 우측버튼을 클릭하여 Add Method를 클릭..
  2. 새로 나타난 다이얼로그 창에 메쏘드 이름과 파라미터 리스트를 입력..
  3. 파라미터 입력시 데이터형과 규칙에 맞게 입력을 해준다..

이 다이얼로그에서 리턴값을 선택할 수 없는 황당함을 느끼게 되는데, 이는 나중에 처리할 것이니 여기서는 일단 넘어간다.. 나도 처음에 이 다이얼로그를 보고 어찌나 황당하던지..

데이터형은 COM에서 사용할 수 있는 자료형들이 많이 있지만 long, double, BSTR, VARIANT 정도만 알고 있으면 된다.. long과 double은 C++에서와 동일하니 같은 의미로 사용하면 되고, 문자열의 경우는 BSTR을, 한 자료형의 배열이나 여러 자료형이 섞인 구조체의 경우는 VARIANT를 사용한다..

아울러 COM 인터페이스를 기술하는 방법의 특이한 점이 메쏘드 패러미터 앞에 [in], [out], [out,retval] 이라는 내용을 명시한다는 점.. 메쏘드 추가시 이 부분까지 같이 명시를 해서 표기를 해주면 더 좋다.. 물론, 여기서는 생략하고 나중에 직접 하나하나 고쳐도 된다.. 생략하면 모두 [in]으로 간주한다..

일단 만들때는 위저드를 통해 뭔가 UI가 제공되지만, 수정과 삭제를 할때는 그러한 UI가 제공되지 않는다.. VC++ 6.0의 한계중 하나인데 일관된 UI를 제공해주지 않는다.. 만들때 뭔가 UI가 나왔으니 수정이나 삭제시에도 기대를 하게 되는 것이 사람 심리인데, 이러한 당연한 기대를 완전 무시하는 것이다.. 수정과 삭제는 편집기 열고 내가 알아서 잘 해야 한다.. 만들때 내가 직접 만들지 않았으므로 어디 어디 코드들이 추가되었는지 알 길이 없는데, 이럴때에는 메쏘드 이름을 가지고 Find In Files를 잘 해서 필요한 곳 빠지지 않고 잘 수정 혹은 삭제가 되도록 신경써야 한다.. 첨 해볼때만 좀 황당하지, 한번만 해보면 별거 아니라는 생각이 든다.. VC++ 6.0에 뭔가 많이 바라지도 않아왔었고, 손으로 열심히 다듬던 코드들인데 새삼스러울 것도 없다..


프로퍼티 추가/수정/삭제하는 방법
프로퍼티는 메쏘드와 방식이 완전 동일하다.. 메쏘드를 추가, 수정 및 삭제를 할줄 안다면 프로퍼티도 동일한 방법으로 하면 된다..



리턴값 넘기기

리턴값을 넘기고 싶은 경우는 패러미터 리스트에서 가장 마지막 패러미터에 [out, retval]를 붙여주면 된다..
예를들면 맨 마지막 파라미터를 [out,retval] int* iResult 라고 했으면 int 값을 리턴으로 넘기는 것이며, [out,retval] BSTR* sFileName 이렇게 하면 문자열을 리턴값으로 넘긴다는 의미가 된다..

따라서, SetImagePath([in] BSTR sPath, [out,retval] int* iResult) 이렇게 메쏘드를 선언했다면 파라미터는 문자열을 넘기는 것 하나이며 정수값을 리턴하는 메쏘드가 되는 것이다..
호출할때는 대략 result = objTestCom.SetImagePath ("경로명") 이런 모습으로 사용하게 된다.. 리턴값을 파라미터 리스트에 정의한다는게 좀 어색하기는 하다.. 아무튼, COM 컴포넌트에서는 이렇게 만들어야 한다.. 이상하지만, 따르는 수 밖에 없다..



리턴값으로 Variant 넘기기
C에는 배열과 구조체라는 것이 있으며 다른 언어에도 이와 상응하는 자료구조가 있을 것이다.. 문제는 언어마다 다른 자료구조를 COM 이라는 환경에서 어떻게 동일한 인터페이스로 처리할 것인가.. 고민의 결과는 바로 VARIANT 이다.. 따라서 기본 자료구조로 해결 안되는 모든 자료구조는 바로 이 Variant로 해결을 해야 한다.. 대부분 배열을 위해 많이 사용된다.. 이를 좀 더 응용하면 여러 상황에서 활용될 수 있을 것이다.. 기본적으로 Variant는 다른 자료형들을 하나로 묶어서 관리할 수 있다..

STDMETHODIMP CTestVariant::ReturnVariant(int iValue, VARIANT *pVal)
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState())

    VARIANT v;
    v.vt = VT_VARIANT | VT_ARRAY;

    int iRowCount    = 3 ;
    int iColumnCount = 2 ;
   
    SAFEARRAY* pSA;
    SAFEARRAYBOUND bnd[2]={{iRowCount,1}, {iColumnCount,1}};
    pSA = SafeArrayCreate(VT_VARIANT, 2, bnd);  
   
    VARIANT* pVar;
    SafeArrayAccessData(pSA, (void**)&pVar);

    for(int i=0 ; i<iRowCount ; i++)
    {
        for(int j=0 ; j<iColumnCount ; j++)
        {
            char szPrint[1024] ;
            sprintf(szPrint, "%d, %d", i+1, j+1) ;

            int iIndex = i + j * iRowCount ;

            USES_CONVERSION ;
            pVar[iIndex].vt = VT_BSTR;
            pVar[iIndex].bstrVal = SysAllocString(T2OLE((TCHAR*)szPrint));
        }
    }    

    SafeArrayUnaccessData(pSA);
    v.parray = pSA;
   
    *pVal = v;

     return S_OK ;
}


Variant를 리턴값으로 넘기는 방법에 대해서는 kindlion님의 글을 보고 참조를 하였다.. 다만, 글에 약간 잘못된 부분이 있어 이 부분은 약간 수정을 했다.. Variant에서는 C++에서와 VB에서 서로 반대로 들어가는 것이 아니고, n*n 배열을 만드는데 있어 C++에서는 연속적인 메모리 공간이고 이를 논리적으로 분리하여 n*n 배열을 만드는 것이니 메모리에 접근할때 논리적으로 구성된 배열처럼 접근하도록 계산을 좀 해야 하는데 이 계산이 kindlion님 말처럼 항상 반대는 아니라는 것.. kindlion님의 글에서는 마침 반대로 되었을 뿐, 이 상황은 배열을 몇 바이 몇으로 만드느냐에 따라 달라질 수 있다.. 해서 n*n 크기의 일반적인 상황에서도 데이터를 제대로 넣을 수 있도록 수정을 해야했다..

iRowCount, iColumnCount 값을 바꿔가며 배열의 생성초기화를 바꿔도 VB에서는 제대로된 값을 가져올 수 있도록 수정된 부분은 위의 샘플코드에서 색상표시가 된 부분이다..   



테스트하기
자, 그럼 이렇게 작성된 코드를 ASP에서 어떻게 활용할 수 있는가 함 보자..

<%
    set objTestCom = Server.CreateObject("Test.TestVariant")

    Dim data
    data = objTestCom.ReturnVariant (1)

    for i=1 to UBound(data,1) step 1
        for j=1 to UBound(data,2) step 1
            response.write data(i,j) & "<br><br>"
        Next
    Next
   
    set objTestCom = nothing
%>


2차원 배열을 받아 화면에 출력해주는 ASP용 코드이다.. 직접 호출을 해주면 C++ 코드에서 넣었던 인덱스 값들이 제대로 출력되는 것을 확인할 수 있을 것이다..

테스트하는 방법은 위의 코드를 ASP 파일로 저장한 후에, IIS가 설치된 사이트 혹은 가상디렉토리에 넣은 후 해당 URL을 호출하면 실행된 결과를 확인할 수 있다.. 테스트하는 PC가 컴포넌트를 빌드하는 PC와 다르다면 개발하는 PC에서 DLL 파일을 테스트용 PC에 옮긴후, 도스창을 열어서 DLL 파일이 복사된 경로로 이동한 후에 다음과 같은 명령을 실행시켜줘야 한다.. "regsvr32 DLL파일명"



디버깅하기

Visual Studio는 강력한 디버깅 환경을 제공하는 것으로 유명한데, IIS 서버 콤포넌트 개발시에는 어떻게 이 강력한 디버거를 활용할 수 있을까? 일반적인 상황처럼 사용할 수는 없다.. 조금은 번거로운 방식으로 디버깅을 해야한다..

  1. 빌드를 한다..
  2. 웹브라우저를 실행시켜 테스트용 페이지를 호출한다..
  3. 작업관리자를 실행시킨다.. 프로세스탭으로 가서 dllhost.exe 프로세스를 찾아 PID를 확인한다.. 여러개가 있는 경우에는 프로세스를 실행시킨 사용자가 인터넷 서비스 계정인 것을 찾는다..
  4. VC++에서 디버깅을 한다.. Build > Start Debug > Attacth to Process 를 클릭.. 새로 뜬 다이얼로그 창에서 Show System Processes를 클릭..  3번 과정에서 확인한 PID를 갖는 프로세스를 선택한 후 OK 버튼을 클릭하면 디버깅이 시작된다..
  5. 디버깅 하고자 하는 코드가 담긴 소스코드 파일을 열어 브레이크 포인트를 걸고 디버깅을 한다..

프로젝트의 워크스페이스 파일이 닫혀 버리니 원하는 소스코드 파일 찾기도 귀찮아지고, 디버깅을 종료했다 다시 시작할때마다 이 과정을 반복해야 하니 여간 귀찮은게 아니긴 하다.. 하지만, 그래도 웹서버와 연동이 되어 돌아가는 DLL 파일을 이렇게라도 디버깅 할 수 있다는게 어딘가.. 이런 방법이 없었다면 별 수 없다.. 천상 로그파일에 로그 찍어가며 디버깅 하는 수 밖에..

디버깅 하는 방법 자체는 VC++ 6.0의 디버거를 사용하는 것과 동일하니 이 내용은 생략한다..

여러번 반복해보면 알겠지만, 다른 프로그램이 추가로 실행되지 않는다면 3번 과정을 생략할 수 있다.. 바로 4번으로 넘어가도 우리가 원하는 프로세스가 뭔지 알 수 있다..

위와 같은 과정을 계속해서 반복해야 하는데 이를 좀 더 편하게 하는 팁이 몇개 있다.. 내가 주로 사용하는 팁인데, 우선 개발환경과 테스트 환경을 한데 붙여 한 PC에서 수행하는게 편하다.. 이를 위해서는 XP의 경우 반드시 Professional 이상을 사용해야 한다.. 그 이하에서는 IIS가 설치되지 않기 때문에..

두번째로는 VC++을 하나는 소스코드 수정 및 콤포넌트 빌드용, 다른 하나는 디버깅용 이렇게 2개를 동시에 띄워놓고 사용하는 것이 편하다.. 일반적인 디버깅 환경과 달리 Attach Process를 통한 디버깅은 소스코드 워크스페이스가 닫혀 버리기 때문이다.. 매번 열고 닫고 하기가 귀찮으니 하나는 코드수정 및 빌드용으로, 다른 하나는 디버깅 전용으로 2개를 동시에 실행시켜두고 사용하는 것이 편하다..

마지막으로, 정말 귀찮은 작업중에 하나가 웹서버를 계속 내렸다 올렸다 하는 것이다.. IIS는 서버 컴포넌트를 한번 올리면 메모리에 올려두기 때문에 코드를 수정한 경우 수정된 코드가 반영되지 않는다.. IIS가 파일을 물고 있기 때문에 VC++이 새로운 DLL을 덮어쓰지 못하기 때문이다.. 따라서 IIS를 재기동 시키는 일이 자주 반복되는데 이거 여간 귀찮은게 아니라서 마우스 더블클릭 혹은 커맨드라인에서 쉽게 실행시킬 수 있도록 bat 파일을 하나 만들었다..

net stop W3SVC
net stop IISADMIN
net start IISADMIN
net start W3SVC


위의 내용을 담은 텍스트 파일을 하나 만들고, 파일명을 ReStartIIS.bat 으로 바꾸면 된다.. 명령어는 XP에 IIS 5.0을 사용했을때 기준이며, Windows 2003의 경우에는 명령어가 약간 다를 수도 있다.. 이 bat 파일을 VC++의 Tools 메뉴에 등록시켜두면 단축키로 쉽게 웹서버를 내렸다 올렸다 할 수 있다..



Posted by 미친병아리
새로운 OS가 나오게 되면 가장 관심을 가지는 것은 과연 내가 만든 프로그램이 새 OS에서 정상적으로 동작할 것인가 하는 점이다.. 윈95가 등장할때 그랬으며, 윈98, 윈ME, 윈2000, 윈XP 등등.. 이번 윈도우 비스타도 예외는 아니었지만, 그러면서도 안심이 되는 부분은 MS가 새 OS를 내 놓을때 가장 신경을 많이 쓰는 부분이 다름아닌 하위호환성 보장이라는 것.. 새 OS들이 나올때마다 걱정은 했지만, 별 일 없이 넘어갈 수 있었던 것이 바로 이 부분 때문이었으며, 이번에도 큰 어려움 없을 것이라는 안일한 자세.. 사실 윈3.1에서 윈95로 넘어갈때 말고는 큰 일이 없었던것이 사실이다.. (Microsoft가 그렇게 중요시 하는 하위호환성에 대해 자세히 느껴보고 싶으면 조엘 온 소프트웨어를 읽어보시길..)

하지만, 윈도우 비스타는 달랐다.. 많이 달랐다.. 윈XP에서 잘 돌아가는 프로그램을 윈도우 비스타에서 돌아가게 만드는데 무려 2달 정도가 걸렸다.. 물론, 다른 일들이 많아 팀원 전체가 붙어 대응을 하지 못해 오래 걸리긴 했지만, 애초에 예상했던 것 보다는 훨씬 오래걸린 대응 준비기간이었다..

우리 프로그램의 문제점
- ActiveX 컨트롤
- 레지스트리
- 파일저장
- 프로세스 생성
- 윈도우 메시지 전달
ActiveX 컨트롤은 사실 아무런 문제없이 윈도우 비스타로 옮길 수 있다.. 윈도우 비스타라고 해서 ActiveX 컨트롤이 없으질게 아니고 (Silverlight도 윈도우 환경에서는 ActiveX로 구현되며, 플래쉬, 애크로뱃리더도 ActiveX로 구현되어 있기 때문에 대체기술이 나오기 전에는 없어질 리가 없기 때문에.. 대체기술은 웹표준이 그래픽과 멀티미디어쪽으로 확정되기 전에는 오랜기간 없을 것으로 보인다..) 기본적으로 우리 프로그램도 아무런 문제가 없었지만, 레지스트리와 파일억세스를 하는 부분이 많았다..

레지스트리 접근은 HKEY_CURRENT_USER 하위는 읽고 쓸 수 있기 때문에 위치만 옮기면 아무런 문제가 되지 않는다.. 물론, 현실에서는 이 위치를 공유하는 프로그램들이 많을 수 있고, 어떤 프로그램에서는 위치를 변경하는게 만만한 작업이 아닐 수 있기 때문에 현실은 그리 녹녹치 않을 수도 있다.. 가장 좋은 방법은 레지스트리 사용은 아예 하지 않도록 수정하는 방법이 정답이다.. 하지만, 우리 프로그램은 새 버젼이 개발중이었으므로 최소한의 노력을 들이기로 했다..

파일저장 부분도 사실 큰 어려운 부분은 아니지만, 레지스트리의 경우와 비슷하다.. 권한이 없는 폴더에는 접근하지 않도록 수정해줘야 한다.. 특히, 권한을 가진 프로그램이 만들어둔 파일을 다른 프로세스에서 접근해야 하는 경우 문제가 생길 수 있다.. 가장 문제가 되는 것이 ActiveX 컨트롤이 접근해야 하는 경우인데, 이 경우는 ActiveX 컨트롤이 해당 파일에 접근할 수 있는 방법이 없으므로 권한이 낮은 프로세스에서도 접근 가능한 위치로 옮겨야 한다..

프로세스 생성은 비교적 간단하다.. ShellExecute에 추가된 파라미터를 넣어 높은 권한으로 실행시킬 수 있는 방법이 있기 때문이다.. 하지만, 원래 권한이 낮은 곳에서 (다른 프로세스나 ActiveX 컨트롤이) 높은권한의 프로세스를 실행시키는 일이라 권한상승 경고창이 뜬다..

윈도우즈 메시지 전달은 사실 별로 신경을 쓰지 못했던 부분인데, 낮은 프로세스에서 높은 프로세스로 메시지를 보내는 것은 사정없이 무시된다.. 특히, ActiveX 컨트롤이 실행파일을 실행시킨 후에 메시지를 통해 데이터를 전달하는 구조의 경우 문제가 된다..

하지만, 위의 문제들을 해결하기 위해 그동안 여러가지 검토를 하고 테스트 코드를 짜며 든 생각은 과연 무엇이 더 좋아졌는가 이다.. 좋아진 부분이 딱 하나 있기는 하다.. 권한이 상승된 프로세스가 허락없이 실행될때 경고창이 뜬다는 것이다.. 이점은 나 몰래 어떤 프로그램을 실행시키기가 더 어려워 졌다는 점에서 보안이 강화되었다고 할 수 있는데, 이외의 것들은 소위 하위호환성 때문에 조금만 코드를 고치면 XP에서 동작했던 것 처럼 동작하도록 수정할 수 있다.. 어찌 보면 내가 예상한대로였는데, 작년말쯤 팀원들과 이야기 하던 내용이 기억난다.. "그렇다면 좋아질게 하나도 없는데, 그렇게 고칠거면 뭐하러 고치나?"

열심히 함 고쳐보라는건가? 뭐하러 이런 소모적인 해야 수정을 하는지 모르겠다.. 되먹지 않은 악성 프로그램을 배포하는 사람들이 코드 좀 수정해서 비스타에서도 동작하도록 만들게 하기 위해, 전 세계 수많은 프로그래머들이 비스타에서 돌아가는 프로그램을 위해 코드를 수정하게 만들어야 했는가? 하위호환성 때문에 피해가는 방법이 다 존재한다면, XP에서 문제없이 돌아가는 프로그램은 비스타에서도 그냥 돌아가도록 하는게 더 좋았을 것이다.. 그렇다 하더라도 권한상승창 때문에 원래의 목적은 달성할 수 있었을 것이다.. 참, 아쉬운 부분이다..

권한 상승창이 뜨는 부분은 비스타 사용자들로부터 많은 이야기가 나올 것인데, 윈도우 비스타에서 깔끔하게 돌아가는 프로그램을 만들기 위해서 (권한상승 허가하는 창이 뜨지 않고 동작하도록)는 앞으로는 개발초기 설계시부터 잘 고려를 해야하겠다..


Posted by 미친병아리