IT/Synology NAS2015. 10. 5. 09:15

 

 

 

0. 프롤로그

OwnCloud시놀로지에서는 기본으로 포함되어 있는 일종의 웹하드다.

 

 

시놀로지에서의 기본 설치법은 정말 간단하다. 하지만 이것만 가지고는 안된다(진짜 짜증나는 부분. 모르는 사람은 쓰지도 말라는건지..)
시놀로지의 고급형에서는 링크하드라는 웹하드를 설치할 수 있는데(CPU가 인텔인 경우만) 이게 정말 괜찮다고 하지만, 문제는 내 하드인 215j에서는 링크하드가 안깔린다.
그래서 찾아본게 pydio와 ownCloud다. 여기서는 owncloud설치에 대해 얘기해보고자 한다.

 

1. owncloud설치 사전작업

무조건 설치만 해서 되는게 아니라 몇가지 사전 작업이 필요하다. 왜 자기네 패키지로 올려놓고서 이런 복잡한 작업을 하게 하는지 이해가 되진 않는다. (뭐, 그냥 주는것만으로도 감사해야 하나..?)

 

첫번째는 공유폴더를 만들어주는 것이다. 공유폴더 정도는 다들 만들줄 아실테니 길게 설명은 안하겠다.
공유폴더를 만들때는 각자의 사정이 있겠지만, 하드가 2개 이상이고 논리적으로도 2개 이상(볼륨이 1 초과하는 경우)에는 다른 하드에 부여하는 것도 나쁘진 않을거 같다. 특히 외부 친구들이나 업무적으로 사용할때는 공간의 나눔은 매우 중요하다.
지금은 volume2에 owncloud 공유폴더를 만들었다.

두번째는 maria DB, phpMyAdmin을 설치한다.(이미 되어 있으면 패스한다.)
phpMyAdmin의 주의점은 반드시 한번 실행해서 들어간 다음 root의 암호를 바꾸라는 것이다. 기본이 [암호없음]이기 때문에 반드시 들어가서 암호를 변경해야 후환이 없다. 만약 나중에 바꾸면 owncloud에도 문제가 될거 같다..(뭐 물론 암호를 다시 물어볼거 같긴 하지만..)

 

2. owncolud 설치

패키지센터 - 커뮤니티에 가면 owncolud가 있다. 일단 그냥. 설치하면 된다. 그러면 다운로드가 시작된다. 다운로드는 상황에 따라서 무지무지 오래 걸릴 수도 있다. 

 

다운로드가 완료되면 설치가 시작된다. 설치의 시작은 두가지 암호에 대한 설정이다.

첫번째는 root의 암호를 넣으라는 건데, 암호를 처음부터 세팅하지 않았다면 넘어가도 될거 같다(물론 안해봤다. 하지만 보안을 위해서라도 phpMyAdmin에서 암호를 설정하기를 권한다).
phpMyAdmin에서 설정한 root의 암호를 넣으면 된다.

두번째는 owncloud의 암호를 넣으라는 거다. owncloud 사용자를 만들거니 그 암호를 넣으라는 것으로 보인다. 당연히 암호를 설정하고 다음을 누른다.

 


다음을 누르면 말그대로 admin을 설정하는 화면이 나온다. 꼭 user name을 admin으로 안해도 된다. 워낙 admin이 기본이다보니, 해킹의 첫번째 목표가 되어버린다.
고로 가능하면 다른거로 바꿔주자.(물론 잊어먹으면 곤란하다..) 그리고 admin역할 ID의 암호를 설정해 준다.
그 밑의 것은 데이터(파일들)을 어디다 저장할지를 묻는 것이다. 이 경로를 아까 설정한 공유폴더로 설정하면 된다. 공유폴더명이 owncloud가 아니면 폴더명에 맞게 고쳐주면 될거다. 화면은 volume1(기본값)으로 되어 있으나 이걸 volume2로 수정하면 volume2로 설정된다.

 

다음을 누르면 최종화면이 나온다.

여기서 [적용]버튼을 누르면 지금까지 입력했던 각종암호를 테스트하고 문제가 없으면 완료시키게 된다. 그런데 root의 암호가 틀리거나 하는 문제가 발생되면 당연히 더이상 진행하지 못한다. 그러면 [뒤로] 버튼을 눌러서 암호를 수정하면 된다.

왜 굳이 처음 암호를 넣을때 점검을 안하는지 모르겠다.(뭐.. 그냥 사용자에 대한 예의가 없는 걸로.. 암호도 모르는 유저하고는 상대하기도 싫은가..)

 

 


모든 작업이 완료되면 패키지설치화면에 owncloud가 [설치]에서 [열기]로 바뀐다. 바로 열기를 클릭한다. 만약 설치가 잘 되었다면 다음의 화면이 나올 것이다. 바로 [X]를 눌러서 닫는다. 

 

 

잘 설치가 되었다면 로그인 창이 뜰것이고, 설치에 문제가 있으면 문제점을 보일 것이다.
발생할만한 가장 큰문제점이 아까 설정한 공유폴더를 owncloud가 사용할 수 없다고 메시지를 내는 것이다.
말그대로 권한이 없는건데, 이건 puttty등을 사용해서 접속한 다음, 공유폴더의 권한을 777로 바꿔주면 된다.(putty사용법은 검색해보세...)
이때 주의할 점은 SSH로 NAS에 접속할때는 반드시 root로 접속해야 한다. admin으로 하면 권한이 없다고 하니(로그인은 된다), 반드시 root로 접속을 해야 한다.
물론, 시놀로지 사용자에는 원래 root가 없다. 그냥 root에 admin의 암호를 주면 된다.

 

3. ownCloud실행

 

모든 작업이 완료되면 ownCloud에 접속해보자.

ownCloud에 접속하는 방법은 NAS주소에 owncloud를 붙이면 된다.

 

http://나스주소/ownCloud 라고 하면 된다. 다만 이부분은 내부 네트워크 환경망에서 접속할때 사용 방법이고 외부에서 접속하면 또 몇가지 추가적인 방법이 필요하다. 이건 후에 설명하겠다.

 

접속을 하게 되면 위와 같은 최초 화면이 나온다. 아직 사용법은 잘 모르겠고 중요한 것은 우리가 하고자 하는 일에 대한 정의다.(뭐가 이리 거창한지..)

여기서 추가적인 작업을 해야 하는데, 상단에 보면 [새로만들기] 옆에 위로 향하는 화살표가 하나 보인다. 딱 감이 오지 않는가??
업로드 버튼이다. 그런데, 마우스를 가져다 대면 캡쳐에서 보이는 바와 같이 최대 513MB라고 나올거다.(원래 이게 정상이다..)

웹하드를 설치하고자 하는데 위 이미지에서 보듯이 업로드 가능용량이 513M?? 이건 옛날 CD1장도 안되는 사이즈다. (이래선 동영상 연동이 안된다는..) 이걸 수정하는게 또 일이다.

 

4. Putty를 통한 용량 수정

 

뭐 그냥 쓸수도 있겠지만 NAS를 사용하고 대용량 파일을 사용하기 위함이니 용량을 늘려보자.

 

