Digital Angel Master

Spread the wing for new starting.

Archive for 1월, 2008

< MySQL 백업 & 복구하기 >

Posted by Digital Angel Master on 1월 29, 2008

<< MySQL 백업 & 복구하기 >>

History :
  2007/09/28  : MySQL 입력시 한글 깨지는것 해결 방법
  2001/10/30  : 문서 최초 작성
##############################################################################

백업을 하기 위해서는 mysqldump 명령어를 사용합니다.
그리고, 복구를 하기 위해서는 mysql 명령어를 사용합니다.
이 명령어의 path 를 잡아주세요.!!

형식은 다음과 같습니다.
(참고: [] 는 선택 항목입니다.)

  user> mysqldump [-h 호스트] [-u 사용자] [-p] DB명 [table명]> 백업파일
  user> mysql [-h 호스트] [-u 사용자] [-p] DB명 < 백업파일

  예제 1) root 라는 사용자가 mydb 를 백업하는 명령입니다.
          이렇게 하시면 mydb.sql 파일에 sql문으로 저장이 됩니다.
  user> mysqldump -u root -p mydb > mydb.sql  

  예제 2-1) 백업된 mydb.sql 을 newdb 에 입력하는 방법
  user> mysql -u dbakorea -p newdb < mydb.sql

  예제 2-2) 한글이 깨지는 경우 문자셋을 설정하여 입력하는 방법
    1. 테이블 문자셋 확인
    2. 이력 파일의 문자셋 확인
    3. 문자셋 지정 입력

  user> mysql -u dbakorea -p --default-character-set=euckr newdb < mydb.sql

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

<< 형화가 사용하는 프로그램 >>

###################
# 사용하기전에 할일
###################

1. 작업을할 디렉토리(dir/)를 만들고 cgi 파일을 만든 디렉토리에 복사한다.
  앞으로 작업디렉토리를 dir 이라 하겠다.
2. dir 밑에 temp 디렉토리를 만들고 권한을 700 으로 준다.

  user> mkdir -p dir/temp
  user> chmod 700 temp

###########
# 백업하기
###########

  user> chmod 700 mysqldump.cgi
  user> perl mysqldump.cgi

db_list 파일이 생성 되었는지 확인한다. 

################
# DB 생성하기
################
dbinput_list 파일은 mysqldump.cgi 에 의해 만들어진 db_list 파일을
복사해서 사용하면 된다. 생성이 필요없는 DB는 지우면 된다.
(주의: 처음 3줄은 삭제를 하지 말아라.)

  user> chmod 700 mysqldbcreate.cgi
  user> perl mysqldbcreate.cgi

################
# DB에 입력하기
################
dbinput_list 파일에 입력할 DB 를 추가한다.
(주의: mysql DB 는 빼는게 좋다.)

  user> chmod 700 mysqlinput.cgi
  user> perl mysqlinput.cgi

####################
# 사용되는 파일들
####################

======================== mysqldump.cgi ===============================
#!/usr/bin/perl

# Linux에 있는 모든 DB를 DB_name.dump 파일에 dump한다.
# 1999,12,2

# $mysql_path = "/usr/local/bin";  # FreeBSD
$mysql_path = "/usr/local/mysql/bin";
$passwd = "";	# root 비번을 입력한다.
$host = "";		# 접속할 호스트 (외부에 DB가 있는 경우만 사용한다.)

if( $passwd ne ''){
	$passwd = " -p$passwd";
}
if( $host ne ''){
	$host = " -h $host";
}

`$mysql_path/mysqlshow -uroot $passwd $host > db_list`;

open( IN, 'db_list' );
$start = 0;
while( <IN> ) {
    if( $start ne 3 ) {
        $start ++;
# print "start:$_\n";
        next;
    }
    elsif ( $_ !~ / / ) {   # Blank
        next;
    }
    chop();
    ( $a, $db, $c ) = split( /\|/, $_);
    $db =~ s/ //g;

    # 각 DB의 dump파일을 생셩한다.
    `$mysql_path/mysqldump -uroot $passwd $host $db > temp/$db.dump`;
    print "$db Dumped\n";
}
close( IN );

======================== /mysqldump.cgi ===============================

======================== mysqldbcreate.cgi ===============================
#!/usr/bin/perl

# dbinput_list에 있는 모든 DB를 생성한다.
# 2000. 4. 5

# dbinput_list 파일은 mysqldump.cgi 에 의해 만들어진 db_list 파일을
# 복사해서 사용하면 된다. 생성이 필요없는 DB는 지우면 된다.
# (주의: 처음 3줄은 삭제를 하지 말아라.)

# $mysql_path = "/usr/local/bin";  # FreeBSD
$mysql_path = "/usr/local/mysql/bin";
$passwd = "";	# root 비번을 입력한다.
$host = "";		# 접속할 호스트 (외부에 DB가 있는 경우만 사용한다.)

if( $passwd ne ''){
	$passwd = " -p$passwd";
}
if( $host ne ''){
	$host = " -h $host";
}

open( IN, 'dbinput_list' );
$start = 0;
while( <IN> ) {
    if( $start ne 3 ) {
        $start ++;
        next;
    }
    elsif ( $_ !~ / / ) {   # Blank
        next;
    }
    chop();
    ( $a, $db, $c ) = split( /\|/, $_);
    $db =~ s/ //g;

    # 각 DB를 생성한다.
    `$mysql_path/mysqladmin -uroot $passwd $host create  $db`;
    print "$db Created\n";
}
close( IN );

# 설정을 다시 읽는다.
`$mysql_path/msyqladmin -uroot $passwd $host reload` 

======================== /mysqldbcreate.cgi ===============================

======================== mysqlinput.cgi ===============================
#!/usr/bin/perl

# dbinput_list에 있는 모든 DB를 각 DB에 입력한다.
# 2000. 4. 3

