MenuIcon

Owl-Networks Archive

LoginIcon

Perl : ActivePerl 과 Strawberry Perl 을 함께 사용하기

| 분류: Perl | 최초 작성: 2012-02-12 06:52:16 |

이 게시물은 국내 Perl 커뮤니티의 @aer0 (http://twitter.com/aer0) 님께서 알려주신 기본적인 설정 방법을 소개하고, 이를 좀 더 편리하게 사용할 수 있도록 조금 더 살을 붙여서 작성한 것입니다.


1. 윈도우용 Perl 의 양대산맥 - ActivePerl 과 Strawberry Perl


윈도우에서 사용되는 Perl 바이너리 중 대표적인 것을 두 개만 말한다면 단연 이 두 개의 바이너리를 이야기할 수 있다. ActivePerl 과 Strawberry Perl 이 그것이다. 물론 이 두 개의 Perl 바이너리 말고도 몇 가지의 윈도우용 Perl 바이너리가 더 있지만, 필자 역시 이 두 바이너리 이외의 바이너리는 사용해 본 적이 없다. (아, 예전에 Indigo Perl 을 잠깐 써본 적이 있긴 하다. 문자 그대로 "써 보기만" 했기 때문에 이에 대해서는 전혀 할 말이 없다.)

* ActivePerl : http://www.activestate.com/activeperl
* Strawberry Perl : http://www.strawberryperl.com/

두 바이너리 모두 기본적으로 Perl 이라는 점에 있어서 동일하다. 약간의 미묘한 차이가 있지만 같은 버전에서는 기본적인 사용법이나 호환성에 큰 차이가 없다. ActivePerl 은 MS VC++ 을 이용하여 컴파일한 Perl 바이너리이며, Strawberry Perl은 오픈소스 컴파일러인 gcc 를 이용하여 컴파일한 Perl 바이너리라는 점이 가장 큰 차이점이라고 한다.

국내 Perl 커뮤니티의 분들 사이에서는 ActivePerl 보다는 Strawberry Perl에 대한 선호도가 더 높은 것 같다. 정확한 이유는 필자도 모르겠다. 지금은 Strawberry Perl 에서도 PPM 을 지원하므로, 모듈 설치의 편의성 등에서도 별 차이가 없어졌다고 생각된다.


필자의 경우 기본적으로 ActivePerl 을 사용하고 있다. 특별한 이유가 있는 것은 아니고, 처음에 사용하기 시작한 것이 ActivePerl 이었기 때문에(당시에는 Strawberry Perl이 아직 등장하기 전이었다. 아니면 이미 등장했었으나 필자가 몰랐을 수도.) 계속 이를 사용하고 있을 따름이다. 한때 PPM 의 존재가 계속 ActivePerl 을 사용하는 이유가 되었던 시기도 있었으나, 지금은 Strawberry Perl 에서도 PPM 을 지원하기 때문에 더 이상 그것이 이유가 되지는 않는다.


2. ActivePerl 과 Strawberry Perl 을 함께 사용하기


사실 두 바이너리를 동시에 사용하여야 할 이유는 그다지 크지 않을지도 모르겠다. 오히려, 여러 버전의 Perl 을 함께 사용하는 데에 이 팁을 적용하는 것이 더 유용할지도 모른다. 어떻게 사용하든 사용하는 사람 마음이다. (필자의 경우는 주로 사용하는 바이너리는 ActivePerl 이지만, 작성한 Perl 어플리케이션을 배포하기 위하여 Strawberry Perl 을 사용한다.)

일단 ActivePerl 이건 Strawberry Perl 이건, 두 바이너리 모두 설치되면서 시스템에 특별한 조작을 가하지 않는다는 점을 짚고 넘어가야 한다. 즉, Perl을 설치하기 전후로 레지스트리나 시스템 설정 등에 특별한 변화가 없다는 것이다. (설치 프로그램이 .pl 파일을 자신이 설치하는 perl.exe 와 연결하는 것은 별론으로 하자. 이 한도 내에서는 레지스트리의 항목에 변화가 있다.) 기본적으로 모든 설정 항목들은 Perl 이 설치되는 폴더 이하에 기록된다. 따라서, 두 개의 Perl 을 모두 설치한다고 하더라도 설치 폴더만 다르다면 이 둘은 전혀 충돌하지 않고, 문제도 일으키지 않는다.

다만, Strawberry Perl의 경우에는 공식적으로 무설치(포터블)버전을 함께 공개하고 있기 때문에, 안전을 기하기 위해 이 쪽을 사용하는 것도 좋다.


그렇다면, 두 개의 Perl 이 모두 설치되어 있는 시스템에서 perl.exe 를 실행한다면 어느 쪽이 실행될까? 답은 "시스템 경로(PATH) 의 앞 쪽에 등록되어 있는 쪽이 실행된다" 이다. (물론 .PL 파일이 특정한 Perl 바이너리에 연결되어 있는 상태에서 탐색기에서 .PL 파일을 더블클릭했다면 그 특정한 Perl 이 실행될 것이다. 이건 예외다. 이 확장자 등록 기능은 잠재적으로 문제를 일으킬 가능성을 가지고 있는데, 이에 대한 내용은 이 글의 제일 끝 부분에서 추가로 논의할 것이므로 반드시 함께 알아두기 바란다.)

따라서, PATH 에 두 개의 Perl 경로를 필요할 때마다 선택적으로 추가해 주는 방법만으로, 두 개의 Perl 바이너리를 선택적으로 실행할 수 있다. 이 방법은 서로 다른 여러 개의 Perl 버전을 선택적으로 구동해야만 할 때에도 사용 가능한 방법이다.

1. Strawberry Perl 을 사용해야 하는 경우 :

다음의 세 개의 폴더를 PATH 에 추가한다. (설치 폴더가 C:\Strawberry 인 경우를 가정했다.)

* C:\strawberry\perl\bin
* C:\strawberry\perl\site\bin
* C:\strawberry\c\bin

덧붙여, 환경 변수에 TERM=dumb 라는 항목을 추가해야 한다. (이유는 모른다.) 이를 배치 파일로 만들면 다음과 같이 된다. [다운로드 (크기: 193Byte)]

@ECHO OFF
PATH C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;C:\strawberry\c\bin;%PATH%
SET TERM=dumb
CMD

이 배치 파일을 실행하면 콘솔 창이 뜨게 되는데, 이 콘솔 창에서는 Strawberry Perl 을 메인 Perl 바이너리로 사용할 수 있다.


2. ActivePerl 을 사용해야 하는 경우

다음의 두 개의 경로만 PATH 에 추가해 넣으면 된다. (설치 경로가 C:\Perl 인 경우를 가정했다.)

* C:\Perl\site\bin
* C:\Perl\bin

이를 배치 파일로 만들면 다음과 같다. [다운로드 (크기: 208Byte)]

@ECHO OFF
PATH C:\Perl\site\bin;C:\Perl\bin;%PATH%
CMD

이 배치 파일을 실행하여 출력되는 콘솔 창에서는 ActivePerl 을 메인 Perl 바이너리로 사용할 수 있다.

양 쪽 모두에 있어서, 하나의 바이너리의 여러 버전을 선택하여 사용하는 경우에도 위와 같은 방법을 사용하면 된다. 각각의 버전은 별도의 폴더에 설치되어 있을 것이 요구된다.


다만 한 가지, 위의 방법으로 변경한 PATH 환경 변수는 그 PATH 변경과 함께 출력된 콘솔 창 안에서만 유효하다. 각각의 콘솔 창은 독립된 명령 처리기이므로 이는 어쩌면 당연한 것이다.

위 두 배치 파일을 하나의 배치 파일로 묶을 수도 있다. 다음의 배치 파일은 이를 통합한 것이다. 배치 파일 실행 후 1번을 입력하면 ActivePerl 을, 2번을 입력하면 Strawberry Perl 을 메인 바이너리로 사용하는 콘솔 창을 열게 된다. (윈도우에서 기본 제공하는 CHOICE 명령을 이용하여 구성하였으나, 인자를 받는 방식으로 구성하여도 상관 없을 것이다.) [다운로드 (크기: 362Byte)]

@ECHO OFF
ECHO.
ECHO 1. Open ActivePerl Console Window
ECHO 2. Open Strawberry Perl Console Window
ECHO 0. EXIT
ECHO.
CHOICE /C 120 /N /M "Choice: "

IF ERRORLEVEL 3 GOTO END
IF ERRORLEVEL 2 GOTO STRAWBERRYPERL
IF ERRORLEVEL 1 GOTO ACTIVEPERL

GOTO END

:ACTIVEPERL

@ECHO OFF
PATH C:\Perl\site\bin;C:\Perl\bin;%PATH%
SET TERM=
CMD

GOTO END

:STRAWBERRYPERL

@ECHO OFF
PATH C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;C:\strawberry\c\bin;%PATH%
SET TERM=dumb
CMD

GOTO END

:END



3. 콘솔 창이 열릴 때 특정한 폴더에서 열도록 하기


이 항목은 다음 문서를 바탕으로 작성되었습니다 :

윈도우 7 / 윈도우 탐색기의 특정 폴더를 클릭하여 콘솔 모드 열기 : http://www.owlnetworks.pe.kr/document/read/412


위에서 만든 배치 파일을 조금 더 개선해 보자. 콘솔 메뉴가 열릴 때에 시작되는 폴더는 항상 일정한 위치로 고정되어 있다. 관리자 권한 하에서 실행된다면 C:\WINDOWS\SYSTEM32, 관리자 권한이 아니라면 각 개인 폴더에서 열린다. 그러나 대개 스크립트는 그 위치에 있지 않을 것이다. 그 결과 원하는 스크립트를 실행하기 위해 몇 단계의 폴더 이동을 거쳐야 한다. 이런 불편함을 개선하기 위하여, 탐색기에서 특정 폴더를 우클릭하여 그 폴더에서 콘솔 메뉴가 오픈되도록 할 수도 있다. 이 기능을 사용하기 위해서, 위 배치 파일을 아래와 같이 조금 수정하여 특정한 폴더에 저장한다. [다운로드 (크기: 371Byte)]

@ECHO OFF
ECHO.
ECHO 1. Open ActivePerl Console Window
ECHO 2. Open Strawberry Perl Console Window
ECHO 0. EXIT
ECHO.
CHOICE /C 120 /N /M "Choice: "

IF ERRORLEVEL 3 GOTO END
IF ERRORLEVEL 2 GOTO STRAWBERRYPERL
IF ERRORLEVEL 1 GOTO ACTIVEPERL

GOTO END

:ACTIVEPERL

PATH C:\Perl\site\bin;C:\Perl\bin;%PATH%
SET TERM=
CMD /k cd /d "%1"

GOTO END

:STRAWBERRYPERL

PATH C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;C:\strawberry\c\bin;%PATH%
SET TERM=dumb
CMD /k cd /d "%1"

GOTO END

:END


각각 CMD.EXE 를 실행하는 부분에 옵션으로 /k cd /d "%1" 이 들어간 것을 알 수 있다. /k 옵션을 붙이면 뒤에 따라오는 명령을 실행한 후에도 콘솔 창이 꺼지지 않기 때문에, 사용자는 계속 같은 환경에서 명령어를 입력하여 콘솔 창을 사용할 수 있다. CD 명령에 /D 옵션을 사용하면 폴더 외에 드라이브도 변경할 수 있으므로 드라이브 까지 변경되는 경우에도 오류 없이 한 번에 원하는 폴더로 찾아갈 수 있다. %1는 반드시 큰따옴표로 묶어주어야 중간에 공백문자가 있는 폴더를 찾아갈 때 오류가 발생하지 않는다.

이제 이 배치 파일을 실행할 레지스트리 항목을 등록해야 한다. 다음 레지스트리 항목을 등록한다. 위의 배치 파일을 PerlSel.bat 라는 이름으로 C:\ 에 저장하였다고 가정한 것이므로, 각자의 환경에 따라 적절히 수정한다. PerlSel.bat 배치 파일은 정확한 경로까지 입력해주어야 제대로 실행된다. [다운로드 (크기: 405Byte)]

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Drive\shell\cmdsperl]
@="Perl 바이너리를 선택하여 폴더 열기"