첫번째는 php.ini를 수정해야 한다. 메모장을 하나 열어서 다음을 저장한다. 딱 한줄이다. 파일명은 전통을 따라서 phpinfo.php 로 만들어준다.


<? phpinfo(); ?>


이 파일을 NAS의 web폴더에 넣어준다.
그리고 그 파일을 웹으로 열어준다. 여는 방법은 만약 나스의 IP가 192.168.0.100 이라면..

http://192.168.0.100/phpinfo.php

 

그러면 php의 정보가 쭉 나열된다.(이걸 몰라서 pydio설치할 때는 온갖 삽질을 했다는..) 이중 다른건 잘 모르겠고 Loaded Configuration File 을 찾는다. 이게 php.ini의 위치다. 이걸 수정해야 한다. 다른 프로그램(config Editor같은거)을 이용하면 다른 위치의 내용을 뿌려주는 경우가 간혹 있으니 조심해야 한다.

 

정보를 알아냈으면 putty를 사용해보자.
실제 입력방법중 가장 간단한게 디렉토리를 바꾸는건데, 가장 위로 가는 방법이 다음과 같다. cd 디렉토리 변경인데, cd ..(cd 다음에 한칸 띄고 .. 이다)을 입력하고 커서 위쪽키를 누르면 직전 입력한 명령어가 나오니 커서 위쪽키를 누르고 엔터를 몇번 반복한다. 그다음 ls -a 는 현재 폴더의 내용을 전부다 보여주는 명령어다.
여기서 다시 cd를 써서 아까 php.ini의 경로로 간다. 

 

그다음..
vi를 써서 수정해야 한다. vi는 유닉스(또는 리눅스)용 문서 편집기다. 다만, 처음엔 좀 어렵겠지만 몇번 써보면 간단한다.(그리고 생각보다 간단하고 무지 강력한 에디터다.)
다시 돌아와서.. 원하는 폴더까지 이동을 했으면 vi php.ini를 입력하면 php.ini가 열린다.

그중 다음을 찾는다.

 

 

[PHP]
engine = On
short_open_tag = On
asp_tags = Off
precision = 14
output_buffering = 4096
zlib.output_compression = Off
implicit_flush = Off
serialize_precision = 17
disable_functions =
disable_classes =
zend.enable_gc = On
expose_php = Off
max_execution_time = 240
memory_limit = 512M
error_reporting = E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
display_startup_errors = Off
log_errors = On
log_errors_max_len = 1024
ignore_repeated_errors = Off
ignore_repeated_source = Off
report_memleaks = On
track_errors = Off
html_errors = Off
variables_order = "GPCS"
request_order = "GP"
register_argc_argv = Off
auto_globals_jit = On
default_mimetype = "text/html"
default_charset = "UTF-8"
include_path = "."
extension_dir = "/usr/lib/php/modules"
sys_temp_dir = "/var/services/tmp"
enable_dl = Off
file_uploads = On
upload_tmp_dir = "/var/services/tmp"
upload_max_filesize = 2G

post_max_size = 2G

max_input_time = 20000
max_file_uploads = 20
allow_url_fopen = On
allow_url_include = Off
default_socket_timeout = 60

이중 3가지만 수정한다.

 

upload_max_filesize = 2G

post_max_size = 2G

max_input_time = 20000

 

"=" 다음 값은 다를 수도 있으니 앞의 문자열만 찾는다.

첫번째는 업로드 시간이다. 파일이 크면 당연히 오래 걸리니 한 20000으로 바꿔준다. 단위는 초다.
두번째, 세번째는 업로드 사이즈다. 당연히 이 두가지를 키워야 한다. 기본은 byte이며 간단하게 2G로 둘다 바꿔주면 된다.2000M로 써도 된다.

실제 수정방법은 vi가 실행되었으면 [i]를 누르면 수정모드로 들어간다.(이전에는 방향키 외에는 입력키가 먹지 않는다.)
원하는 위치로 가서 수정한 다음, 모든 수정이 완료되면 [ESC]를 눌러서 수정모드를 종료한다.
그리고 [:]을 입력하면 맨 밑에 : 이 보인다.
여기서 wq를 입력하고 엔터하면 수정내역이 저장된다.
이렇게 php.ini가 수정되면 pydio는 업로드 가능 사이즈가 확 변한다. 그런데 owncolud는 하나더 수정해야 한다.
다시 cd .. 을 반복해서 최상위로 돌아간다.

 

그리고 아까 owncolud설치했던 폴더로 들어간다.  경로는 [volumeX]/web/owncloud가 기본이다.(volumeX에서 X는 논리적 드라이브 번호다) 여기서 아까처럼 vi를 써서 파일을 연다.

 

vi .user.ini

아까 php.ini를 수정하는 것과 동일한 방법으로 다음 두줄을 수정한다.

upload_max_filesize=2G
post_max_size=2G

memory_limit=512M
mbstring.func_overload=0
always_populate_raw_post_data=-1
default_charset='UTF-8'
output_buffering=off 

 

역시 513M를 원하는 사이즈로 바꿔준다. 여기서는 2G로 설정한다. ESC키를 누르고 :wq해서 저장한다.

여기까지 완료하면 일단, NAS를 리부팅한다. 명령어중에 webserver만 리부팅하는 명령어가 있다고 하는데 걍.. DSM에서 [다시시작]하면 된다.

리부팅이 되면, owncloud를 웹화면에서 다시 실행해본다.

 

http://192.168.0.100/owncloud  (당연하겠지만 앞의 주소는 각자의 상황에 맞춰서...)

 

최초 설정한 admin(또는 admin에 해당하는 ID)와 암호를 넣어서 로그인한다. 아까 업로드 사이즈를 확인해보면 용량이 업되어 있는 것을 볼 수 있을 것이다.

 

그러면 기본적인 설치는 전부 완료된 것이다.

 

5. 외부에서 ownCloud사용하기

pydio같은 경우는 설치가 완료되면 외부 도메인을 사용하여 여는 것에 대해 관대하다. 그러나, ownCloud는 그렇지 않다.

 

우리가 보통 외부에서 집에 있는 NAS에 접속하기 위해서는 나에게 부여된 유동IP를  알아내기 위해 DDNS등을 사용하고 있다. 그런데 알다시피 DDNS도 도메인의 일종이다. pydio는 그냥 열면 열리나, ownCloud같은 경우는 해당 도메인이 적절한지를 꼭 확인하고 등록해줘야 한다.

설치가 잘 되어 있으면 도메인을 추가할 것인지 묻고 바로 등록해주나 설치에 문제가 있다면 직접 수정해줘야 한다.

 

마찬가지로 vi를 사용하기 위해 putty로 접속한 다음 web폴더 안에 ownloud/config폴더를 찾아간다.

 

그안에 있는 config.php파일을 vi로 연다.