# $mysql_path = "/usr/local/bin";  # FreeBSD
$mysql_path = "/usr/local/mysql/bin";
$passwd = "";	# root 비번을 입력한다.
$host = "";		# 접속할 호스트 (외부에 DB가 있는 경우만 사용한다.)

if( $passwd ne ''){
	$passwd = " -p$passwd";
}
if( $host ne ''){
	$host = " -h $host";
}

open( IN, 'dbinput_list' );
$start = 0;
while( <IN> ) {
    if( $start ne 3 ) {
        $start ++;
        next;
    }
    elsif ( $_ !~ / / ) {   # Blank
        next;
    }
    chop();
    ( $a, $db, $c ) = split( /\|/, $_);
    $db =~ s/ //g;

    # 각 DB에 dump파일을 입력한다.
    `$mysql_path/mysql -uroot $passwd $host $db < temp/$db.dump`;
    print "$db Inserted\n";
}
close( IN );

======================== /mysqlinput.cgi ===============================

Posted in Database, Web Programming | Leave a Comment »

ActiveX 배포관련 QNA

Posted by Digital Angel Master on 1월 29, 2008

Active X 관련하여 여러가지 경우가 있었던거 같습니다.

저같은 경우엔 게임을 오토인스톨및 업데이트 프로그램을 만들었는데요.

인증부분에서 저두꽤 ~ 애를 먹었던거 같네요.특히 cab화일 안에 포함되는 OCX  버젼탓도 있었고….

설명을 시작하기 전에 전제를 하겠습니다 인증과정은 무결하다고 생각하고요.^^ 인증과정은 그다지 노하우같진 않았습니다. 메뉴얼식으로 잘 서술되어있어서. 그냥.따라하기만 하면 되더군요.

그럼 시작합니다. 웹에서 실행시에  반응이 없으실때…

C:\WINNT\Downloaded Program Files여기를 보시면 아마 ActiveX 관련상황이 나올껍니다.

만약에 ActiveX의 이름이  “1810DFFB-F74D-48F6-AB0B-37ADE0E678E1″ 식의  숫자가 막~~ 나오는경우엔

그 Activex는 깨진경우라고 생각하심 될꺼에요 그런경우라면 아마 실행이 제대로 안될겁니다.

그리고 만약에 개발했던 PC 에서는 다운이 잘 안됩니다. 원칙적으로….

왜냐면 인증부분때문인데요.

만약에 제가 ActiveCogame라는 Active X 를 컴파일하고  ‘패키지 및 배포 마법사’를 실행하면 CLASSID 라는것이 나옵니다.

당연히 cab화일도 나오겠죠.cab화일이 존재하는 폴더에 보시면. Support라는 폴더가 나오는데요. 그곳에 보시면 ActiveCogame.INF 라는 식의 환경화일이 나옵니다.

열어보시면.. 이런식이죠…(이부분은 Cab화일의 .Inf와 관련이 많은곳입니다 다운받은 active x가 로컬에 존재하는지 버젼은 같은지 확인할수있는 연결고리죠..^^)

[AddToRegistry]
HKLM,”SOFTWARE\Classes\CLSID\{1810DFFB-F74D-48F6-AB0B-37ADE0E678E1}\Implemented Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}”
HKLM,”SOFTWARE\Classes\CLSID\{1810DFFB-F74D-48F6-AB0B-37ADE0E678E1}\Implemented Categories\{7DD95801-9882-11CF-9FA9-00AA006C42C4}”
HKCR,”Licenses”,,,”Licensing: Copying the keys may be a violation of established copyrights.”

구현하셨던 부분의 CLASSID 도 위와 동일해야합니다.
[ActiveCogame.dll]
file-win32-x86=thiscab
RegisterServer=yes
clsid={C4075797-79BE-4533-8C95-BF074E773E9E}
DestDir=
FileVersion=1,0,0,103
배포마법사를 사용할때마다…clsid 3개가 수정되고 버젼번호 하나를 수정됩니다

Categories\{7DD95802-9882-11CF-9FA9-00AA006C42C4}” 이 정보 보이시죠?
이것이 로컬에 저장된 내용입니다. 7DD95802-9882-11CF-9FA9-00AA006C42C4 이것이 CLASSID  라는건데요.
지금 ‘패키지 및 배포 마법사’를 거치면서 자동으로 저장된거죠. 이것은 인증이 거쳐지지 않은겁니다.

Active X를 배포할때. 로컬에 저장유무를 판단하는것은…

인증이 되어있는 cab 화일안에 있는 정보인 CLASSID 라는겁니다. 그러니까 당연히 인증받은것이 다운을 받더라도 등록을 하거나 실행하진 않죠..

왜냐면 로컬에 이미 같은 정보의 화일이 존재한다고 되어있으니까요.

아마 개발했던 pc 에서 실행이 안되거나 다운이 안되는경우엔 컴파일시에 로컬에 Dll이나 cab화일이 존재하기때문에 다운이 안받아지는경우엔 대략 이부분때문이었던걸로 기억합니다.

간단하게 배포하기 위해서는 컴파일 했던 폴더를 지우시는것도 좋은 방법이네요. 단 레지스트리가 좀 지저분해지는 경우는 있지만..

다시 저같은경우를 생각해서 말씀드리면..

만약에 소스가 D:\source에 존재해서 거기서

임의의 폴더 D:\A라는곳에 컴파일을 하고 저장하고난

이후에 ‘패키지 및 배포 마법사’를 실행했습니다.

실행시에 다시 재컴파일을 했죠.움…그러면 CLASSID와 CODEBASE의 version 가 각각 바뀌게 됩니다.

배포하기 위해서 올리고 난이후엔 web에서의 object 의

CLASSID  & CODEBASE 값을 Cab화일과 동일하게 바꾸고 cab화일을 경로에 맞추어 올리는거죠^^