[HKEY_CLASSES_ROOT\Drive\shell\cmdsperl\command]
@="C:\\PerlSel.bat \"%1\""

[HKEY_CLASSES_ROOT\Directory\shell\cmdsperl]
@="Perl 바이너리를 선택하여 폴더 열기"

[HKEY_CLASSES_ROOT\Directory\shell\cmdsperl\command]
@="C:\\PerlSel.bat \"%1\""


Drive 와 Directory 에 모두 등록하여, 대상 스크립트가 특정 드라이브의 루트 폴더에 있는 경우에도 찾아갈 수 있도록 한다. 이제 탐색기에서 특정한 폴더를 마우스 우클릭하면 다음과 같은 화면이 나타나게 된다.

임의의 폴더를 마우스 우클릭하면 이와 같이 Perl 바이너리를 선택하여 콘솔 창을 여는 메뉴가 나타난다.
임의의 폴더를 마우스 우클릭하면 이와 같이 Perl 바이너리를 선택하여 콘솔 창을 여는 메뉴가 나타난다.


이후의 과정은 위에서 본 것과 똑같고, 다만 시작 폴더만 선택한 폴더로 바뀌게 된다.


4. 특정한 바이너리를 이용하도록 하는 메뉴 출력하기


때로는 굳이 콘솔창을 열 필요 없이, 특정한 바이너리를 이용하여 특정한 스크립트만 일시적으로 실행하고 싶은 경우도 있을 수 있다. 이런 경우를 위하여 .PL 파일을 마우스 우클릭하였을 때 바이너리를 지정하여 실행하는 메뉴를 넣을 수 있다. 아래에 이를 추가하는 레지스트리 파일을 기술하였다. 참고로, 이 내용이 잘못 변경되면 .PL 파일의 연결이 끊어지는 사태가 벌어질 수 있으므로, 가능하다면 기존의 레지스트리 내용이 있다면 백업한 후에 이 레지스트리를 실행하도록 한다. 백업할 레지스트리는 다음의 두 항목이다.

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.pl
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Perl