<?php
$CONFIG = array (
  'instanceid' => 'ocm1a8woxqg3',
  'passwordsalt' => 'xhxn6KzYGkIpRjR3qr20/jMD0UsuEM',
  'secret' => 'XU45SR+pv6pLkRm4Wls2t+m+9vdvcrrCBg3Tht+/zdndcFDg',
  'trusted_domains' =>
  array (
    0 => 'xxxxxxxx.synology.me',
    1 => 'xxxxxxxx.iptime.org',
  ),
  'datadirectory' => '/volume2/owncloud',
  'overwrite.cli.url' => 'http://xxxxxxxxx.synology.me/owncloud',
  'dbtype' => 'mysql',
  'version' => '8.1.3.0',
  'dbname' => 'owncloud',
  'dbhost' => 'localhost',
  'dbtableprefix' => '',
  'dbuser' => 'owncloud',
  'dbpassword' => 'adadadadad',
  'logtimezone' => 'UTC',
  'installed' => true,
  'theme' => '',
  'maintenance' => false,

 

안에 보면 trusted_domains가 있는데 여기에 원하는 도메인을 추가해 주면 된다.내부망는 굳이 등록안해도 되고 그외에 DDNS나 synology용 DDNS의 도메인은 등록해야 사용이 가능하다.

 

아까도 얘기했지만, pydio같은 경우는 원래 가지고 있던 정식 도메인이 있어서 iframe를 이용하여 내 nas의 DDNS가 대놓고 노출되지 않도록 하였으나 ownCloud같은 경우는 iframe를 사용하면 아예 로딩이 되지 않는다. 그래서 도메인 업체에서 포워드 할때 도메인을 고정시키지 말고 변경되도록 해야 한다.

 

결국 owncould사용시에는 내 DDNS를 노출시킬 수 밖에 없는 문제가 있다는..

 

 

6. 마치며

ownCloud를 설치후 많이 사용해보진 않았다. pydio와 비교해 보면..

 

장점으로는 확실히 pydio보단 빠르다. pydio는 접속을 시도하면 확실히 느리지만 ownCloud는 로그인창도 많이 빠르고 안에 들어가는 것도 확실히 빠르다. 그리고 간결하고 직관적이다.

 

단점으로는 pydio는 안드로이드 핸폰 앱이 무료인데 owncloud는 유료인게 굳이 단점이라면 단점이겠다.

 

나머지는 좀 써봐야 하겠다.

 

혹시 pydio, ownCloud말고 추천할만한 웹하드가 있다면 추천좀 부탁한다.(링크하드 뺴고... ㅠㅠ)

 

 

 

 

 

 

 

 

 

 

Posted by 비와바람
IT/Synology NAS2015. 9. 16. 11:21

DS215j를 사용하고 있습니다.

정말 정말 어렵게 깔았네요..

실제 설치 방법은 여기저기 많으니 따라하심 됩니다.

 

http://blog.naver.com/PostView.nhn?blogId=kimkim0313&logNo=220430743547&parentCategoryNo=&categoryNo=&viewDate=&isShowPopularPosts=false&from=postView

 

아. 이 링크는 NAS가 아니라 웹서버(PC)에서 설치시이니 pydio설치부분만 보시면 됩니다.


다만 리눅스 및 나스를 잘모르시는 분들.. 저같은 사람을 위해서 몇가지만 첨언하고자 합니다.

일단, 이미지 없고 풀텍스트로만 합니.. 쿨럭..

 

 

[pydio설치전]
1. PhpmyAdmin과 mariaDB를 설치합니다. 이때 암호는 잘 기억해두세요..


PhpmyAdmin을 설치를 다 하고 경로/phpMyAdmin으로 웹주소를 기재하면 root(admin이 아닙니다..) 암호를 입력해야 하는데..  이거 기본이 암호 없음이므로 빈칸으로 그냥 root에 "실행"하시면 됩니다.

저는 설치는 전에 했다가 다시 재도전인데, 원래 암호가 없었는데 암호를 수정한 줄 알고 한참 해맸다는..

하지만 반드시 암호는 바꿔줘야 합니다. 외부로 공개되는 순간, 암호가 없으면 털릴 확률이 넘 높습니다.

뭐, 중요한 자료야 있겠습니까만(그녀들..?), 그래도 재설치하고 그냥 암생각없이 모았던 자료라도 다 날려먹음 눈물좀 나겠지요...

 

2. 공유기 설정
그리고, 내부 같은 망에서 작업하시면 상관없는데, 외부(저같이 회사에서 일안하고 이딴 짓(!) 하는 경우에는.. 켁..) 반드시 공유기의 포트를 확인해야 합니다.

뭐, DSM으로 붙여서 보시기 위해 기본적으로 5050은 포트포워드 하셨을 겁니다.


이것처럼 외부에서 작업하시려면 나스연결용으로 5050번, phpMyAdmin용으로 9091번이 열려 있어야 하고 Putty를 이용하기 위해서는 SSH를 사용해야 하는데, 기본이 22번입니다.

(근데, 전 이거 2212로 바꿔썼습니다.(왜 바꿨는지 기억은..) 이거 땜시 연결안되는 이유를 몰라서 한참 고생을.. 아마 해킹 가능성이 높은 기본포트라서 바꿔쓴거 같긴 합니다만..)

음.. 이거 외에는 대충.. 다른 분들이 설치안내기 써놓으신거 보면 큰 문제 없습니다.


[pydio설치]
맨처음 문제는 과연 pydio파일을 어디다 복사해야 하는가 하는 문제입니다.

가장 간단한 방법은 공유폴더 리스트를 보면 web 라는 기본 공유폴더가 있습다. 여기에 넣으심 됩니다.  web 밑에 넣으심 되는데, 여튼 복사를 하면 접속주소/pydio설치폴더로 접근하면 실제 설치가 진행됩니다.

다행히 안의 내용이 전부 상대경로인거 같아서 다행이지만(폴더명을 바꿔도 바로 됩니다만, 경험상 폴더명을 바꾸면 재설치하는게 낫습니다), 이 web 밑에 폴더를 만들면 접속시 주소/폴더명을 해야 합니다.

예를 들어서.. 주소가 . abc.iptimg.org 인데 pydio폴더명을 그냥 pydio로 했다면,  http://abc.iptimg.org/pydio 로 해야 합니다.게다가 해보니.. 폴더명은 대소문자를 구분하는거 같더군요.

원래 DDNS를 사용하려니 주소명도 좀 복잡한데, 뒤의 폴더명까지 쓰려니 무지무지 복잡하니, 걍.. 폴더명을 "1"로 하시는건 어떨지..

그러면 http://abc.iptimg.org/1 로 접속하면 되는거죠.

 

여기서 웹문서중에는 리눅스 시스템 답게 파일(또는 폴더?)의 권한을 변경하는 얘기가 있습니다만, 이건 그냥 현재 로그인하고 있는 아이디가 web폴더를 읽기/쓰기 할수 있으면 됩니다.

파일 복사는 그냥 로컬 네트워크 상에서 하면 되는데, 당연히 web폴더를 열려면 NAS에 등록되어 있는 아이디로 하겠지요?? 그 아이디가 web폴더를 읽고 쓸수 있으면 된다는 겁니다.

전 복사했던 아이디와 로그인 아이디의 폴더권한이 달라서 한참 삽질했습니다.

 

복사가 완료되면 접속주소/pydio설치폴더 로 웹주소를 오픈하면 기본 설치가 시작됩니다.

 

만약 이때 특정폴더(또는 파일)의 수정권한(write)이 없다면 위에 쓴 권한을 다시 확인해야 합니다. 실제 설치는 인터넷에서 찾아보세.. 쿨럭..

주의점은 Admin설정할때입니다. admin은 꼭 admin이나 root로 안하셔도 되고 그냥 자주 쓰는 아이디 써도 됩니다. 마스터 아이디를 설정하는 과정이라고 보시면 되고 나중에 보니까 마스터 권한은 나중에 추가로 다른 아이디에 부여도 가능하더군요.
암호가 무지 길고 복잡해야 합니다. -.-;;

 

[pydio실행]
pydio 설치가 완료되면 그냥 웹페이지가 백지가 됩니다만, 주소에서 엔터를 치면 이제는 설치가 아닌 pydio로그인이 뜹니다.

위에서 말한것 처럼 다른 외부에서 접속할 때 접속주소/폴더명까지 치라고 하는게 문제라면 문제겠지요.


가장 간단한 방법은 설치에서 얘기한것처럼 설치폴더명을 "1"등 짧은걸로 만드는 겁니다. 가장 간단하고 무식(!)한 방법이죠.

좀 신경쓴다면? web폴더의 index.html을 수정하는 겁니다. 이방법은 기본적으로 NAS에서 홈페이지는 아예(!) 운영하지 않고 웹하드용으로만 쓰겠다는 전제로 합니다.

 

뭐, 홈페이지 만들줄 아시는 분은 대충 감이 오실겁니다만...

web폴더에 보면 index.html이 있습니다. 이 파일을 그냥.. rename해 버립니다.

그리고, 메모장을 열고 다음을 복사해 넣습니다. 여기서 설치폴더는 pydio로 가정합니다. 1 이면 pydio대신 1 쓰면 됩니다.


<HTML>
<HEAD>
 <meta charset = "UTF-8"> 
  <TITLE>Web Hard</TITLE>
 <frameset rows = "100%, 0%">
 <frame src = "http://abc.iptimg.org/pydio">
 </frameset>

</HTML>
</HEAD>

그리고 이 메모장을 index.html로 저장후 web폴더에 복사합니다. 그러면, abc.iptimg.org에 접속하면 바로 웹하드가 뜨게 됩니다. 그리고 frame처리 했기 때문에 주소창이 변경되거나 하지도 않습니다.

기본적인 http://abc.iptimg.org가 남아 있는거죠.

 

여기에 더 추가한다면...

아예 내 도메인으로 만들 수도 있습니다. 일단 DDNS의 사용은 어쩔수 없습니다. 내 NAS의 IP는 언제 바뀔지 모르죠(그야말로 통신사 마음.. 전 거의 1년째 같은 IP를 쓰고 있긴 합니다만.. 여튼 그게 싫으면 고정 IP서비스 받으심 됩니다만.. 그돈으로 까까 사드세..).

적당한 도메인업체에 내 도메인을 등록(이라고 쓰고 구매라고 읽는다. 당연히 도메인은 년단위 과금이 있습니다)합니다. 등록이 되면 포워드를 신청하면 됩니다. 이 도메인에 접속을 요청하는 경우에는 어디로 보내달라.. 뭐 그러는거죠. 이때 포워딩을 DDNS로 신청하면 됩니다. 등록을 하면 보통 전체로 퍼져나가는 시간이 있어서 하루정도 걸릴겁니다만, 내 도메인이 있거나, 위의 iptime.org이딴게 싫고 짧게 쓰고 싶다면 돈으로 해결을...(쿨럭..) 값은 보통 싼게 .kr이 1만원(1년)이 조금 넘습니다.

 

[설치후 발생되는 문제점 해결]

설치도 뭐 할만하구요(보급형인데도 설치가 그렇게 느리진 않더군요).

그런데, 명색이 웹하드인데.. 업로드가 쬐..끔만 되면 문제겠지요?? 일단 기본이 32M입니다. 그 이상은 안올라가요.

물론, 수정하면 됩니다(!).

다음 링크를 참고하시면 됩니다.

 

http://blog.naver.com/kimkim0313/220436769722

 

 

그 설정이 PHP.ini에 있습니다. 이 PHP.ini를 수정하는 방법은 여러가지가 있는데요, 그냥 putty 등을 사용해서 vi로 수정하는게 가장 편하더군요. 이것 역시 찾으면 무지무지 많이 나옵니다만..

여튼, 그렇게 PHP.ini를 수정하고 나서  pydio의 설정(admin으로 설정한 ID로 로그인해야 합니다) - Application Core - Uploader Option의 Limitations에 보면 File Size가 있는데 이걸 PHP.ini의 MAX_UPLOAD_FILESIZE의 용량과 같거나 조금 작게 설정해주면 됩니다.

 

근데 이걸 저장했는데도 File size가 원상복귀가 된다면??

이건 PHP.ini수정에 뭔가 삽질이 있었다는 겁니다.

첫번째가 실수로 MAX_UPLOAD_FILESIZE가 두개 있을 수 있습니다. 뭐.. 이건 봐서 하나 지우면 됩니다.

 

하지만 이건 도리어 가능성이 거의 없는거고, 그것보단 어디에 있는 PHP.ini을 읽느냐가 문제가 됩니다. 전 인터넷상에서 말하는 위치, /usr/syno/etc에 PHP.ini를 믿었고 또한 Config File Editor이라는 프로그램에서도 자동으로 저 위치를 열어줬는데,

실제 제 NAS는 전혀 다른 위치를 보더군요.

이거 알아내는게 꽤 걸렸습니다.

 

방법은 생각보다 간단합니다.

 

아까 index,html만들듯이 메모장 열어서 다음과 같이 입력합니다. 딱 한줄입니다.

 

<? phpinfo(); ?>

 

그다음, phpinfo.php라고 파일명으로 저장한 다음 이 파일을 web폴더로 복사합니다. 그리고 이 php을 웹브라우저에서 실행합니다. 도메인이 http://abc.iptimg.org라면 그냥..

http://abc.iptimg.org/phpinfo.php를 주소창에 치면 됩니다.

그러면 PHP Version과 PHP관련 설정을 표로 쫘~악.. 나열해줍니다.

딴건 잘 모르겠구요.. 여기서 필요한거는 Loaded Configuration file입니다. 이게 실제 웹서버가 읽어들이는 PHP.ini경로입니다.

결국 이건 방법이 딴게 없고 putty등으로 로긴해서 해당경로로 이동한 다음 vi로 다시 파일을 편집하는 수밖엔 없더군요.

이거 수정하고 pydio설정을 다시 수정하니.. 됩니다.. ㅠㅠ

아무도 안알려주셨는데 SLR클럽의 작은꼬마님께서 주신 조언으로(첨엔 이것도 뭔소린지 몰랐...) 찾은 방법입니다(아시는 분은 다 아시겠지요...??)

 

[아직 미해결]

업로드는 해결했는데 다운로드가 좀 불편합니다.

아마 Synology의 disk station을 사용해도 올리는건 정말 간단하게 파일을 그냥 올리기만 하면 되는데, 문제는 다운을 받을때는 무조건 압축을 해버리는 군요.

이것만 해결되면 좀 편하게 쓸수 있을거 같기도 합니다만, 이걸 하는 국내업체는 대부분 웹이 아닌 activeX로 했을 가능성이 높아서 좀 아쉽습니다.

 

지금까지 시놀로지 NAS에 pydio설치에 대해 얘기했습니다.

생각보다 많이 안쓰셔서 관련문서가 없어서 고생좀 했습니다. ㅠㅠ

나중에 같은 삽질을 안하시기를 바라면서 여기서 마치겠습니다.

 

Posted by 비와바람
IT/Delphi2015. 1. 26. 15:36

































































































































































































































































































































































































































































































































































































































































































유니트 찾기
Type Unit
_Stream ADODB_TLB
akTop, akLeft, akRight, akBottom Controls
AnsiLowerCase SysUtils
Application (the variable not a type) Forms
Beep SysUtils or Windows (different functions)
CGID_EXPLORER ShlObj
CN_BASE Controls
CoInitialize ActiveX
CopyFile Windows
CoUnInitialize ActiveX
CreateComObject ComObj
CreateOleObject ComObj
Date SysUtils
DeleteFile SysUtils or Windows (different versions)
DispatchInvokeError ComObj
DWORD Windows
EDatabaseError DB
EncodeDateTime DateUtils
EnumWindows Windows
EOleError ComObj
EOleException ComObj
EOleSysError ComObj
Exception SysUtils
ExtractFileName SysUtils
FileExists SysUtils
FileOpen SysUtils
FILETIME Windows
FindFirst SysUtils
FindFirstFile Windows
FindWindow Windows
FlushFileBuffers Windows
fmOpenRead SysUtils
fmShareDenyWrite SysUtils
Format SysUtils
FormatDateTime SysUtils
FreeAndNil SysUtils
fsBold Graphics
ftWideString DB
ftString DB
GetCurrentProcessId Windows
GetEnvironmentVariable SysUtils or Windows (different versions)
GetFileAttributes Windows
GetFileVersionInfoSize Windows
GetStdHandle Windows
GetTickCount Windows
GetWindowLong Windows
HDC Windows
HFont Windows
HINTERNET WinInet
HKEY_CURRENT_USER Windows
HWND Windows
IHTMLDocument2 MSHTML or MSHTML_TLB
IHTMLElement MSHTML or MSHTML_TLB
IHTMLEventObj MSHTML or MSHTML_TLB
IID_IWebBrowser2 SHDocVw or SHDocVw_TLB
IMessage CDO_TLB
InternetClosehandle WinInet
InternetOpenUrl WinInet
InternetReadFile WinInet
IntToHex SysUtils
IntToStr SysUtils
IOleCommandTarget ActiveX
IOleContainer ActiveX
IPersistStreamInit ActiveX
IsSameDay DateUtils
IStream ActiveX
IWebBrowser2 SHDocVw or SHDocVw_TLB
LockWindowUpdate Windows
Log10 Math
LowerCase SysUtils
LPSTR Windows
MAX_PATH Windows
MessageBox Windows
MessageDlg Dialogs
MB_YESNO, MB_OK etc Windows
MinutesBetween DateUtils
Now SysUtils
OleInitialize ActiveX
OleUninitialize ActiveX
PItemIDList ShlObj
POleCmd ActiveX
POleCmdText ActiveX
PostMessage Windows
PosX StrUtils
QueryHighPerformanceCounter Windows
QueryPerformanceCounter Windows
RandomRange Math
ReverseString StrUtils
RoundTo Math
SendMessage Windows
SetForegroundWindow Windows
ShellExecute ShellAPI
ShellExecuteEx ShellAPI
SHGetFileInfo ShellAPI
SHFILEINFO ShellAPI
ShowMessage Dialogs
Sleep SysUtils
StrAlloc SysUtils
StrPas SysUtils
StrToDate SysUtils
StrToInt SysUtils
StrToIntDef SysUtils
TAdoConnection ADODB
TAdoQuery ADODB
TAlign Controls
TAlignment Classes
TAnchors Controls
TBitmap Graphics
TBlobStream DBTables
TCanvas Graphics
TClientSocket ScktComp
TComboBox StdCtrls
TComponent Classes
TControl Controls or QControls
TCriticalSection SyncObjs
TField DB
TFieldType DB
TFileName SysUtils
TFileStream Classes
TForm Forms
TFrame Forms
TGroupBox StdCtrls
TIID ActiveX
TIniFile IniFiles
TJPEGImage Jpeg
TLabel StdCtrls
TList Classes
TMemo StdCtrls
TMemoryStream Classes
TMouseButton Controls
TNofityEvent Classes
TObjectList Contnrs
TOSVersionInfo Windows
TPanel ExtCtrls
TPoint Types
TProcessEntry32 TlHelp32
TProgressBar ComCtrls or QComCtrls
TRadioButton StdCtrls
TRadioGroup ExtCtrls
TRect Types
TRegistry Registry
Trim SysUtils
TRoundToRange Math
TSearchRec SysUtils
TSize Windows
TSocketAddrIn Winsock
TStaticText StdCtrls
TStream Classes
TStringList Classes
TStrings Classes
TStringStream Classes
TSystemTime Windows
TTable DBTables
TTabSheet ComCtrls
TThread Classes
TTreeNode ComCtrls
TWebBrowser SHDocVw or SHDocVw_TLB
TWinSocketStream ScktComp
TWMCommand Messages
Unassigned Variants
VarArrayCreate Variants
VarArrayOf Variants
VirtualProtect Windows
WaitForSingleObject Windows
WM_MOVE Messages
WM_MOVING Messages
WM_USER Messages
YearOf DateUtils

 

 

 

Posted by 비와바람
IT/MS-SQL2014. 12. 19. 17:18

http://msdn.microsoft.com/ko-kr/library/hh272701(v=vs.103).aspx

 

 

저장 프로시저 디버깅

이 항목은 아직 평가되지 않았습니다.- 이 항목 평가

Transact-SQL 디버거를 사용하면 SQL 저장 프로시저의 SQL 호출 스택, 지역 변수 및 매개 변수를 표시하여 저장 프로시저를 대화식으로 디버깅할 수 있습니다. 다른 프로그래밍 언어로 디버깅할 때와 마찬가지로 Transact-SQL 스크립트를 디버깅하는 동안 지역 변수 및 매개 변수를 보고 수정하고, 전역 변수를 볼 수 있을 뿐 아니라, 중단점을 제어 및 관리할 수도 있습니다.

이 예에서는 Transact-SQL 저장 프로시저를 만들고 이를 한 단계씩 실행하여 디버깅하는 방법을 보여 줍니다.

Warning 주의:
다음 절차에서는 이전의 연결된 데이터베이스 개발프로젝트 기반 오프라인 데이터베이스 개발 섹션에 나오는 절차에서 만든 엔터티를 사용합니다.

 

 

저장 프로시저를 디버깅하려면

  1. 솔루션 탐색기에서 TradeDev 프로젝트를 마우스 오른쪽 단추로 클릭하고 추가를 선택한 다음 저장 프로시저를 선택합니다. 이 새 저장 프로시저의 이름을 AddProduct로 지정하고 추가를 클릭합니다.

  2. 저장 프로시저에 다음 코드를 붙여 넣습니다.

    CREATE PROCEDURE [dbo].[AddProduct]
    @id int,
    @name nvarchar(128)
    AS
    INSERT INTO [dbo].[Product] (Id, Name) VALUES (@id, @name)
    
  3. F5 키를 눌러 프로젝트를 빌드하고 배포합니다.

  4. SQL Server 개체 탐색기의 로컬 노드에서 TradeDev 데이터베이스를 마우스 오른쪽 단추로 클릭하고 새 쿼리를 선택합니다.

  5. 쿼리 창에 다음 코드를 붙여 넣습니다.

    EXEC [dbo].[AddProduct] 50, N'Contoso';
    GO
    
  6. 왼쪽 창 여백을 클릭하여 EXEC 문에 중단점을 추가합니다.

  7. Transact-SQL 편집기 도구 모음의 녹색 화살표 단추에 있는 드롭다운 화살표를 누르고 디버거를 사용하여 실행을 선택하여 디버깅이 설정된 상태로 쿼리를 실행합니다.

  8. 또는 SQL Server 개체 탐색기에서 디버깅을 시작할 수 있습니다. 로컬 -> TradeDev 데이터베이스 -> 프로그래밍 기능 -> 저장 프로시저 아래에 있는 AddProduct 저장 프로시저를 마우스 오른쪽 단추로 클릭합니다. 프로시저 디버그...를 선택합니다. 개체에 매개 변수가 필요한 경우 각 매개 변수의 행이 포함된 테이블이 있는 프로시저 디버그 대화 상자가 나타납니다. 테이블의 각 행에는 매개 변수의 이름 열과 해당 매개 변수의 값 열이 있습니다. 각 매개 변수의 값을 입력하고 확인을 클릭합니다.

  9. 지역 창이 열려 있는지 확인합니다. 지역 창이 열려 있지 않으면 디버그 메뉴를 클릭하고 을 선택한 다음 로컬을 선택합니다.

  10. F11 키를 눌러 쿼리를 한 단계씩 실행합니다. 저장 프로시저의 매개 변수와 해당 값이 지역 창에 표시됩니다. 또는 마우스를 INSERT 절의 @name 매개 변수 위에 놓아도 할당될 Contoso 값이 표시됩니다.

  11. 텍스트 상자에서 Contoso를 클릭합니다. 디버깅하는 동안 Fabrikam을 입력하고 Enter 키를 눌러 name 변수 값을 변경합니다. 지역 창의 값을 변경할 수도 있습니다. 이제 매개 변수의 값이 변경되었음을 나타내는 빨간색으로 표시됩니다.

  12. F10 키를 눌러 나머지 코드를 한 단계씩 실행합니다.

  13. Product 테이블의 데이터 뷰에 있는 새로운 내용을 보려면 SQL Server 개체 탐색기에서 TradeDev 데이터베이스 노드를 새로 고칩니다.

  14. SQL Server 개체 탐색기의 로컬 노드에서 TradeDev 데이터베이스의 Product 테이블을 찾습니다.

  15. Product 테이블을 마우스 오른쪽 단추로 클릭하고 데이터 보기를 선택합니다. 새 행이 테이블에 추가되었는지 확인합니다.

 

Posted by 비와바람
IT/Delphi2013. 5. 28. 09:16

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

type
  TForm4 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

function SecondsIdle : DWord;
var
    liInfo : TLastInputInfo;
begin
    liInfo.cbSize := SizeOf(TLastInputInfo);
    GetLastInputInfo(liInfo);

    Result  := (GetTickCount - liInfo.dwTime) div 1000;
end;

procedure TForm4.Timer1Timer(Sender: TObject);
begin
    Label1.Caption := Format('System IDLE Last %d seconds', [SecondsIdle]);
end;

end.

 

Posted by 비와바람
IT/Delphi2013. 4. 3. 09:16

TxQuery는 자체적으로 SQL문을 수행할 수 있는 상용 DataSet 컴포넌트입니다. 다른 데이터셋들로부터 데이터를 가져와 조인을 하여 새로운 결과를 만들어낼 수도 있습니다. 꽤 애용자들이 많았었고, 저도 꼭 필요한 경우가 있어 사용한 적이 있습니다.

그런데 이 TxQuery가 몇년 전부터 업그레이드가 되지 않고, 홈페이지도 폐쇄되었었습니다. 대단히 유명한 컴포넌트는 아니지만 경우에 따라서는 다른 대안이 없이 꼭 필요한 컴포넌트이기 때문에 많이 아쉬웠었는데요.

조금 전에 서핑하다가 TxQuery가 다시 업그레이드되고 있다는 것을 알게 되었습니다. 유명한 델파이 매니아 중 한 사람인 Chau Chee Yang씨가 2009년 말에 원 개발자인 Alfonso Moreno씨에게 연락하여, 오픈소스화를 허락받았다고 하더군요. 게다가 Chau Chee Yang씨는 유니코드 마이그레이션까지 완료해놓아서 델파이 XE, 2010, 2009 버전까지 지원합니다.

TxQuery의 가장 큰 장점은, 클라이언트로 가져온 여러 데이터셋들로부터 로컬 조인이 가능하다는 것입니다. 예를 들면, 다음과 같이 사용합니다. (헬프에 소개된 샘플 코드인데, 설명을 위해 일부러 모두 코드로 구현한 것이며, 폼디자이너에서 각 데이터셋들을 추가할 수 있습니다)

procedure TForm1.FormCreate(Sender: TObject);
var
  XQuery: TxQuery;
  Item: TXDataSetItem;
  sql: String;
begin
  XQuery := TxQuery.Create(Self);
  XQuery.AddDataSet(Table1, 'Customer');
  XQuery.AddDataSet(Table2, 'Orders');
  XQuery.AddDataSet(Table3, 'Items');
  XQuery.AddDataSet(Table4, 'Parts');

  XQuery.SQL.Text := 'SELECT * FROM customer c INNER JOIN Orders o ' +
    'ON (c.CustNo = o.CustNo) INNER JOIN Items i ' +
    'ON (o.OrderNo = i.OrderNo) INNER JOIN Parts p ' +
    'ON (i.PartNo = p.PartNo);';
  XQuery.Open;
end;

TxQuery는 로컬 조인이 가능하기 때문에, 원래의 데이터베이스가 뭐였는지에 대해 완전히 투명하게 됩니다. 즉, 서로 다른 데이터베이스로부터 가져온 데이터셋들을 조인할 수도 있게 됩니다.

또, SQL을 지원하지 않는 데이터스토어, 예를 들면 버클리DB 등에 대해서도 SQL 쿼리가 가능해지죠. (물론 그러려면 실제 필요한 것보다 훨씬 더 많은 데이터를 로컬로 가져와야 하는 경우가 생기지만, 그래도 가능하기만 하다면, 하고 간절한 경우가 종종 있죠)

현재의 최신 버전은 1월 21일에 공개된 2.1 버전이구요. 구글 코드 사이트에서 다운로드할 수 있습니다.
http://code.google.com/p/txquery/

Posted by 비와바람
IT/컴퓨터2012. 9. 7. 10:24

코드 키보드 자판 비고
8 빽 스페이스
9 Tab  
13 Enter 자판과 숫자패드 둘다
16 Shift 양쪽 둘다
17 Ctrl 왼쪽
18 Alt 오른쪽만 왼쪽은 안됨
19 Pause Break  
20 Caps Lock  
25 한자  
25 Ctrl 오른쪽
27 Esc  
32 space  
33 PageUp  
34 PageDown  
35 End  
36 Home  
37 방향키
38 방향키
39 방향키
40 방향키
45 Insert  
46 Delete  
48 0  
49 1  
50 2  
51 3  
52 4  
53 5  
54 6  
55 7  
56 8  
57 9  
65 A  
66 B  
67 C  
68 D  
69 E  
70 F  
71 G  
72 H  
73 I  
74 J  
75 K  
76 L  
77 M  
78 N  
79 O  
80 P  
81 Q  
82 R  
83 S  
84 T  
85 U  
86 V  
87 W  
88 X  
89 Y  
90 Z  
91 윈도우키 왼쪽
92 윈도우키 오른쪽
93 오른쪽마우스키 오른쪽 Ctrl 옆에있는
96 0 숫자패드
97 1 숫자패드
98 2 숫자패드
99 3 숫자패드
100 4 숫자패드
101 5 숫자패드
102 6 숫자패드
103 7 숫자패드
104 8 숫자패드
105 9 숫자패드
106 * 숫자패드
107 + 숫자패드
109 - 숫자패드
110 . 숫자패드
111 / 숫자패드
112 F1  
113 F2  
114 F3  
115 F4  
116 F5  
117 F6  
118 F7  
119 F8  
120 F9  
121 F10  
122 F11  
123 F12  
144 Num Lock  
145 Scroll Lock  
186 ; 세미콜론
187 =  
188 , 쉼표
189 - = 옆에키
190 . 마침표
191 /  
192 ` Tab키위에
219 [  
220 \ 원표시
221 ]  
222 ' 작은따옴표
229 한/영  
http://smartweb.tistory.com/trackback/92

Posted by 비와바람
IT/Delphi2012. 2. 22. 09:29

델마당의 장성호님의 답변해 주신 글입니다.. (물론 제 질문은 아닙니...)

http://www.delmadang.com/community/bbs_view.asp?bbsNo=17&bbsCat=41&indx=409079&keyword1=Hint&keyword2=시간

------------------------------------------------------------------------------


ListView에서 Row별로  힌트를 다르게 주려고 한다면

MouseMove 이벤트에 처리해야 하는것은 맞습니다.


1. 먼저 OnMouseMove이벤트에서 현재 마우스 위치에 Row 즉 ListItem을 알아야 겠죠?

    그것은 ListView에 GetItemAt 이라는 함수가 있습니다.
 
   procedure TForm3.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,  Y: Integer);
   var
      item: TListItem;
    begin
       item:=ListView1.GetItemAt(X,Y);
       ....
   end;

   문론 GetItemAt으로 item을 구했는데 nil 인경우도 있습니다. 
   이럴경우도 처리해야죠

2. Mouse위치의 Item을 알았으니 ListView의 Hint를 바꿔줘야 겠죠
    다음과 같이 마우스 위치의 ListItem을 구해서 ListView의 Hint를 바꿔줄수 있습니다.
 

procedure TForm3.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  item: TListItem;
begin
  item:=ListView1.GetItemAt(X,Y);

  if Assigned(item)then
  begin
      ListView1.Tag:= item.Index ;
      ListView1.Hint:='ListView Items= '+item.Caption;
  end
......
end;
 

     그런데 Hint를 바꾼다고 해서 바로 변경된 Hint가 보여지는것이 아니죠

3.  Hint를 보여주고/ 말고 하는것은 Application객체가 담당합니다.
     
     대게 Hint가 보여지는것은 마우스위치에 있는 Control이 바뀌었을때 해당Control의 힌트를 보여주죠

      그런데 listview에서 mouse만을 움직였을때는 item만 바뀌지 control을 여전히 같은 listview이기때문에
      hint가 보여지지 않는것입니다.


4. 즉각적으로 Hint를 다시 보여주려면 Application의 Hint관련 함수를 이용하면 됩니다.
 
    // 현재 떠있는 힌트를 닫습니다.
    Application.CancelHint;    
  
    // 넘겨준 TPoint위치에 hint를 보여줍니다.
   Application.ActivateHint( point );

5. 결론적으로 listveiw의 hint를 바꾼뒤에
     위 Application 의 CancelHint  , ActivateHint 를 한번씩 호출해주면 됩니다.
 

procedure TForm3.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Integer);
var
  item: TListItem;
begin
  item:=ListView1.GetItemAt(X,Y);

  if Assigned(item)then
  begin
      ListView1.Hint:='ListView Items= '+item.Caption;
      Application.CancelHint;
      Application.ActivateHint(Mouse.CursorPos);
  end;
end;
 

6. 그러데 MouseMove 이벤트가 같은 item위치에서 여러번 발생할수있죠
    마우스위치의 item이 바뀌지 않았는데 반복해서 CancelHint , ActivateHint 를 띄우면
    좀 이상하겠쬬

    그러니 현재 hint로 띄운 item을 기억하고 있을 필요가 있을것입니다.
    
   즉 item이 변경되면 hint를 새로 띄우는것이 아니라
    hint가 변경되면 hint를 새로띄우는것이죠

procedure TForm3.ListView1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  item: TListItem;
begin
  item:=ListView1.GetItemAt(X,Y);

  if Assigned(item)then
  begin
    if(item.Index <>ListView1.Tag ) then
    begin
      //item의 index를 ListView.Tag에 기억해두고 tag가 같지 않는경우에만 ...
      ListView1.Tag:= item.Index ;
      ListView1.Hint:='ListView Items= '+item.Caption;
      Application.CancelHint;
      Application.ActivateHint(Mouse.CursorPos);
    end;
  end;

end;   

     뭐 대충 이런식으로 하면 됩니다.

     이 방식으로 listview뿐만 아니라 VCL의 모든 Control에 적용할수 있습니다.
     마우스 위치의 control이 변경되지 않았는데
     hint를 바꾸고 싶을경우에는 

     1)  먼저 hint를 바꾼후에
     2)  Application.CancelHint;
     3)  Application.ActivateHint(Mouse.CursorPos);
       해주면 됩니다.
    
6. 마지막으로  Application 객체에는 hint관련해서 프로퍼티와 함수가 몇가지 더 있습니다.

      Application.Hint;
      Application.HintColor:=clRed;  //힌트 보여지는 Color
      Application.HintPause; //Control위에 마우스가 들어간뒤에 Hint가 보여지기까지 delay
      Application.HintHidePause; //hint가 나타난후에 사라지기까지 시간
      Application.HintShortCuts;
      Application.HintShortPause;

7.  hint를 좀더 발전된 형태로 보여주고 싶다면

     THintWindow 를 상속받아서 hint 클래스를 새로만드시구요   
     TMyHintWindow = class(THintwindow) 
   
     다음과 같이 HintWindowClass 에 설정해주시면
     HintWindowClass := TMyHintWindow
     Application객체가 HintWindowClass 에 등록된 class를 생성해서 보여줍니다.

그럼..

Posted by 비와바람
IT/Delphi2011. 3. 15. 14:34

흠... 좋은 팁이란 바로 이런거다...
초보 델피언으로 많은 시간을 허비해야 했던 바로 그 문제의 답이 될 수 있는 팁을 발견했다.

좋은 팁을 올려주신 양병규님께 감사드린다. - 출처 델마당 팁란

http://www.delmadang.com/cwb-bin/CrazyWWWBoard.exe?db=dmdlec3&mode=read&num=3866&page=1&backdepth=1

인용
--------------------------------------------------------------------------------------------------------------------
음...

어떻게 보면 기본인것같은데.. 의외로 많은 분들이 잘 모르시는 것같아서... 이야기해봅니다.

액세스바이올뢔이션 에러가 발생하면 에러난 위치의 주소값을 16진수로 보여줍니다.

그 화면을 본 사용자는 큰일 난줄알고 바로 연락하는 경우가 많은데...

그 화면의 내용을 줄줄줄 다 읽어주기도하고....

보통은 캡쳐해서 보내주기도하는데...

정작 그걸 보는 개발자는 그 숫자가 의미하는게 뭔지도 잘모르고..

그걸 가지고 뭘해야하는지도 잘 모르는 경우가 많습니다.

자... 잔소리 그만하고..... ^^;

...

메모리 주소값을 설명하는것이므로.... 정확한 주소값으로 설명하기위해...첨부한 소스를 가지고 설명하겠습니다.

(참고로 델파이7입니다. 다른 버전에서는 여기서 설명하는 메모리주소값과 다른 주소값이 나올겁니다만... 내용은 동일합니다.)

자...

소스를 열어봅시다.

Form1Create에서는 Label1.Caption 에다가 HInstance를 IntToHex로 보여주게했고...(그냥 참고하라고....)

Button1Click에서는 다음과 같이 코딩해서 액세스바이올뢔이션에러가 뜨게했습니다.



31: procedure TForm1.Button1Click(Sender: TObject);
32: var
33:   P: Pointer;
34:   i: Integer;
35:   S: String;
36: begin
37:
38:   P := Pointer( 99999999 );
39:
40:   i := Integer( P^ );
41:
42:   S := IntToStr( i );
43:
44: end;



자 컴파일해보면 Label1에는 $00400000 라고 써있고...

버튼을 클릭해보면

Access violation at address 0044EBA9 in module 'Project1.exe' read of address 05FF5E0FF

라는 에러가 뜰겁니다.

여기서 말하는 address 0044EBA9  ...

이 주소값으로 소스코드의 어느 유닛 몇번째 라인인지를 알 수 있는데....

그냥은 알수없고....

...

● 프로젝트 옵션을 엽니다. (Shift+Control+F11,  Project->Options)

● Linker 탭을 엽니다.

● Map file 을 젤 밑에꺼 Detailed를 클릭합니다.

● Build Alll

그리고나서 소스코드가 있는 폴더에 보면 Project1.map라는 파일이 만들어져 있을겁니다.

그걸 메모장으로 엽니다.

다른 건 다른 자료들 찾아서 공부해 보시고.... 여기서 설명하는건 맵파일의 젤 아랫부분입니다.

젤 아랫부분에는 다음과 같이 나와있습니다.



Line numbers for Unit1(Unit1.pas) segment .text

   27 0001:0004DB00    28 0001:0004DB18    29 0001:0004DB70    36 0001:0004DB90
   38 0001:0004DBA4    40 0001:0004DBA9    42 0001:0004DBAB    44 0001:0004DBD2
   46 0001:0004DC08    46 0001:0004DC0F

Line numbers for Project1(C:\Documents and Settings\양병규\바탕 화면\새 폴더\Project1.dpr) segment .text

    9 0001:0004DE18    10 0001:0004DE28    11 0001:0004DE34    12 0001:0004DE4C
   13 0001:0004DE58

Bound resource files

c:\program files\borland\delphi7\Lib\Buttons.res
c:\program files\borland\delphi7\Lib\ExtDlgs.res
c:\program files\borland\delphi7\Lib\Controls.res
Unit1.dfm
Project1.res
Project1.drf


Program entry point at 0001:0004DE18



이 중에서도 젤 윗 라인을 보면

Line numbers for Unit1(Unit1.pas) segment .text 라고 되어있는데...

말 그대로 소스코드의 라인들의 주소값들이 나와있습니다.

27 0001:0004DB00 이거는

27라인의 0001번째 글자부터의 소스코드가 0004DB00번지로 만들어졌다....라는 뜻입니다.

...

자... 에러가 난 주소가 얼마였져?

$0044EBA9 였군요....

이 주소 값에서 HInstance인 $00400000를 뺍니다.

그리고 PE포맷의 헤더등 불필요한 앞부분 사이즈인 $1000 도 뺍니다.

그러면

$0004DBA9 가 됩니다.

Line numbers for Unit1(Unit1.pas)에서 이 주소 $0004DBA9를 찾아봅시다.

몇라인인가요?

40 0001:0004DBA9 이라고 되어있습니다.

고로 에러가 난 부분은 Unit1의 40라인 0001번째 글자부터...입니다.

그 부분의 소스는

 i := Integer( P^ );

입니다.

XP, 2000에서 HInstance는 항상 $00400000 이고,

델파이로 만들어진 EXE의 PE헤더정보는 항상 $1000 바이트입니다. 그러므로....

에러가 난 주소는 = 에러화면에 나온 주소 - $00401000 하면 됩니다.


이렇게 찾으시면 되는데...........

map파일이 있어야하므로 프로그램을 배포하기 전에 맵파일을 만들어두셔야합니다.

혹은 안만들었어도 나중에 만들면 되는데...

단, 소스코드가 최종 컴파일됐을때의 모양 그대로 있어야겠지요....

그리고,

맵에 라인별 주소값은 컴파일 할 당시 실제로 컴파일한 유닛들만 나옵니다.

그러므로 Graphics.pas와 같이 Lib 경로에 Dcu만 있고 pas는 없는 유닛들은 포함되지 않습니다. 바꿔말하면 Graphics.pas 도 맵에 라인별 주소값을 남기려면 그 유닛도 컴파일이 되도록.. 프로젝트 경로에 같이 두던가 Lib에 Graphics.pas를 넣던가하면 됩니다.

끝.
Posted by 비와바람
IT/TMS2010. 8. 21. 09:15
procedure TfrmCreSDatHIB.sgdCreateListGetFormat(Sender: TObject; ACol: Integer;
  var AStyle: TSortStyle; var aPrefix, aSuffix: string);
begin
    AStyle  := ssAlphaCase;
end;

AStyle을 조정해 주면 된다.

형식은 다음과 같다.

  TSortStyle = (ssAutomatic, ssAlphabetic, ssNumeric, ssDate, ssAlphaNoCase,
    ssAlphaCase, ssShortDateEU, ssShortDateUS, ssCustom, ssFinancial, ssAnsiAlphaCase,
    ssAnsiAlphaNoCase, ssRaw, ssHTML, ssImages, ssCheckBox
    {$IFDEF TMSUNICODE}
    , ssUnicode
    {$ENDIF}
    {$IFDEF DELPHI7_LVL}
    , ssDateTime, ssTime
    {$ENDIF}
    , ssAlphaNumeric, ssAlphaNumericNoCase
    );
Posted by 비와바람