그리고 로컬의 D:\A 삭제합니다.

그러면 아마 실행은 시키실수 있습니다.

그리고 웹은  특별히 문제가안될듯합니다..CLASSID  & CODEBASE 만 정확하다면..

그리고 정상적으로 Active X 가 실행시킬수 있는지 확인하는 가장좋은 방법은…..

PC방을 이용하시기 바랍니다.^^ 저같은경우에는 실제로 서비스를 받는 사람을 고려하기 위해서 비슷한 환경을 찾다보니 PC방에서 테스트를 많이 했답니다. 왜냐면 window 98경우엔 MSVBVM60.DLL 이게 없는거 같더군요^^;;

열코딩하시고 좋은 성과있으시길..cheer!!!!

—————————————————————————————————

기본적으로 VB런타임의 Dll파일은 2개입니다.

vb60ko.dll

msvbvc.dll

위 파일명의 스펠링 틀릴수 있음…쩝

그러나 가타 부수적인 컨트롤들을 포함하면 다를 파일까지 묶기게 됩니다.

OS별로 런타임의 버젼 차이가 있습니다.

예를들어

98나 98은 런차임 모듈을 가지고 있지 않은걸로 기억이 되고

XP는 기본으로 VB6의 런타임을 가지고있어서

VB6의 컴파일한(일반적인 컨트롤을 사용했을경우)

EXE파일 하나로 동작이 됩니다.

단 약간의 버젼차이죠(날짜 혹은 패치파일)로 인한 실행 불가…

배포를 한 후 리부팅을 원하는것은 OS가 전적으로 제어를 합니다.

윈도 부팅시 필요한 DLL파일을 미리 로드시키는 경우가 있는데

거런것들이 업그레이드 된다면

OS는 알아서 재부팅을 요구하게됩니다.

따라서 결론적으로 95나 98은 OS의 기본 DLL이 예전것이라

재부팅을 원하는 경우가 있고

XP, 2000경우는 비슷한 버젼이거나 똑같을 경우가 있어서

재부팅을 요구안할때가 종종 있습니다.

그럼…
————————————————————————————-
[답변]activex를 만들어서 웹배포를 하는데요…문제가
————————————————————————————-

님이 어떤 과정을 거쳐 배포판을 생성하셨는지, 혹은 어떤 기준을 가지고 테스트 하셨는지 구체적이지 않은 관계로

매우 일반적인 사항만을 (제가 아는선에서….^^)  적도록 하겠습니다.

배포시 문제점을 확인하는 몇가지 기준이 있습니다.

뭐, 꼭 정해진 기준은 아니고, 개발 환경내지는 주어진 절차에 맞게끔 가공 처리 되었는지가 대부분입니다.

웹 배포던, 아님 로컬인스톨패키지던 공통적으로 확인해야 할 부분은 다음과 같습니다.

1. 자신이 개발한 환경이 가장 최근의 버전들로 패치된 상황이라면, 그이전의 버전들로 설정되어 있는 환경에서는 정상적인

설치가 진행되지 않을 수 있습니다.

2.패키지 구성에 사용된 (프로그래밍에 사용된) 구성요소들(컨트롤,DLL,혹은 기타등등의 코드)가 장비의존적인지 아님

운영체제 의존적인지를 확인 합니다.(결국 1번과 같은 얘기입니다.)

-> 가장 쉬운 확인 방법은 각각의 상황을 설정해놓고 설치해보는게 가장 확실 합니다.

3.특히 웹배포패키지 일경우는 웹에서 사용하기 위한 일련의 절차등을 확인해야 합니다.

하지만, 인증이나 사용안전을 위한 절차가 개발자가 개발한 패키지의 설치 자체에 영향을 주지는 않습니다.

다음과 같은 순으로 테스트를 합니다.

가. 웹배포 패키지를 일반 로컬설치패키지로 생성한 다음 문제가 생기는 환경에서 설치를 합니다.

만일 이 테스트에서 설치가 되질 않는다면, 위의 1,2번항목에 이상이 있습니다.

나.웹배포패키지가 설치된 웹페이지를 보안수준을 가장 낮음에 놓고 접근하여 테스트를 합니다.

만일 이 테스트에서 설치가 되질 않는다면, 위의 1,2번항목에 이상이 있습니다.

다. [가]항목에서는 정상적인 설치가 이루어지지만, [나] 항목에 이상이 있을 경우는 웹배포패키지에 몇가지 파일이

제외 되었거나, 클라이언트가 해당 패키지를 설치하고 실행하기 위한 정보가(파일)이 부족한 경우 입니다.

다음과 같은 방법으로 테스트를 진행해 봅니다.

a.배포판 인증을 할 시 캐비넷에 인증을 하거나, 컨트롤에 인증을 하는 방법으로 테스트 합니다.

b.웹배포판 패키지 생성시 로컬배포패키지 생성시처럼 모든 파일을 패키지에 포함하여 테스트합니다.

4. 실행오류가 아닌, 설치문제는 반드시 위의 1,2,3번 과정에 그 원인이 포함 됩니다.

대부분 사용구성요소(컨트롤,DLL,API…..)가 버전이나,장비, 운영체제등 환경을 가려지원하는 경우이거나, 아니면,

설치시 동반되는 구성요소들이 설치되는 환경의 시스템구성요소여서 제약이 생기거나 등록이 되질 않는 경우입니다.

차분히 체크사항들을 확인하고 진행하면 님의 경우는 꼭 해결 되리라 봅니다.
————————————————————————————————-

1. 먼저 ActiveX Control을 개발하실 때, Version관리를 하신다면, 프로젝트 속성에서 [디버깅]-버전 호환성에서 이진 호환성으로 하셔야 합니다. 그래야만, 버전이 바뀌었을 때, 웹에서 알아서 다운을 받아 설치를 하고요.