이하는 레지스트리 파일의 내용이다. ActivePerl 은 C:\Perl 이하에, Strawberry Perl은 C:\Strawberry 이하에 설치되어 있다고 가정한다. [다운로드 (크기: 419Byte)]

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\.pl]
@="Perl"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Perl\shell\OpenWithActivePerl]
@="Run with Activeperl"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Perl\shell\OpenWithActivePerl\command]
@="C:\\Perl\\bin\\perl.exe \"%1\""

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Perl\shell\OpenWithStrawberryPerl]
@="Run with StrawberryPerl"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Perl\shell\OpenWithStrawberryPerl\command]
@="C:\\Strawberry\\Perl\\bin\\perl.exe \"%1\""


위의 레지스트리 파일을 적용한 후 .pl 파일에 마우스 오른쪽 버튼을 클릭하면 다음과 같이 바이너리를 선택하여 실행할 수 있는 메뉴 항목이 출력된다. 이제 둘 중 하나를 선택하여 스크립트를 실행하면 되겠다.

임의의 .PL 파일을 마우스 우클릭한 화면. 어떤 바이너리를 사용하여 열 것인지 선택할 수 있다.
임의의 .PL 파일을 마우스 우클릭한 화면. 어떤 바이너리를 사용하여 열 것인지 선택할 수 있다.