2. 패키지 및 배포 마법사를 통해서 ocx에 대한 인터넷 배포 패키지를 만듭니다.

3. CAB파일에 서명을 합니다.

아래 페이지를 참조하여 테스트 인증서를 만드시면 됩니다.

마이크로 소프트 CAB파일 서명 단계

4. lpktool.exe를 사용하셔서, lpk 파일을 만듭니다.

이때, 현재 컴파일한 activex control을 regsvr32.exe를 사용하여 등록하신 후,

그 control로 lpk파일을 만드셔야 합니다. 기존에 ocx를 설치한 후, 새 버전을 설치하고 이리하여 레지스트리가 엉망이 된 경우에     lpk를 만들면, 제대로 만들어 지지 않습니다.

그런 후에 웹에 올려서 배포하시면, 클라이언트 브라우저에서 나타나는 문제가 없더군요..

근데, 특별한 구성요소를 포함하여 ocx를 만들면 설치가 안되거나, 문제가 생기는 경우가 있구요..

위 과정에서 제대로 안된 부분이 있으면 설치가 안됩니다.

과정을 하나하나 짚어가면서 하시면 큰 문제가 없으리라 생각되네요..

참고로 저의 개발 PC사양은 winxp, vb6.0(한글판), ie 최신 버전으로 했습니다.

————————————————————————————————–

질문하신 내용입니다.

——————————————————————————

웹으로 cab파일을 묶어서 배포할때 system32 폴더에 묶었던 ocx 파일이 왜 없을까요?

ocx가 레지스트리에 등록만되고 system32에는 저장이 안되는걸까요?

고수님들 답변부탁드립니다!

——————————————————————————

저는 고수가 아니라 함부로 답하기가 죄송합니다만,

도움이 되실지 몰라 짧게나마 글을 남겨볼까 합니다.

우선 System32 폴더에 ocx 가 등록되지않는다면, 혹시 CAB 파일을 작성하실때 INF 파일에서

등록될 경로를 잘 못 지정하신게 아닌가 먼저 짐작됩니다.

아래는 제가 작성했던 HTML 코드의 일부분 입니다.

<html>

<중략….>

<body>

<!– 여기서 teWExchange.LPK 파일은 LPK 툴을 이용하여 작성하고 생성된 *.LPK 파일 입니다. –>

<OBJECT CLASSID=”clsid:5220cb21-c88d-11cf-b347-00aa00a28331″><PARAM NAME=”LPKPath” VALUE=”teWExchange.lpk”></OBJECT>

<OBJECT id=teExchange1 classid=”clsid:F1E566AC-3319-4714-BA37-E30A77229A64″  CODEBASE=”http://182.1.143.8/proto/rg/teWExchange.CAB#version=1,0,0,0“>

<PARAM NAME=”_ExtentX” VALUE=”26088″>

<PARAM NAME=”_ExtentY” VALUE=”17965″>

<PARAM NAME=”uid” VALUE=”<%=Session(“user_id”)%>”>          <!– 사용자 –>

<PARAM NAME=”uname” VALUE=”<%=Session(“user_name”)%>”>      <!– 사용자명 –>

<중략….>

</html>

그리고 작성했던 CAB 파일은 인증을 받았습니다.

CAB 파일을 작성할때는  Batch 파일을 만들어서 아래와 같이 했습니다.

## 배치파일(BAT : Batch File) 의 내부 ##

1 라인 : del teWMig.cab

2 라인 : SignCode -spc bizbank_2003.spc -v bizbank_2003.pvk -n teWMig -i http://182.1.143.8/proto/rg -t http://timestamp.verisign.com/scripts/timestamp.dll teWMig.ocx

3 라인 : cabarc.exe -s 6144 N  teWMig.cab teWMig.ocx teWMig.INF

4 라인 : SignCode -spc bizbank_2003.spc -v bizbank_2003.pvk -n  teWMig -i teWMig.cab -t  http://timestamp.verisign.com/scripts/timestamp.dll teWMig.cab

5 라인 : pause

((‘1 ~ 5 라인 : ‘ 은 확인하기 편리하기 위하여 표기한것 입니다.))

만약 인증받지 않은 CAB 파일등이라면

IE -> 인터넷옵션 -> 보안 -> 사용자 지정 수준 -> ActiveX 컨트롤 및 플러그 인

에서 모두 ‘사용’ 으로 체크하시고 하시면 될 것 같습니다.(IE6.0 기준)

## INF 파일의 내부 입니다. ##

;teWMig.ocx용 INF 파일
;

; ★★ DestDir은(는) Windows 디렉터리에서 10, 둡니다.

; ★★ Windows\System(32) 디렉터리에서는 11이거나 Occache 디렉터리에서는 비워

; ★★ 질문 하신 내용과 가장 깊은 관련성이 있을듯한 부분 입니다.

;

[version]

signature=”$CHICAGO$”

AdvancedINF=2.0

[Add.Code]

teWMig.ocx=teWMig.ocx

[teWMig.ocx]

file-win32-x86=thiscab

RegisterServer=yes

clsid={75D46F48-925D-4EAB-914E-0B4DDD5F5AA0}

FileVersion=1.0.0.0

DestDir=11

[RegisterFiles]

%11%\teWMig.ocx

================================================================================================

이상 입니다.

소스코드 라인 한줄 한줄 주석을 달아드리지 못해 죄송합니다.

보시고 참고하실 부분이있다면 참고하시고 없다면 과감히 버리십시오.

질문이 있으시다면 다시 글 이어주십시오.

부디 이것으로 끝나기를 .. ^^;  ((왜냐하면 깊이 들어가면 모르거든요.. ^^;))

Posted in Web Programming | Leave a Comment »

Resources and Satellite Assemblies 2

Posted by Digital Angel Master on 1월 28, 2008

Fusion 9 : Resources and Satellite Assemblies 2

오늘은 자원과 위성 어셈블리 그 두번째 시간 되겠다.

(바이너리 리소스를 위한) XML Compiled Resources

지금 까지의 리소스 포함은 우리가 어플리케이션 내에 문자열 리소스를 포함하는 경우 ( 예를들면, 에러 메시지, 다이얼로그 박스 상의 캡션 정보와 같은)  적합한 형태이다. 하지만 아이콘, 비트맵과 같은 바이너리 리소스를 포함하고 싶은 경우,
바이너리 리소스는 문자열에서 했던 방식의 메커니즘을 제공하지 않는다. 바이너리 리소스를 위해서는 텍스트 인코딩을 사용해 바이너리 값을 텍스트 값으로 변환해야 한다.Convert 클래스는 두 개의 메서드를 제공하는데, ToBase64String과 FromBase64String이 그것이다.

관리되는(Managed)   XML리소스는 일반적으로 .resx 파일로 알려져 있다.
(결국, resx 파일 내에 우리는 원하는  바이너리 리소스를 포함할 있으며 이를 Compiled 리소스로 컴파일 생성되는 .resources 파일을 리소스로 포함시켜 프로세스를 실행하면 되는 것이다.)

Raw 형식의 XML 리소스(.resx)  파일 생성 –> (resgen 툴을 이용해 컴파일) –> 컴파일 된 xml 리소스 파일(*.resources) –>실행 프로그램의 리소스로 포함시켜 컴파일

이 파일은 ResxResourceWriter 클래스를 사용해 쓸 수 있으며,  ResxResourceREader 클래스를 이용해서 .resx 파일의 데이터를 읽을 수 있다.  하지만 ResxResourceWriter  클래스를 사용하는데 익숙치 않으므로 이전처럼 그냥 .resx로 컴파일하고 ResourceManager로 읽을 수 있다면 편할 것이다.
Resgen 툴은 .txt 또는 .resx 파일을 입력을 받아들일 수 있으며, 흥미롭게도 .resources 파일을 입력을 받아 들일수도 있다. 이 경우 툴은 .resources 파일을 디컴파일하여 .txt 또는 .resx파일로 결과는 생성한다.
Resx 파일은 엄격한 스키마를 가지고 있으며 이 스키마를 지키지 않으면 컴파일이 되지 않는다. Visual Studio를 사용하면 프로젝트에 윈 폼을 추가할 때 마다 자동으로 .resx 파일을 생성해 준다. Visual Studio를 사용하지 않으면 우리가 직접 resx 파일을 생성해야만 한다.

□ 수동으로
.resx 만들기(without Visual Studio)

그렇다고 resx파일을 만드는 것이 매우 어려운 작업은 아니다 resgen 툴을 이용해서 .resources 파일을 디컴파일 할수 있기 때문이다.
그 생성 단계는 간단하다. 먼저 빈 텍스트 파일을 생성한다. 그리고 리소스 파일로 컴파일 한다. 마지막으로 .resx 파일로 디컴파일 한다.

일반
raw 리소스 파일 생성 –> (resgen 툴을 이용해 컴파일) –> 컴파일된 리소스 파일(.resources)
–> (resgen 툴을 이용해 resx로 디컴파일) –> 디컴파일된 raw  XML 리소스 파일(.resx)

Resgen test.txt
Resgen  test.resource  test.resx

이렇게 하면 test.resx 라는 이름의 XML 파일이 생성된다. 이 파일은 매우 긴 주석과 스키마, 그리고 기본값을 포함하고 있다. 주석을 제거하고,  스키마는 유지하는게 낳을 것이다. 결론적으로 아래는 내용은 resx 파일 내에 존재해야 한다.

<?xml version=”1.0″ encoding=”utf-8″?>
<root>
<resheader name=”resmimetype“>
<value>text/microsoft-resx</value>
</resheader>
<resheader name=”version”>
<value>2.0</value>
</resheader>
  <resheader name=”reader”>
    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
  <resheader name=”writer”>
    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
  </resheader>
</root>

마지막 두 항목은 .resx 파일을 읽고 쓰는데 사용되는 클래스를 나타낸다. 더 중요한 것은 resmimetype 이다. 이는 데이터의 기본적인 형식을 나타내면 위 예시에서는 text를 포함하고 있음을 나타낸다.(text/microsoft-resx)
리소스 파일에 데이터를 추가하는 것은 쉽다. 각 <data> 노드는 <value> 노드를 포함한다. <data> 노드는 name 속성을 가지며 추가적으로 type 속성을 가질 수도 있다. <value> 노드의 내부 텍스트에 값이 들어가게 된다.
만일 mimetype을 명시하지 않으면 <data> 노드는 기본 resmimetype이 사용되며 이는 값이 다음 중 하나의 타입이어야 한다는 것을 의미한다.
String, Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, DateTime, TimeSpan, Decimal
ResourceManager는 type과 value을 읽는다 그리고 그 값을 통해 타입을 생성한다. ResourceManager.GetObject를 이용해서  컴파일된 리소스로부터 항목을 가져올 수 있다. 이때 리소스 명을 인자로 전달해야 한다.GetObject는 Object  객체를 리턴하므로 적당한 타입으로 변환해야 한다.
예를 들어 아래의 텍스트를 test.resx 파일에 추가한다.

 <data name=”Data” type=”System.Int32,
mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″>
<value>42</value>
</data>
</root>

Data 는 32 비트 정수라는 것을 나타낸다.

이 리소스를 읽는 코드는 간단하다.

class App
{
static void Main()
{
Assembly a = Assembly.GetExecutingAssembly();
ResourceManager resources = new ResourceManager(“test”, a);
object obj = resources.GetObject(“Data”);
int data = (int)resources.GetObject(“Data”);
Console.WriteLine(“value is {0}”, data);
}
}