특정한 확장자에 대해 컨텍스트 항목을 연결하는 방법은 다음의 문서를 참조하였습니다.:

마우스 우클릭으로 .java 컴파일과 .class 실행하기 : http://snoopybox.co.kr/1457


이를 조금 더 응용하여, 이런 경우도 생각할 수 있다. 위의 레지스트리에서는 각각의 항목에 대해서 바로 해당 perl.exe 를 호출하여 실행하도록 설정되어 있는데, 이런 경우에 (혹시라도) PATH 의 설정과 관련하여 문제가 발생할 여지도 있을 수 있다. (물론 필자의 경우에는 그런 문제가 발생하지 않았다. 그러나 가능성이 있을 것 같아서 하는 첨언이다.) 만약 이런 가능성마저 원천봉쇄하고 싶다면, 각각의 Perl 바이너리에 관하여 배치 파일을 작성해 둔 후, 레지스트리의 각 실행 메뉴의 연결을 배치 파일로 해 두면 된다. 예를 들면 이렇다. 만약 Strawberry Perl 의 설치 경로가 C:\Strawberry 이하라고 가정하자. 그리고 다음과 같은 배치 파일을 perlrun.bat 라는 이름으로 C:\Strawberry 폴더에 저장했다고 생각하자.

@ECHO OFF
PATH C:\strawberry\perl\site\bin;C:\strawberry\perl\bin;C:\strawberry\c\bin;%PATH%
SET TERM=dumb
perl %1
pause


그리고 위 레지스트리 파일 중 Strawberry Perl 과 관련된 항목을 다음과 같이 변경한다. 제일 마지막 줄의 command 부분만 변경하면 된다.

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Perl\shell\OpenWithStrawberryPerl\command]
@="C:\\Strawberry\\perlrun.bat \"%1\""


이렇게 하면, "Run with StrawberryPerl" 을 선택하면 방금 저장했던 배치 파일이 실행되면서 우선 PATH 를 Strawberry Perl 로 변경한 후 선택된 .pl 파일을 실행하게 된다. Strawberry Perl 에 대해서만 예를 들었지만, ActivePerl 에 대해서도 PATH 부분만 변경하면 그대로 적용이 가능하다.