그리고 .resx를 compiled 리소스로 컴파일 하고, 프로세스 컴파일 , 실행
큰 그림 보려면 클하세요!(돋보기도 같이 활용)

□ 바이너리
리소스 데이터 추가하기

위 에 언급된 기본 타입 외의 타입을 사용하고 싶다면, 타입을 직렬화한 후(BinaryFormatter 또는 SoapFormatter를 이용해서) 그 결과를 base64로 인코딩 해야 한다.이렇게 하는 가장 간단한 방법은 ResxResourceWriter를 이용하는 것이다.
예를 들어, .cur 파일을 가지고 있고 이 커서 파일을 폼의 커서로 이용하고 싶다고 가정한다.
genCursor.cs라는 이름의 콘솔 어플리케니션을 생성하고 코드는 아래와 같다

// First parameter is the name of the icon in the .resx file
// Second parameter is the name of the cursor file
using System; using System.IO;
using System.Resources;
using System.Windows.Forms;
class App
{
static void Main(string[] args)
{
if (args.Length < 2) return;
using (ResXResourceWriter writer
= new ResXResourceWriter(Console.Out))
{
using (FileStream fs = File.OpenRead(args[1]))
{
Cursor cursor = new Cursor(fs);
writer.AddResource(args[0], cursor);
cursor.Dispose();
writer.Generate();
}
}
}
}

위 코드는 ResXResourceWriter 의 출력을 콘솔로 재지정(redirect)한다. 그래서 그 출력을 다시 다시 파일로 연결하거나  콘솔에서 그냥 복사해도 된다.

genCursor Cursor test.cur > test.resx

Test.resx 파일을 열면 아래와 같이 리소스가 추가되어 있다.

<data name=”Cursor” type=”System.Windows.Forms.Cursor, System.Windows.Forms” mimetype=”application/x-microsoft.net.object.bytearray.base64“>
<value>
AAACAAEAICAAAA8ADwAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAgAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAGBgAACAEAABDwgAAjDEAARAggAEg
QIACIIxAAkESQAJCIkACREJAAkiCQAIxBEABIgSAAQQIgACMMQAAQ8IAACAEAAAYGAAAB+AAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////gf///gB///wAP//4AB//8D
wP/+D8B//h+Af/wfAD/8Pgw//DwcP/w4PD/8MHw//AD4P/4B+H/+A/B//wPA//+AAf//wAP//+AH///4
H/////////////////////////////////8=
</value>
</data>

Mimetype이 application/x-microsoft.net.object-.bytearray.base64으로 주어진다. 이는 Cursor 객체를 직렬화하는데 BinaryFormatter가 사용되었다는 의미이다.

□ 바이너리
리소스 사용하기

결과 리소스 파일(test.resx)을 컴파일 한다.

Resgen test.resx

윈폼 어플리케이션을 하나 만들고 리소스로 포함된 커서를 이용하도록 한다.

using System;
using System.Resources;
using System.Windows.Forms;
using System.Reflection;
class MainForm : Form
{
MainForm()
{
Assembly a = Assembly.GetExecutingAssembly();
 ResourceManager resources = new ResourceManager(“test”, a);
      this.Cursor = (Cursor)resources.GetObject(“Cursor”);
}
static void Main()
{
Application.Run(new MainForm());
}
}

윈폼 어플리케이션 컴파일
큰 그림 보려면 클하세요!(돋보기도 같이 활용)
결과


□ Visual Studio
를 이용해 리소스 활용하기

매우 작업이 간단해 진다. 거의 모든 작업을 Visual Studio가 처리해 준다.
바이너리 파일을 리소스화(resx 파일에 리소스로 추가),  리소스 파일에 대한 컴파일,  리소스를 어셈블리에 embed 하는 작업 등

프로젝트 상에서 리소스 파일 추가

추가된 리소스 파일(Resource1.resx)를 디자인 모드로 열면,
문자열/이미지/아이콘/… 등의 카테고리 별 리소스를 확인할 수 있다.

문자열 리소스 하나 추가 : a=1

바이너리 리소스 하나 추가 : 디스크 상의 기존 이미지 파일을 리소스로 추가

이미지 파일을 추가했으므로 왼쪽 카테고리를 “이미지”로 변경하면 추가된 파일이 보인다.

리소스 사용하기

코드도 매우 간단하다.
 private void Form1_Load(object sender, EventArgs e)
{
//문자열 리소스 사용
MessageBox.Show(Resource1.a);
//바이너리 리소스 사용
this.BackgroundImage = Resource1.KKansoon;
}

실행


특별하게 신경 쓰지 않아도 Visual Studio가 embedded 리소스 형태로 이미지를 실행 어셈블리에 포함시켜 준다.
잘 보면, managed XML 리소스 파일(resx)이 포함(embedded)  리소스로 어셈블리에 포함됨을 속성으로 지정하고 있다.(기본값)

이 의미는 곧 Resource1.resx 파일 안에 바이너리 데이터(base64 인코딩된 텍스트)가 포함될 것이고, 이 Resource1.resx가 실행 어셈블리(exe)에 포함될 것이므로, 프로젝트 상에 추가되어 있는 실제 이미지 파일(깐순.jpg)는 굳이 다시 실행 어셈블리에 포함시킬 필요가 없다.
곧 이미지 파일은 Visual Studio가 빌드과정에서,  Resource1.resx을 컴파일 하여 Resource1.resources 를 생성할 때 그 바이너리 데이터를 제공하기 위해 사용되기 위한 것이라 짐작이 가능하다.

즉,  디자인 타임에만 사용될 녀석이라는…실행시간에는 필요가 없다는..
해당 이미지 파일의 빌드작업 속성을 찍은 “없음” 값이 기본이다. (이것 때문에 많이 헷갈려 했었는데…)



이미지 파일을 “포함리소스”로 변경하면? 이미 리소스 파일에 포함된 이미지 데이터가 다시 따로 실행 어셈블리 속으로 포함되므로, 쓸데없이 실행 어셈블리 사이즈만 증가시키는 결과를 낳는다.
 리소스로 포함된 다른 형태의 파일들도 마찬가지 일 것이다.

■ 커서파일을 리소스로

Visual Studio 이용해서 커서 파일을 리소스로 추가하는 것은 조금 애로사항이 있다.(*.cur) 아래를 참조 바람.

http://edndoc.esri.com/arcobjects/9.0/ArcGISDevHelp/DevelopmentEnvs/DotNet/WorkingWithResources.htm

*.cur
리소스로 추가될 그냥파일형태로 추가된다. (커서라는 카테고리 없음, 그렇다고 이미지도 아님)



그래서
아래 처럼 폼의 커서 속성에 바이너리 데이터를 우겨 넣으면 에러.

this.Cursor = (Cursor)Resouce1.TestCursor;

Visual Studio를 쓰지 않는 방식대로 resx를 수동으로 만들어서 해당 커서 바이너리 데이터를 넣어서 그걸 붙여 넣기 할 수 있다.
그래서 수동으로 임의의 resx를 만들어 그 안에 커서 바이너리를 추가한 다음 해당 <data> 항목(리소스)를 클립보드로 복사하여,
Resource1.resx 파일 내용에 집어 넣는다.

예)
<data name=”TestCursor” type=”System.Windows.Forms.Cursor, System.Windows.Forms” mimetype=”application/x-microsoft.net.object.bytearray.base64″>
<value>
AAACAAEAICAAAA8ADwAwAQAAFgAAACgAAAAgAAAAQAAAAAEAAQAAAAAAgAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4AAAGBgAACAEAABDwgAAjDEAARAggAEg
QIACIIxAAkESQAJCIkACREJAAkiCQAIxBEABIgSAAQQIgACMMQAAQ8IAACAEAAAYGAAAB+AAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAA//////////////////////////////////gf///gB///wAP//4AB//8D
wP/+D8B//h+Af/wfAD/8Pgw//DwcP/w4PD/8MHw//AD4P/4B+H/+A/B//wPA//+AAf//wAP//+AH///4
H/////////////////////////////////8=
</value>
</data>

그럼 “기타 ” 카테고리에 항목이 생기면서 아래 처럼 표시된다.

그런 후 에

this.Cursor = (Cursor)Resouce1.TestCursor;

하게 되면 커서는 바뀐다.  그러나 좀 번거롭다… resx를 수동으로 만드는 작업을 해야 하니….

또다른 두번째 방법은 소발에 쥐잡기로 알아낸 방법이다. CursorConverter를 이용해도 된다. 그냥 “파일” 카테고리로 커서 파일을 리소스에 추가해 놓고, 아래처럼 리소스 바이너리 데이터를 커서로 변환한다.

 CursorConverter cv = new CursorConverter();
this.Cursor = (Cursor)cv.ConvertFrom(Resource1.Cursor1);


두번째가 조금 간단해 보인다.. 참고) 더 나은 방법이 존재할 거라 본다.

오늘은 요까이

Posted in C# | Leave a Comment »

시간 간격 구하기

Posted by Digital Angel Master on 1월 28, 2008

시간을 계산해야 할 일이 필요했다.

내가 필요했던 부분은 경매사이트에서 DB에 들어있는 마감시각을 가져와서 현재시각과 계산하여 남은 시간을 계산하기 위해서였다.

C#에서 DateTime이 시간이다. 보통 DB에도 “2007-07-23 오전 12:52″같은 형식으로 들어가는데 그럼 이것을 어떻게 계산을 해야하는가? 일단 그냥 빼기를 해서는 계산이 되지를 않았다.

C#에서는 연산자 오버로드를 할 수 있으므로 연산자 오버로드를 해야하는가 하면서 이것저것 뒤지다가 나온 것인 TimeSpan이다. 둘다 System네임스페이스를 사용한다.

TiemSpan은 시간 간격을 나타내는 구조체이다. DateTime을 계산하기 위해서 사용한다.

일단 소스를 보자.

(Language : cpp)
  1. DateTime end = DateTime.Parse(EndtimeHF.Value.ToString());
  2. TimeSpan t3 = end.Subtract(DateTime.Now);
  3. TimeSpan t2 = DateTime.Now.Subtract(DateTime.Now);
  4. if (t3.CompareTo(t2) > 0)
  5. {
  6.     DeadlineLB.Text = t3.Days + “일 “ + t3.Hours + “시간 “ + t3.Minutes + “분 “ + t3.Seconds + “초 남았습니다.”;
  7. }
  8. else
  9. {
  10.     DeadlineLB.Text = EndtimeHF.Value.ToString();
  11. }

따로 또 수정하기 귀찮아서 그냥 내가 쓴 소스를 그대로 잘라왔다. ㅋ

여기선 히든필드에서 값을 가져왔지만 스트링이면 DateTime으로 캐스팅하면 되고 DateTime이면 그냥 쓰면 된다.

Substract가 값을 빼는 메서드이다. end에서 현재의 시간을 빼고 이걸 TimeSpan t3에 저장해서 남은 시간을 계산했다.

여 기에 시간 간격이 0이하일 경우에는 그냥 종료시간만 표시하기 위해서 TimeSpan t2를 썼다. 이것저것 만져봤지만 TimeSpan의 형식을 정확히 알 수가 없어서 크기를 계산할 수가 없어서 나름대로 꼼수를 부렸다. Substract로 현재에서 현재를 빼서 t2에 저장을 했다. 연산속도를 보았을때 0이 나올 것이고 머 꼭 0이 아니더라도 너무 작은 값이므로 큰 상관이 없다.