물론 이 방법은 문제점이 있다. 실행하려는 스크립트에 대해서 인자를 넘겨줄 수 없다는 것이다. 인자와 함께 실행하기 위해서는 콘솔 모드상에서 직접 해당 스크립트를 인자를 주어 실행하는 방법을 써야 한다. 특정한 바이너리를 선택하여 특정한 폴더에서 콘솔 창을 여는 방법은 위에서 이미 보았으므로 생략한다.



5. ActivePerl과 StrawberryPerl을 함께 사용할 때의 유의사항 (2012년 3월 27일 추가)


윈도우의 확장자 연결 기능을 사용하면, .PL 확장자를 Perl에 연결할 수 있다. 사용자가 수동으로 제어판 또는 탐색기에서 연결할 수도 있고, Perl 을 설치할 때 설치 옵션으로서 확장자 연결을 줄 수도 있는데, 설치 프로그램을 이용하여 설치를 했다면 대개 설치 시 확장자 연결을 했을 것이다.

이렇게 확장자 연결을 해 두면 탐색기에서 .PL 파일을 더블클릭하여 바로 실행이 가능해지므로 상당히 편리해진다. 또 이 확장자 연결은 콘솔 모드에서도 유효하므로, CMD 창에서 다음과 같은 두 개의 명령 모두 유효하게 현재 폴더의 makefile.pl 을 실행하게 된다.

perl makefile.pl
makefile.pl


그런데, 이 부분 때문에 예기치 않은 오류가 발생하는 경우가 있다. 예를 들면, 현재의 PATH 에는 Strawberry Perl 이 있고, 확장자 연결은 ActivePerl로 되어 있을 경우, 위의 두 명령 중 perl 을 붙인 명령은 PATH의 연결을 따라 Strawberry Perl이 실행되지만, 아래쪽의 perl 없이 바로 파일명을 입력한 명령은 PATH와 관계 없이 확장자 연결을 따라 ActivePerl이 실행되게 된다. 그 결과, 필요한 환경 변수가 달라지거나, 필요한 모듈을 찾을 수가 없다는 등의 예기치 않은 오류를 만나게 될 수도 있다.

doomed.png


위 그림은 실제로 발생한 난장판의 예인데, 모듈의 설치를 위해 makefile.pl 을 실행하면서 무심결에 perl 을 빼고 바로 파일명을 입력한 탓에 생성된 설치 스크립트가 완벽하게 꼬여버렸다. 왼쪽이 정상적으로 만들어진(perl makefile.pl 실행 결과) 설치 스크립트이고, 오른쪽이 잘못 꼬여버린(makefile.pl 실행 결과) 설치 스크립트다. 오른쪽 이미지를 보면, C:\Strawberry 이하의 경로를 가리켜야 정상인 스크립트 설정 중 일부가 C:\usr 이하(여기에는 ActivePerl이 설치되어 있다)를 가리키고 있다. 그 결과 설치 중 계속적으로 원인을 알 수 없는 오류를 만났고, 원인을 찾느라 한참의 시간을 낭비해야 했다.

따라서, 두 개 이상의 Perl 바이너리를 이 방법으로 사용하는 경우, 현재 실행되는 Perl 바이너리가 어느 쪽 버전인지를 분명하게 해 주어야 한다. 특히 콘솔에서 실행 시 perl 을 빼고 입력하는 것은 상당히 위험하다. 가능하면 확장자 연결 기능을 사용하지 않는 것이 더 좋을지도 모르겠다.

☞ 태그: Strawberry Perl, ActivePerl,

☞ 트랙백 접수 모듈이 설치되지 않았습니다.

☞ 덧글이 1 개 있고, 트랙백이 없습니다.

덧글을 남기시려면 여기를 클릭하십시오.

□ 저니리 님께서 2012-02-17 23:19:44 에 작성해주셨습니다.

ActivePerl에서 cpan을 지원하더구만... cpan을 실행하면 MinGW를 다운받기 시작더만.... 과거 윈도우에서는 컴파일러의 부재로 인하여 ActivePerl이나 Straberry Perl이나 cpan을 사용하지 못했는데, 지금은 다 쓸 수 있게 해놨더군... 내가 Perl 가지고 끄적 거릴 때는 되는 게 없었는데 말이야.... ActivePerl의 경우 패키지 매니저로 윈도우에 설치될 수 있는 패키지는 미리 자기들이 받아서 컴파일 해놔서 64비트나 32비트에 관한 문제가 발생하지 않도록 막아주니 윈도 환경에서는 ActivePerl이 현재로써는 더 좋은게 분명하오. 64비트 윈도에서 Win32::GUI는 ActivePerl이 아니면 깔 방법이 없소.

그렇지만!!!

Perl은 전통적으로 리눅스에서 사용되는 일이 많은 녀석이오. 물론 리눅스에 설치나 실행이 불가능한 패키지가 있는 것도 사실이지만, 리눅스의 시스템 함수나 라이브러리를 참조하는 패키지도 졸라게 많은게 사실.

아래는 만들다가 만 거. (옆에서 C#으로 만든 걸 기다리는 중... 개발 속도가 너무 차이가 나서 따라갈 수가 없어...)

use Win32::GUI;
use Win32::GUI::Grid;
use Carp;
use FindBin;
use Win32::OLE qw( EVENTS );
use Number::Format qw(:subs);

#my $DOS = Win32::GUI::GetPerlWindow();
#Win32::GUI::Hide($DOS);

my $DEFAULT_USR_ID = '';
my $DEFAULT_USR_PASSWD = '';
my $DEFAULT_ACCOUNT = '';
my $DEFAULT_ACCOUNT_PASSWD = '0000';

#####################################################################
#
#####################################################################

our $XASession = Win32::OLE->new('XA_Session.XASession');

Win32::OLE->WithEvents(
$XASession,
\&XASessionEventsHandler,
'{6D45238D-A5EB-4413-907A-9EA14D046FE5}',
);

croak Win32::OLE->LastError if Win32::OLE->LastError != 0;

sub XASessionEventsHandler {
my ($obj, $event, @args) = @_;
my ($code, $msg) = @args;

if($event == 1){ # on loginls -al;l
$MAIN_SBAR->Text("[$code] $msg");
Win32::OLE->QuitMessageLoop;
}
elsif($event == 2){ # on logout
$MAIN_SBAR->Text("ERROR - Logout. (" . $XASession->GetErrorMessage( $XASession->GetLastError ) . ")");
}
elsif($event == 3){ # on disconnect
$MAIN_SBAR->Text("ERROR - Disconnected.(" . $XASession->GetErrorMessage( $XASession->GetLastError ) . ")");
}
};


#####################################################################
# MAIN Window
#####################################################################

our $MAIN_WIN = new Win32::GUI::Window (
    -title => "System Trading with PERL",
    -pos => [100, 100],
-width => 800,
    -height => 400,
    -name => "MainWindows",
-resizable => 0
) or die "new Window";

#####################################################################
# Main Windows Event Handler
#####################################################################

sub MainWindows_Terminate {
  return -1;
}

our $MAIN_SBAR = $MAIN_WIN->AddStatusBar();

#####################################################################
#Login Group Box
#####################################################################

$LABEL_GUIDE_H1 = 20;
$TEXTFIELD_GUIDE_H1 = 120;
$TEXTFILED_SIZE = 120;

$MAIN_WIN->AddGroupbox(
    -name => "LoginGroupBox",
    -text => "Login Information",
    -pos  => [5, 5],
-width => 250,
    -height => 150
);

# ID

$MAIN_WIN->AddLabel(
-name => 'LoginLabelID',
-text => 'ID',
-pos  => [$LABEL_GUIDE_H1, 30],
-width => 80,
    -height => 25
);

my $USR_ID = $MAIN_WIN->AddTextfield(
-name   => "LoginTextFieldID",
-text => $DEFAULT_USR_ID,
-pos  => [$TEXTFIELD_GUIDE_H1,25],
-width => $TEXTFILED_SIZE,
    -height => 25,
-prompt => ""
);

# PASSWORD

$MAIN_WIN->AddLabel(
-name => 'LoginLabelPASSWD',
-text => 'Password',
-pos  => [$LABEL_GUIDE_H1, 60],
-width => 80,
    -height => 25
);

my $USR_PASSWD = $MAIN_WIN->AddTextfield(
-name   => "LoginTextFieldPASSWD",
-text => $DEFAULT_USR_PASSWD,
-password => 1,
-pos  => [$TEXTFIELD_GUIDE_H1,55],
-width => $TEXTFILED_SIZE,
    -height => 25,
-prompt => ""
);

# CERTIFICATE PASSWORD

$MAIN_WIN->AddLabel(
-name => 'LoginLabelCERTPASSWD',
-text => 'Cert Password',
-pos  => [$LABEL_GUIDE_H1, 90],
-width => 100,
    -height => 25
);

my $USR_CERT_PASSWD = $MAIN_WIN->AddTextfield(
-name   => "LoginTextFieldCERTPASSWD",
-text => '',
-password => 1,
-pos  => [$TEXTFIELD_GUIDE_H1,85],
-width => $TEXTFILED_SIZE,
    -height => 25,
-prompt => ""
);


# LOGIN BUTTON

our $LOGIN_BUTTON = $MAIN_WIN->AddButton(
-name => "LoginButton",
-text => "Do Login!",
-pos  => [$TEXTFIELD_GUIDE_H1,115],
-width => $TEXTFILED_SIZE,
    -height => 25,
-onClick => sub {
$USR_CERT_PASSWD->Text();

my $server      = 'demo.etrade.co.kr';    # server
my $port        = 20001;                  # port
my $srvtype     = 1;                      # server type
my $showcerterr = 1;                      # certificate error

if(!$XASession->IsConnected()){ # 연결되지 않았을 때만,
$XASession->ConnectServer($server, $port) or croak $XASession->GetErrorMessage( $XASession->GetLastError );
$XASession->Login($USR_ID->Text(), $USR_PASSWD->Text(), $USR_CERT_PASSWD->Text(), $srvtype, $showcerterr) or croak $XASession->GetErrorMessage( $XASession->GetLastError );
Win32::OLE->MessageLoop;

LOAD_MY_STOCKS(); # 보유 주식 로드

$LOGIN_BUTTON->Disable();
}
}
);


#####################################################################
# Stock Data Grid
#####################################################################

our @GRID_COL_NAME = ('Name','Purchase UPrice','Currnet UPrice','Quantity','Evalued TPrice','Eearning TPrice','Eearning Rate');
our @GRID_COL_STYLE = (
DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX,
DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX,
DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX,
DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX,
DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX,
DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX,
DT_RIGHT|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX);
our $COUNT_GRID_COL = $#GRID_COL_NAME+1;

our $STOCK_LIST_GRID = new Win32::GUI::Grid (
-parent => $MAIN_WIN,
    -name    => "StockListGrid",
    -pos     => [5, 160],
-width   => 785,
-height  => 185,
-hscroll  => 1,
-editable => 0
) or die "new Grid";

# Init Grid

$STOCK_LIST_GRID->SetRows(1);
$STOCK_LIST_GRID->SetColumns($COUNT_GRID_COL);
$STOCK_LIST_GRID->SetFixedRows(1);
$STOCK_LIST_GRID->SetFixedColumns(0);

for($i = 0;$i < $COUNT_GRID_COL;$i++){
      $STOCK_LIST_GRID->SetCellFormat(0, $i, DT_CENTER|DT_VCENTER|DT_SINGLELINE|DT_END_ELLIPSIS|DT_NOPREFIX);
      $STOCK_LIST_GRID->SetCellText(0, $i, $GRID_COL_NAME[$i]);
}

# Resize Grid Cell
$STOCK_LIST_GRID->AutoSize();

# Event loop
$MAIN_WIN->Show();

Win32::GUI::Dialog();

#Win32::GUI::Show($DOS);
#exit(0);


##########
#
#######

sub DELETE_ALL_STOCK_GRID{
# 행 단위로 모두 삭제
my $exit_rows_count = $STOCK_LIST_GRID->GetRows();
for($i = $exit_rows_count;$i > 1;$i--){ # 밑에서 한줄씩 삭제, 헤더 제외
$STOCK_LIST_GRID->DeleteRow($i)
}
}

sub INSERT_ROW_TO_END_LINE{
@ARG_VAL = @_;

my $last_line = $STOCK_LIST_GRID->InsertRow("",-1); # 그리드에 행 추가, 맨 마지막

for(my $j = 0;$j < $COUNT_GRID_COL;$j++){
$STOCK_LIST_GRID->SetCellFormat($last_line, $j, $GRID_COL_STYLE[$j]);
$STOCK_LIST_GRID->SetCellText($last_line, $j, $ARG_VAL[$j]);
}

$STOCK_LIST_GRID->Refresh();
}

sub LOAD_MY_STOCKS{

my $XAQuery = Win32::OLE->new('XA_DataSet.XAQuery') or croak Win32::OLE->LastError;

Win32::OLE->WithEvents(
$XAQuery,
\&XAQueryLoadMyStocksEventsHandler,
'{AAF89E20-1F84-4B1F-B6EE-617B6F2C9CD4}',
);

croak Win32::OLE->LastError if Win32::OLE->LastError != 0;

$XAQuery->LoadFromResFile("$FindBin::Bin/Res/Tran/t0424.res") or croak Win32::OLE->LastError;

$XAQuery->SetFieldData('t0424InBlock', 'accno', 0, $DEFAULT_ACCOUNT);
$XAQuery->SetFieldData('t0424InBlock', 'passwd', 0, $DEFAULT_ACCOUNT_PASSWD);
$XAQuery->SetFieldData('t0424InBlock', 'prcgb', 0, '1'); # 1:평균단가 2:BEP단가
$XAQuery->SetFieldData('t0424InBlock', 'chegb', 0, '2'); # 0:결제기준잔고 2:체결기준(잔고가 0이 아닌 종목만 조회)  
$XAQuery->SetFieldData('t0424InBlock', 'dangb', 0, '0'); # 0:정규장 1:시간외단일가
$XAQuery->SetFieldData('t0424InBlock', 'charge', 0, '0'); # 0:제비용미포함 1:제비용포함
$XAQuery->SetFieldData('t0424InBlock', 'cts_expcode', 0, ''); #처음 조회시는 Space 연속 조회시에 이전 조회한 OutBlock의 cts_expcode 값으로 설정

my $request_result = $XAQuery->Request(0);

#$MAIN_SBAR->Text("result of request: $request_result");

Win32::OLE->MessageLoop;

sub XAQueryLoadMyStocksEventsHandler {
my ($obj, $event, @args) = @_;

DELETE_ALL_STOCK_GRID(); # 모든 주식 그리드 삭제

my $my_stock_count = $XAQuery->GetBlockCount("t0424OutBlock1"); # 보유 주식 수

#$MAIN_SBAR->Text("No. of My Stocks : " . $my_stock_count );

for(my $i = 0;$i < $my_stock_count;$i++){
#$XAQuery->GetFieldData(szBlockName, szFieldName, nOccursIndex)
#$XAQuery->GetFieldData("t0424OutBlock1", "field", $i);

INSERT_ROW_TO_END_LINE(
$XAQuery->GetFieldData("t0424OutBlock1", "hname", $i),
format_picture($XAQuery->GetFieldData("t0424OutBlock1", "pamt", $i), '###,####'),
format_picture($XAQuery->GetFieldData("t0424OutBlock1", "price", $i), '###,####'),
$XAQuery->GetFieldData("t0424OutBlock1", "janqty", $i),
format_picture($XAQuery->GetFieldData("t0424OutBlock1", "appamt", $i), '###,####'),
format_picture($XAQuery->GetFieldData("t0424OutBlock1", "dtsunik", $i), '###,####'),
format_picture($XAQuery->GetFieldData("t0424OutBlock1", "sunikrt", $i), '###.## %')
);
}

$STOCK_LIST_GRID->AutoSize();

Win32::OLE->QuitMessageLoop;
}
}

⇒ 부엉이 님께서 2012-02-18 19:02:55 에 답글을 작성하셨습니다.

아직도 주식을 하십니까... -_-;;

지금은 형이 Perl 을 만지던 1999-2002년이 아니라서, 그때와 지금의 Perl 환경은 사실상 단절이라고 해도 좋을 정도로 많이 변했지. 내가 형 코드를 보고서 Perl 을 배웠으니 말이지만, 그때 짰던 코드들은 지금 생각해 보면 완벽하게 Legacy Code (그것도 Perl 4 시절의!) 입니다. -_-;;;

ActivePerl 은 지금도 컴파일러를 함께 지원을 안 하지만 MinGW 를 설치하면 되고, Strawberry Perl은 처음부터 gcc 를 포함해서 나온 것이라 따로 깔아줄 필요가 없지. 그리고 과거에는 ActivePerl 에서만 PPM 이 지원되었었지만, 지금은 Strawberry Perl 에도 PPM이 포함되어 있어. CPAN 이야 당연히 사용 가능한 거고.

Win32::GUI 는, 이게 기본적으로 MSVC 를 이용해서 컴파일한 거라, gcc 에서는 컴파일할 때 상당히 삐걱거리더라고. 아마 64비트 문제라기보단 이쪽의 문제거 다 있을 거라는 생각이 드네. PPM을 이용한 수동 설치 방법이 있으니까 한번 써 보는 것도 좋지. 단, 형이라면 Win32::GUI 보다는 다른 GUI 툴을 이용하는 게 더 좋지 않을까 싶은데. 네이버의 Perl Community 에 와 보면 관련된 이야기가 몇 개 있으니까 한번 와서 읽어봐...

그리고 저런 코드를 덧글에다가... 하아...

[489] < [420] [419] [418] [416] [415] ... [413] ... [412] [410] [408] [407] [406] > [19]

(C) 2000-2023, Owl-Networks. Powered by Perl. 이 페이지는 HTML 5 표준에 따라 작성되었습니다.