비교메서드인 CompareTo를 사용해서 t3와 t2를 사용해서 시간간격이 0보다 큰지 아닌지를 비교했다.

Posted in C# | 1 Comment »

[활용팁] phpMyAdmin 설치/사용자 추가방법

Posted by Digital Angel Master on 1월 28, 2008

요즘 DS-107 구입하신 분이 늘어나면서 테터툴즈 설치 등으로 MySQL 을 사용하시는 분이 늘어나는 듯하여 쉬운 MySQL 관리 툴인 phpMyAdmin (최신판)의 설치/사용자 추가방법을 팁으로 정리합니다.. 설명은 테터툴즈에 맞춰져 있지만 조금만 시도해보면 다른 게시판 등의 데이타베이스 생성도 쉽게 할 수 있을 겁니다.

 

0. 시작하기 전에

1) 굵은 글씨 는 직접 입력해야 하는 부분입니다.

2) 빨간 글씨 는 각각의 설정/조건에 맞게 직접 변경해 입력해야 하는 부분입니다.

3) 스크린샷에서 눈여겨 볼 부분은 빨간 네모/화살표로 표시해뒀습니다.

4) 텔넷 로그인은 root 로 했습니다.. 사실 root로 로그인 자주하는건 안좋은데 귀찮아서.. (먼산)

1. 준비
MySQL을 처음 설치했을 경우 데이타베이스 설치, root 유저 암호 설정을 끝내주셔야 합니다.
* mysql이 작동되는 사용자명은 mysql 로 가정합니다. root로 작동하는 경우 –user=mysql 부분은 필요없을 듯.

 

1) 데이타베이스 설치
mysql 설치 디렉토리로 이동
# cd /opt/mysql

mysql 데이타베이스 설치
# bin/mysql_install_db –user=mysql

mysql 시동
# bin/mysqld_safe –user=mysql &

2) root유저 암호 설정
# bin/mysqladmin -u root password ‘new-password

 

2. phpMyAdmin 설치
1) 다운로드
http://www.phpmyadmin.net/home_page/downloads.php 에서 최신 버전을 받거나 혹은 텔넷상에서 wget을 사용하여 직접 다운받습니다.

 

웹서버 홈디렉토리로 이동
# cd /opt/apache/htdocs

wget으로 다운로드
# wget http://internap.dl.sourceforge.net/sourceforge/phpmyadmin/phpMyAdmin-2.10.1-all-languages.tar.gz

압축 해제
# tar -xvzf phpMyAdmin*.gz

디렉토리명 변경
# mv phpMyAdmin-2.10.1-all-languages phpMyAdmin

압축파일 삭제 (원하는 경우만)
# rm phpMyAdmin*.gz

 

2) 설정파일 변경
phpMyAdmin 디렉토리로 이동
# cd phpMyAdmin

예제 설정파일을 복사
# cp config.sample.inc.php config.inc.php

설정파일 에디트
# vi config.inc.php

* 여기부터는 vi명령입니다 (vi 명령에 대해서는 http://cafe.naver.com/networkhard/1195 참조)

auth_type 설정으로 이동
/auth_type

입력 모드로 변환
i

설정값을 http 로 변경 (화살표 키, 백스페이스 사용)
$cfg['Servers'][$i]['auth_type'] = ‘http‘;

ESC 키 눌러 명령어 모드로 나온 다음 저장후 종료
:wq

3. 홈페이지 접속
기기의 IP의 phpMyAdmin으로 접속합니다. (예: http://192.168.0.106/phpMyAdmin )

 

1) 로그인

앞서 root 암호로 로그인합니다. 만약 이 연결창이 나오지 않는 경우 새로고침을 한번 해 주세요.

2) 로그인 후 사용권한 을 눌러 사용자 설정 메뉴로 들어갑니다.

3) 사용자 설정 메뉴에서 새 사용자 추가 를 눌러 사용자 추가 화면으로 들어갑니다.

4) 사용자 추가에서 사용자명암호를 설정합니다. 호스트는 Local로 설정. 그리고 사용자 추가와 함께 데이타베이스도 같이 추가시킵니다. (Create Database with same name and grant all previliges 선택)

5) 화면 맨 밑의 실행 버튼을 누르면 새 사용자 추가 완료 메세지가 나옵니다. 이제 데이터베이스 설정으로 들어가 확인합니다.

6) 데이터베이스가 추가되어 있는 것을 확인할 수 있습니다. 하지만 언어설정이 latin으로 되어 있어 그냥은 사용할 수 없고, 테터툴즈에서 사용하는 UTF8 설정으로 변경시켜야 합니다. 데이터베이스 이름을 누른 후 위쪽 탭에서 테이블 작업 탭을 누릅니다.

7) 테이블 작업 탭 화면입니다 (데이터베이스 이름만 누르고 화면이 다르다고 뭐라 하지 마세요 -_-) Collation을 utf8_unicode_ci 로 변경한 후 실행 버튼을 누릅니다.

8)  다시 데이터베이스 리스트를 보시면 설정이 변경된 것을 알 수 있습니다. 설정 완료. 이제 테터툴즈 설치하면 됩니다.

 

4. 자주(?) 묻지는 않을 지 몰라도 알아둬야 하는 문제;
1) 80번 포트를 사용하지 않을 경우
  저처럼 8080 포트 등을 사용할 때에는 아파치의 httpd.conf 의ServerName 설정에 포트까지 확실히 지정해야 합니다.
ServerName localhost:8080
2) 새 사용자 추가를 눌러도 반응이 없을 경우
  링크스테이션이 그런데요, /var/session 이 root 만 쓰기가 가능하기 때문에 세션이 생성되지 않아 생기는 문제입니다. 이렇게 퍼미션 변경을 시켜주면 됩니다.
# chmod 777 /var
# chmod 777 /var/session

Posted in Web Programming | Leave a Comment »