Visual C++ 2008 Feature Pack Release 설치기

Windows 2008. 4. 8. 10:44 posted by deneb

고대하던 정식판이 나와주셨다.

beta에서 특정 버전만 깔리는 까칠함을 보여주셨는데

이번엔 그나마 영문판 이라면 패스해 주시는 관대함을 배푸셨다.

한글판은 대략 6월 넘길듯 -_-

사용자 삽입 이미지
이번엔 속지 않고 확실하게 정독했다.
대충읽었다가 하루에 세번 깐거 생각하면 -_-

사용자 삽입 이미지
설치 시작 화면

사용자 삽입 이미지
TOC 주저리주저리 라이센스 확인 선택 후 다음 클릭

사용자 삽입 이미지
잘 설치되고 있는 모습

사용자 삽입 이미지
갑자기 원본 넣어달래신다 -_- 당황하지 말고 마운트 시켜주는 센스

사용자 삽입 이미지
설치 완료 모습

듀얼코어 6550, 4GB, Server 2008 기준 20~30 사이로 걸린다.

자 프로젝트를 시작 해보자.

기본 MDI에 오피스모양에 리본 선택 해서 그냥 컴파일 한 모습

사용자 삽입 이미지

미나씨 만나러 가서 많이 봐온 모습이다.

겉모냥이 바뀐것 가지고 흥분하시면 초짜다.

Feature Pack 의 핵심은 TR1이다.

그렇다고 필자도 스마트 모인터인 shared_ptr를 사용하고 정규식 파서가 있고 해쉬 씨리즈를 막 가져다 쓸 수 있다는 것 외에는 잘 모르겠다. -_-

아직도 stl은 컨테이너 밖에 안써서 -_);;;
이거 제대로 당했다.

Server 2008로 과감히 올라가면서 개발환경을 다시 잡았다.
Visual Studio(이하 VS) 쪽은 통상적으로 하위 개발 버전을 깔아야 문제가 생기지 않는다. 개인적 경험으론 VS2k5를 깔고 VS2k3을 설치했을 경우에 아무런 문제가 없었던 적도 있기 때문에 항상 그렇다고 생각하진 않고 순서야 어떻게 되든 환경 설정만 잘 해주면 된다로 생각하고 있다. 그래도 상위를 깔고 하위를 설치하게 되면 제대로 찜찜하다. 환경 설정을 한다고해도 뭔가 이상한 느낌은 지울수 없기에 통상적인 방법을 선택하고 믿고 있는 것이 편하다.

이번에도 역시나 일반적인 방법으로 설치했다.

VS2k8을 사용하는 목적이야 많겠지만 실버라이트니 .netfx 3.5 통합환경이 하는 것 보다 VC++ 2008 Libraries Feature Pack "Beta" 를 직접 사용해 보고자 했던 마음이었다. 이것이 거의 늪으로 들어가는 화근이었다.

VS2k3 관련 설치후  한글판 Visual Studio Team System(이하 VSTS)를  깔고 Windows SDK 설치. 마지막으로 VS90-VCFeaturePack-Beta-KB945273-x86x64-ENU 설치 시도!

사용자 삽입 이미지

설치 불가 -_-

다운로드 사이트에 가서보니 http://www.microsoft.com/downloads/details.aspx?FamilyID=d466226b-8dab-445f-a7b4-448b326c48e7&DisplayLang=en

사용자 삽입 이미지
그렇다. 영문판 이어야 한다. -_-

VSTS 2k8 한글판 제거 T-T

VSTS 2008 Development Edition 2k8 설치 -_-; (이게 실수다)

다시 해당 프로그램 찾을 수 없다는 다이얼로그 T-T

VS2k3 제거, WIndow SDK 제거 -_-;

그래도 해당 프로그램 찾을 수 없다는 다이얼로그 T-T

구글링 모드 돌입
사용자 삽입 이미지
라는 글 발견!

내용은 설치 파일에서 생성하는 임시 디렉토리에 있는 msp 파일을 다른데로 옮겨서 실행해라라!

시도 해봤지만...

사용자 삽입 이미지

역시나... T-T

다른 글을 보니
사용자 삽입 이미지
이런~ 다운로드 페이지에 있는 문구를 건성으로 봤다.
네트워크 경로 설치 했으면 해당 경로를 접근 할 수 있게 하고 DVD로 설치 했다면 DVD에 해당 타이틀을 넣으라는 소리

DVD 이미지 마운트 후 시도!

그래도 해당 프로그램 찾을 수 없다는 다이얼로그 T-T

다시 구글링...
사용자 삽입 이미지
사용자 삽입 이미지
뭐라고? VSTS Development Edition 불가? VSTS Team Suite 영문판과 VS Professional Edition 영문판만 된다는 것이었다.

다시보니 너무 확연히 보인다.
사용자 삽입 이미지
그렇다... 너무 슬쩍봐서 삽질중이었던 것이다. o_o

주의하자.
현재 나와있는 VC++ 2008 Libraries Feature Pack "Beta"(파일명 : VS90-VCFeaturePack-Beta-KB945273-x86x64-ENU.exe)은 VSTS Team Suite 영문판과 VS Professional Edition 영문판 에서만 설치 가능하다.

홧김에 Windows 까지 다시 설치하고 설치 했다. -_-

NSIS에서 따옴표(double quote) 사용하기

NSIS 2008. 3. 5. 23:45 posted by deneb
원문 : http://nsis.sourceforge.net/How_can_I_use_quotes_in_a_string

따옴표 종류는 작은 따옴표(single quote) (') 와 큰 따옴표(double quote) (")로 구분되고
보통 C언어에서는 역슬래쉬(\)뒤에 오면 문자열로 간주한다.
이것을 생각하고 작성하는데 결코 NSIS 스크립트에서는 아니더라...

예제를 살펴보면

MessageBox MB_OK "I'll be happy" ; 더블로 묶고 싱글이 들어가면 문자열
MessageBox MB_OK 'And he said to me "Hi there!"' ; 싱글로 묶고 더블이 들어가면 문자열
MessageBox MB_OK `And he said to me "I'll be damned!"` ; '(1번 왼쪽의 키다)으로 묶으면 싱글, 더블 모두 문자열
MessageBox MB_OK "$\"A quote from a wise man$\" said the wise man" ; 역슬래쉬 앞에 $를 사용하며면 그 뒤의 문자를 문자열로 인식
MessageBox MB_OK "That would be $$60" ; $표시를 하려면 $$로 하면 된다.

보통 escape character, escaping string은 언어의 기본적인 처리에 있어서 아주 중요한데
UI나 다른 컴퓨터 및 서버로 문자열을 전달시 잡기 힘든 버그로 나타나기 아주 쉽기 때문이다.

언어마다 매번 찾아보고 실수를 연발하는데
역시나 기본이 중요하다는 것을 새삼 느끼게 된다.

리소스 전용 DLL 만들기

Windows 2008. 2. 15. 09:43 posted by deneb

from : http://msdn2.microsoft.com/ko-kr/library/24b2tcy0(VS.80).aspx

리소스 전용 DLL은 아이콘, 비트맵, 문자열 및 대화 상자 등의 리소스만 들어 있는 DLL입니다. 리소스 전용 DLL을 사용하면 여러 프로그램 간에 동일한 리소스 집합을 쉽게 공유할 수 있습니다. 여러 언어로 지역화된 리소스가 있는 응용 프로그램을 제공하는 것도 좋은 방법입니다(MFC 응용 프로그램의 지역화된 리소스: 위성 DLL 참조).

리소스 전용 DLL을 만들려면 새로운 Win32 DLL(비 MFC) 프로젝트를 만든 다음 이 프로젝트에 리소스를 추가합니다.

  • 새 프로젝트 대화 상자에서 Win32 프로젝트를 선택한 다음 Win32 프로젝트 마법사에서 DLL 프로젝트 형식을 지정합니다.

  • 해당 DLL에 사용할 문자열 또는 메뉴와 같은 리소스가 포함된 새 리소스 스크립트를 만든 다음 .RC 파일로 저장합니다.

  • 프로젝트 메뉴에서 기존 항목 추가를 선택한 다음 새로 만든 .rc 파일을 프로젝트에 삽입합니다.

  • /NOENTRY 링커 옵션을 지정합니다. /NOENTRY 옵션은 링커가 _main에 대한 참조를 DLL에 링크하지 않도록 하며, 리소스 전용 DLL을 만들 때 반드시 사용해야 합니다.

  • DLL을 빌드합니다.

리소스 전용 DLL을 사용하는 응용 프로그램은 LoadLibrary를 호출하여 명시적으로 DLL에 링크해야 합니다. 리소스에 액세스하려면 모든 종류의 리소스에 대해 작동하는 일반 함수인 FindResourceLoadResource를 호출하거나 다음과 같은 특정 리소스 관련 함수 중 하나를 호출해야 합니다.

  • FormatMessage

  • LoadAccelerators

  • LoadBitmap

  • LoadCursor

  • LoadIcon

  • LoadMenu

  • LoadString

응용 프로그램이 리소스 사용을 마친 경우에는 FreeLibrary를 호출해야 합니다.

: 그렇게 스크랩은 올리지 않으려 했건만...

  1. Vista 설치
  2. administrator 활성화 및 당 계정으로 로그인
  3. IIS 7 설치 
    1. [인터넷 정보 서비스]->[웹 관리 도구]->[IIS 6 관리 호환성]의 하위 아이템을 모두 체크
      정확히 뭐가 필요한건지 파악안되었음 -_-
    2. [인터넷 정보 서비스]->[World Wide Web 서비스]->[응요 프로그램 개발 기능]의 하위 아이템을 모두 체크
  4. Windows SDK를 먼저 설치 하려고 하면 Microsoft Document Explorer 2005 미설치 오류로 종료 당함
  5. 기본적인 순서인 오래된 프로그램 부터 설치하는 방법을 택함
    1. Visual Studio 2003 설치
      1. 설치시 "FrontPage Server Extensions"을 설치하라는 메시지가 출력되고 설치 안하면 저것이 깔린 원격 컴퓨터에서만 웹 응용 프로그램 및 웹 서비스를 호스팅할 수 있다는 협박을 한다. 하지만 3-1. 때문에 괜찮다.
      2. SP1 및 보안 패치 설치
      3. 실행파일을 관리자 권한으로 실행 되도록 지정
    2. Visual Studio 2005 설치 
      1. 전체 설치 
      2. SP1 설치, Vista용 VS2005 SP1 Update 설치, MSDN 업데이트
      3. Windows SDK 설치 (권장 Version : 6.1.6000.16384)
      4. VS2005 Extensions for WWF, VS2005 Extensions fot WFX(WPF & WPF/E, WCF) 설치
      5. 선택 설치 - VSTO(Visual Studio 2005 Tools for Office Second Edition), VSTASDK(Visual Studio 2005 Tools for Applications SDK)등 설치

이 글은 스프링노트에서 작성되었습니다.

최근에 들어서 마치 이리저리 치이고 있는 듯한 모습으로 언론에 비춰지고 있는 듯한 MS
워낙 안티 세력이 많은 것인지 아니면 그런 것은 신경을 전혀 안쓰는 것인지 모르겠지만
어찌보면 그들은 계속 마이페이스로 가고 있는 것이 아닌지 모르겠다.

MS에 대해서 특정 통계나 수치를 가지고 평가해본 적은 없지만 개발자이니 만큼 MSDN 릴리즈와 SDK 릴리즈에 대해서는 민감하다. 개인적으로는 이를 MS의 저 말없이 묵묵히 진행해가는 무서운 포스가 느껴진다.

최초로 Windows SDK 팩을 기억하는 것은 Windows ME가 나오고 Win32 API들을 총 집합해 발표하였다. 대용량도 아니였고 지원도 상당히 허접하여 과연 무엇을 할 수 있나에 대해서 의문점이 가지게 할 정도 였다. 그 후 꾸준한 업데이트 파일을 발표하고 OS가 새로 나올 때마다 해당하는 SDK 팩을 발표했다. 본격적으로 기억하는 것은 Windows XP를 발표하고 내놓은 SDK였다. 용량도 상당히 증가하였고 셋업파일과 풀패키지 파일로 발표하여 Visual Studio의 서비스팩과 별도의 Windows API를 사용하기 위해서 설치했었다. 1년에 한번 꼴도 안되는 업데이트로 그다지 신경을 안써도 될 정도의 시간이 요구되었다. 이런 패턴은 WIndows 2k3 R2 SDK까지 이어지다가 최근에 Vista와 Longhorn Beta3 출시 및 정식 출시 임박에 앞서서 쏟아지는 SDK를 놓고 상당히 놀라고 있다. 예전에 XP와 Windows 2k3의 출시를 앞두고 SDK를 쏟아지게 내놓은 기억은 없다.
중간에 어떤 의미를 가지는지 몰라도 Beta나 CTP(Community Tech Preview) RC에 대한 버전의 SDK까지 릴리즈해주는 것과 함께 말도 안되는 기간을 가지게 된다. 뭐... 하나를 잘 쌓아놓고 바뀐 것만 업데이트 하면 된다고 하지만 이 속도는 폭팔적이라는 것이다. MS만큼 이전의 x86 플랫폼을 버리고 어서 x64와 그 이상으로 옮겨가길 바라는 회사도 없는 것 같다. 2006년말~2007년초에는 Vista와 Office 2k7 발표가 있었다. 그리고 끝인 줄 알았다. "MS도 요즘은 라인업 하나 내놓는데 버거워 하는군~"의 느낌이었다. 하지만 알고보니 서버라인업 Longhorn Beta3 출시, .Net Fremework 3.0의 개념 정리 및 응용에 빠듯한 시기에 .Net Fremawork 3.5의 발표와 WPF/E 환경인 Silverlight나 그에 맞는 컨텐츠를 만드는 Expression 시리지의 발표, 코드네임 Orcas로 불리는 차세대 Visual Studio 시리즈의 Beta 1 발표. 이 모든 것들이 2007년 4월에 일어난 일이라면 우리는 여기저기서 쫒기고 있는 모습의 MS를 생각할 수 없고 그동안 제국을 탐내하였던 일련의 무리들(google-Linux-JAVA-Adobe(Macromedia) 등)에 대해서 더욱 견고한 모습으로 다시 위용을 떨치는 것으로 보인다. 게다가 아직도 발표할 것들이 더 많은 것으로 소식이나 블로그들을 보면 알 수 있다.

하아... orcas가 곧 출시하는 시기에 아직도 VS 6.0에서 깨작대고 VS 2005에서는 도대체 무엇을 할 수 있지하고 머뭇대는 스스로의 모습을 보고 있노라면 무언가 섬득한 느낌이 지나간다.

나는 변화를 두려워 하는 것인가...

까짓껏 쥐뿔하나 모르면서 시작한거 솔찍히 더 잃을 것도 없다.
최근에 시간이 많이 없지만 더욱 헐벗은 모습으로 이노무 뻘에서 삽들고 비벼야 할 것 같다.

Step 3) Zend_Search_Lucene

_undefined 2007. 3. 5. 16:30 posted by deneb

최종 목표 - LAMP(Linux 2.6.x, Apache 2.2.x, MySQL 5.0.x, PHP 5.1.x) 환경 + Zend_Search_Lucene

ZSL

현재 적용해야할 사이트는 php 기반의 사이트다. 이 사이트는 인덱싱화에 있어서 아무런 문제는 없지만 너치와 연계하여 사용하는 것에는 무리가 따른다. 검색하여 인덱싱에 있어서 동기화의 작업이 복잡해 지거나 아예 시간에 따른 수동화로 하거나 검색 결과를 출력하는데 있어서도 사용자-php-jsp-php-사용자 라는 구조를 가지게 되므로써 사용에 따른 효율성만 떨어지게 된다.

그렇다면 해결점은 더 빠른 언어로 만들어진 웹 검색 가능한 솔루션 이거나 아니면 아예 php로 만들어진 루씬을 만드는 것이다. 전자에 있어서는 펄, 파이선, C#, C++로 만들어진 루씬이 있지만 너치와 같은 웹검색 솔루션은 없다. 그렇다면 후자인 php로 만드는 것인데 이는 더 큰 비용이 들기 때문에 php로 만들어진 루씬을 찾아보기로 했다. 찾아본 결과가 Zend_Search_Lucene이다.
Zend_Search_Lucene는 Zend 사의 Zend Framework의 포함된 하나의 검색 인터페이스다. Zend사는 php 관련 솔루션을 공급하는 회사로 대표적으로 php4 이상에 기본적으로 들어가있는 Zend Engine이다. 이 회사에서 Zend Platform을 내놓고 기반이되는 Zend Framework를 내놓았다. 최근에 웹기반개발이 확산 되면서 스크립트 언어들이 인정을 받고 대세인 시대가 되었다. 파이썬, Ajax, 루비 종류 등 다양하게 개발된 스크립트 언어가 나왔고 하나의 축으로 자리잡게 되었다. 허나 기존 php만으로도 구현 할 수 있기에 그 방법론으로 php 기반의 플랫폼을 내놓고 있고 이런 플랫폼은 벌써 10개도 넘는 것으로 안다.

http://www.phpriot.com/d/articles/php/search/zend-search-lucene/index.html 에서 Zend_Search_Lucene을 통한 검색 및 결과를 보여줬다.

1. 설치 환경
PHP 5.1.4 이상의 환경

2. Zend Framework
홈페이지에서 ZendFramework-0.8.0 다운 및 설치
php의 include_path 지정
사용 권한 등 변경

3. 테스트
간단한 indexing 파일 생성과 검색 결과에 대한 테스트 완료

남은 과제 아직 WebDB, crawling에 대해서는 php 실력이 부족한 관계로 차후에 시도해 보려함

참고사항;
ZendFramework-0.8.0
PHPUnit
Pear

Step 2) 너치 온 루씬(Nutch on Lucene)

_undefined 2007. 3. 5. 15:23 posted by deneb

이전 단계의 문제점을 해결하기 위해서는
우선 알아야 할 것이
1. 루씬은 TEXT 파일만 인덱싱 할 수 있다.
2. 루씬은 특정 사이트에 대해서 해석후 텍스트 파일로 만들 수 없다. (crawling)
3. 루씬은 특정 사이트의 하위페이지를 알아낼 수 없다. (WebDB)
4. 루씬은 웹용 검색 서블릿을 제공하지 않는다. (Servlet)

즉, 루씬은 컴퓨터 내에 특정 디렉토리(설정에 따라 그 하위도)내에 있는 TEXT 파일을 검색하여 내에 가지고 단어를 인덱싱화 하여 DB파일로 저장하고 질의를 통해서 그 결과를 알려줄 뿐 웹에서 사용할 검색엔진은 아니라는 것이다.
그렇다면 루씬의 인덱싱 파일화는 기본으로 가지고 세 가지의 문제점을 해결 할 것을 제공하면 되는 것이다.
이런 필요성 때문에 루씬을 기반으로 나온 프로젝트 중의 하나가 너치(Nutch)다.

너치는 Apache Tomcat 기반으로 돌아가는 웹 검색 엔진이다. crawling, WebDB에 대해 돌아가고 그에 더불어 Tomcat과 연계하여 검색 Servlet 페이지를 포함한다.

1. 너치 구동
Java 1.4.x 이상
Tomcat 4.x 이상

Tomcat 6.1 설치

2. 너치 설치
즉, 루씬은 컴퓨터 내에 특정 디렉토리(설정에 따라 그 하위도)내에 있는 TEXT 파일을 검색하여 내에 가지고 단어를 인덱싱화 하여 DB파일로 저장하고 질의를 통해서 그 결과를 알려줄 뿐 웹에서 사용할 검색엔진은 아니라는 것이다.
그렇다면 루씬의 인덱싱 파일화는 기본으로 가지고 세 가지의 문제점을 해결 할 것을 제공하면 되는 것이다.
이런 필요성 때문에 루씬을 기반으로 나온 프로젝트 중의 하나가 너치(Nutch)다.

너치는 Apache Tomcat 기반으로 돌아가는 웹 검색 엔진이다. crawling, WebDB에 대해 돌아가고 그에 더불어 Tomcat과 연계하여 검색 Servlet 페이지를 포함한다.

1. 너치 구동
Java 1.4.x 이상
Tomcat 4.x 이상

Tomcat 6.1 설치

2. 너치 설치
nutch-0.8.1 설치

3. 테스트
사내 사이트를 WebDB 및 인덱싱 화 완료
192.168.0.101:8080 에서 검색 결과 완료
(현재 tomcat 문제로 closed)

3. 테스트
사내 사이트를 WebDB 및 인덱싱 화 완료
192.168.0.101:8080 에서 검색 결과 완료

4. 문제점
사이트에 대한 기본적인 WebDB화 인덱싱 화에 대해서는 문제가 없지만 가장 큰 문제는 JVM 하에서 사용할 수 있다는 것이다.

'_undefined' 카테고리의 다른 글

Step 3) Zend_Search_Lucene  (0) 2007.03.05
Step 1) 루씬 온 리눅스(Lucene on Linux)  (0) 2007.03.05
Vundo(adware/virtumundo) 조심하세요.  (4) 2007.02.23

Step 1) 루씬 온 리눅스(Lucene on Linux)

_undefined 2007. 3. 5. 12:12 posted by deneb

최종 목표 - LAMP(Linux 2.6.x, Apache 2.2.x, MySQL 5.0.x, PHP 5.1.x) 환경 + Lucene+ Nutch

淚信? 淚神?

1. 리눅스를 깔자
CENT OS 4.4 설치

2. 자바 개발 환경을 만들자
기본적으로 gcj(gcc에 포함된 jre 기능을 하는 것)가 자꾸 방해를 한다.
JDK 1.4 혹은 1.5, 그 이후 버전으로 변경 하고 gcj 등이 관련된 심볼릭 링크들을 정리
/etc/profile에 JAVA_HOME 및 jar 파일 등을 PATH, CLASSPATH 에 추가
JUnit 4.1 설치 (배포버전)
/etc/profile에 JUNIT_HOME 및 jar 파일 등을 CLASSPATH 에 추가
Ant 1.6.2 혹은 그 이후 버전 (src 빌드)
/etc/profile에 ANT_HOME 및 jar 파일 등을 CLASSPATH 에 추가
Javacc 4.0 설치 (src 빌드)
/etc/profile에 JAVACC_HOME 및 jar 파일 등을 CLASSPATH 에 추가
Lucene 2.1.0 (배포버전)
/etc/profile에 LUCENE_HOME 및 jar 파일 등을 CLASSPATH 에 추가
- src 버전으로 ant를 이용하여 빌드를 해봤으나 2.1.1-dev 버전이 생기는 탓으로 찜찜한 기분에 배포버전을 사용하기로 함

3. 테스트
test를 위한 jar 파일을 CLASSPATH에 등록하고
java org.apache.lucene.demo.IndexFiles {full-path-to-lucene}/src 등을 수행 완료
java org.apache.lucene.demo.SearchFiles 검색 완료

4. 남은 문제들
쉘에서 cl 모드로 인덱스 생성 및 질의를 통한 검색은 문제없이 되었으나 실질적인 문제는 웹을 통하여 문서에 대한 url 값을 가져오는 것이 문제였다.

'_undefined' 카테고리의 다른 글

Step 3) Zend_Search_Lucene  (0) 2007.03.05
Step 2) 너치 온 루씬(Nutch on Lucene)  (0) 2007.03.05
Vundo(adware/virtumundo) 조심하세요.  (4) 2007.02.23

0. 들어가기 전에
 Microsoft(
이하 MS)에서 Windows XP(이하 XP) SP2 발표하면서 개발자 (윈도우 서버)관리자 중심으로 세미나를 하였지만 이번에 Windows Vista(이하 비스타) 발표하면서 하는 세미나들에 비하면 횟수나 질로 보나 낮았다. 이런 아주 눈에 보이는 단순한 사실에 근거하여 말하는 것도 우습지만 MS 이번 비스타에 대해서 얼마나 많은 것을 걸고 있고 그에 대한 반대급부에 대해서 민감한지가 느껴질 정도다. 과거 MS-DOS에서 Windows 환경으로 그리고 Win16(Windows 95, 98 SE)에서 Win32(Windows XP) 환경으로 넘어 오면서 약간은 위에서 아래를 내려다 보는 시선으로 사용자들을 대한 감이 있었는데 이번 비스타에 대해서는 오히려 눈치를 보고 있다고 있다. 그런 것인가 나름대로 정리한 생각은 MS XP SP2 발표하면서 데스크탑 OS 대한 생각을 고쳐 먹었다. 또한 약간은 차례 있어왔던 인터넷 대란에 대해서 어느 정도 책임에 대해 적극적이지는 않지만 소극적인 반응의 결과로 변화를 시도하고 있다고 보고 있다. 세미나에서 강사가 한마디로 요약해서 해준 말을 인용하자면 이전의 MS 데스크탑 OS 모든 것을 열어두고 문제가 생기면 막자 주의였다. 모든 사용자들은 기본적으로 Administrators 권한으로 OS 사용하게 된다. 그렇기 때문에 발생한 문제가 모르는 사람들의 드라이버설치, 인터넷이나 메일에 의한 감염에 그대로 방치하는 것이 었다. 결과 이상한 공식이 나왔는데 'Windows 불안하다'라는 것이다. 어디선가 이야기로는 윈도우에서 블루스크린을 보게되는 현상의 대부분은 윈도우 자체 결함이 아닌 같이 사용된 드라이버의 문제라고 글을 본적이 있다. MS 대변하는 의미로 적기 보다는 만큼 많은 영역을 소화하기 위해서는 '일반적인 사용자들' 사용자 권한으로 행동을 취하게 해야 하는 것이 OS로서 책임을 지는 것이라는 것을 이제야 비스타에서 적용한다는 것이다.
 
그럼 비스타에서 바뀐 것은 무엇인가 사용자들은 비스타를 설치하는 되는 것이 없더라, 불편해서 못써먹겠네 등의 말을 하는 것일까. UAC, 보호모드, 가상화, 보안 정책 등등을 들어서 설명할 수도 있겠지만 그런 것은 이미 세미나에서 지겹도록 들었기 때문에 그냥 정리된 내용을 적기로 하였다. 그간 우리는 올바른 철학을 적용하여 설계한 OS 사용했기 보다는 어찌 보면 우리나라 IT 맞는 철학에 입각하여 만들어진 것이라고 느껴지는 OS 사용하다가 갑자기 표준이라는 것을 어느 정도 적용시킨 OS 사용하다 보니 나오는 말이라고 있다. 안전한 = 편한 이라는 공식이 적용 있는 사례는 거의 없다. 안전하다는 것은 적어도 한번이라도 불편함을 초래하고 마는 것이다. 하지만 그것으로 갑자기 불편함을 감수해라 라는 의미로 말하는 것인가? 그것은 아니라고 본다. 개발환경, 플랫폼, 워크프레임 등의 기반이 바뀐다는 것은 단지 프로그램의 버전이 올라가서 바뀌는 것을 적응하는 보다 많은 부분에서 사용자의 생각이 바뀌어야 한다는 것을 의미한다. 리눅스의 그놈을 사용하면서 윈도우는 이랬는데 하면서 차이점을 지적하여 사용 못해먹겠다는 자세보다는 이런 것이 리눅스와 윈도우의 차이점이고 이렇게 만든 이유는 무엇인가 있겠구나 하는 자세가 필요하다는 것이다. 다음으로 그에 합당한 프로그램을 만들어야 하는데 아직 그런 것들을 생산할 만큼의 충분한 시간적 여유가 없었다는 것을 의미한다. , 전체적인 환경이 숙성될 만한 시간이 부족한데 궁여지책으로 사용해야 한다는 것이다. 전압으로 예를 들면(비약이 것을 염두하자) 110V에서 어느날 갑자기 220V 바꿨다고 한다면 110V에서 사용하던 기기들은 어떻게 될까? 당연히 트랜스(변압기) 사용하여 사용하여야 한다. 하지만 언제까지 그렇게 사용하지 않는다. 신제품이 나온다면 그에 맞는 220V 나오게 되고 사람들은 슬슬 트랜스를 이용한 110V 기구 사용대신에 진짜 220V 제품을 쓰게 되고 비율은 점차 확대되는 것이다. 이처럼 현재(혹은 과거) 기술을 비스타라는 새로운 환경에 적용시켜서 해내라는 보다는 새로운 환경이 적용된 프로그램으로 옮겨가는 것을 바라는 것이 올바르다. 하지만 비스타는 Win32 무서운 갈굼을 계속 받아 사용자들에게 새로운 환경을 경험시키는데 만족할 것이고 차세대 에서 완벽하게 적용된 OS 발표되고 사용자들은 현재보다 훨씬 수월하게 다른 환경으로 옮겨갈 것이다
.

들은 세미나는 다음과 같았다
.
1. Windows Vista
에서의 ActiveX 컨트롤

 
세미나의 핵심은 윈도우의 변화 과정(XP -> XP SP2 -> XP SP2 + IE7 -> 비스타) 파악해야 하고 그에 따른 과거의 기술을 어떻게 사용할 있을까를 예를 들어서 설명하였다. 전체적으로 예시 보다는 바뀐 비스타와 XP 차이점을 요약 정리 주었고, 우리나라는 ActiveX 사용하게 되었는가에 대해서도 까칠하게 짚고 넘어갔다. 역시나 전체적인 IT 업계와 개발 트렌드를 파악하여 과거 기술을 재사용하는 것에 집착하는 보다 새로운 플랫폼을 파악해 과거 기술을 전이시킬까를 고민하자고 하였다.

2. Windows Vista
보안에 맞는 Application 개발

 
세미나의 핵심은 매니지드 코딩(Managed Coding) 하자. 앞서 세미나들과 전체적으로 곂치는 내용이었지만 핵심을 요약해 주고 강사님이 입심도 좋으셔서(이빨까기 유명함 -_-) 가장 재미있는 세미나 같았다. 그리고 현재 개발 트렌드인 전체를 배포하는 것이 아니라 환경이 배포되고 그에 맞는 콘텐트들을 배포하는 방식(예를 들면 플래시 플레이어 - 기반의 프로그램들) 택하고 윈도우도 작업을 이미 시작했으니 어서 빡시게 공부하자라는 내용이었다.

Using COM to explore the namespace

Windows 2007. 2. 8. 11:23 posted by deneb

출처 : http://netez.com/2xExplorer/shellFAQ/bas_xplore2.html

There are no two ways about it, using low-level COM to enumerate folders is quirky. Note that I didn't say "difficult", it just takes some time getting used to it. With COM you have to manage objects yourself: create the right one, ask for a specific interface for the functionality you are after, then use it and finally take care to release it. In contrast, in regular API-based programming the operating system is doing the management for you; you just call functions directly, oblivious about objects and things behind the scenes.

To enumerate a folder via COM, you need an IShellFolder pointer to the folder object you're after. We've seen a sketch of how to obtain this interface by parsing a path name in the previous section. The next step is to ask the object to enumerate itself using its EnumObjects method, which creates a new object which exposes an IEnumIDList interface. This enumerator object has the contents we are after, as a collection of local PIDLs, one for each item in the folder.

The best way to illustrate all this is with an example. Let's try to create the COM-equivalent of the EnumerateFolderFS() sample presented earlier, which read the contents of a filesystem folder given a full path to it. The following EnumerateFolder() sample produces the same results in a completely different approach.

#include <shlobj.h>

void EnumerateFolder(LPCTSTR path)
{
   HRESULT hr; // COM result, you'd better examine it in your code!
   hr = CoInitialize(NULL); // initialize COM
   // NOTE: usually COM would be initialized just once in your main()

   LPMALLOC pMalloc = NULL; // memory manager, for freeing up PIDLs
   hr = SHGetMalloc(&pMalloc);

   LPSHELLFOLDER psfDesktop = NULL; // namespace root for parsing the path
   hr = SHGetDesktopFolder(&psfDesktop);

   // IShellFolder::ParseDisplayName requires the path name in Unicode.
   OLECHAR olePath[MAX_PATH]; // wide-char version of path name
   MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, path, -1, olePath, MAX_PATH);

   // parse path for absolute PIDL, and connect to target folder
   LPITEMIDLIST pidl = NULL; // general purpose
   hr = psfDesktop->ParseDisplayName(NULL, NULL, olePath, NULL, &pidl, NULL);
   LPSHELLFOLDER psfFolder = NULL;
   hr = psfDesktop->BindToObject(pidl, NULL, IID_IShellFolder, 
                                 (void**)&psfFolder);
   psfDesktop->Release(); // no longer required
   pMalloc->Free(pidl);

   LPENUMIDLIST penumIDL = NULL; // IEnumIDList interface for reading contents
   hr = psfFolder->EnumObjects(NULL, SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, 
                               &penumIDL);
   while(1) {
      // retrieve a copy of next local item ID list
      hr = penumIDL->Next(1, &pidl, NULL);
      if(hr == NOERROR) {
         WIN32_FIND_DATA ffd; // let's cheat a bit :)
         hr = SHGetDataFromIDList(psfFolder, pidl, SHGDFIL_FINDDATA, &ffd, 
                                  sizeof(WIN32_FIND_DATA));

         cout << "Name = " << ffd.cFileName << endl;
         cout << "Type = " << ( (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
                                ? "dir\n" : "file\n" );
         cout << "Size = " << ffd.nFileSizeLow << endl;
         
         pMalloc->Free(pidl);
      }
      // the expected "error" is S_FALSE, when the list is finished
      else break;
   }

   // release all remaining interface pointers
   penumIDL->Release();
   psfFolder->Release();
   pMalloc->Release();

   CoUninitialize(); // shut down COM
}

Oh dear, that sure was hard work. 56 lines of code to do exactly the same thing EnumerateFolderFS() managed in just 23 lines — less than half. But hey, that's C++ baby, either take it or leave it and join the VB club <g>. Since this is the first real COM example I presented, I'll try to be gentle and explain it thoroughly. Many typical issues in COM programming appear in this code:

  • COM initialization. Before you use any of the COM services and objects you need to call CoInitialize. Conversely, after you're done with COM you must call CoUninitialize. Typically an application that relies heavily on COM will initialize the subsystem just once when it starts, not inside each function that utilizes COM. Still it's no harm calling CoInitialize more than once, as long as it is balanced by a CoUninitialize.
    ADVANCED. If your program is multi-threaded, then COM must be initialized in each thread that uses its services. Initializing it once in the main thread won't be enough.
  • Object management. The code sample used four distinct COM objects to read the folder contents. Using desktop's IShellFolder the path was parsed, generating a pidl to the target folder. This second object was created using desktop's BindToObject. The enumerator (third object, the one we were after all along) was created by EnumObjects. Finally the shell memory manager was created by SHGetMalloc to free the various PIDLs that were allocated for us. All COM objects are dynamically created and must be released to free up the associated memory and resources via the object's Release method, inherited from IUnknown. Note that PIDLs are not objects, only pointers to allocated memory. That's why they are Free'd and not Release'd, something that took me some time to realise in the early dayz.
  • UNICODE strings. In case you haven't heard about them, UNICODE strings have wide characters, i.e. 2-bytes each. Apparently the orientals are responsible for this major upset <g>. COM has adopted the UNICODE system whole-heartedly, and most system (and shell) objects expect strings to be wide. The problem is that windows 95/98 (dunno about Me) work with multibyte strings, which are basically regular single-byte strings, despite what their name suggests. If you want your proggy to work in all windows platforms then you'd have to stick with single-byte strings and do manual conversions whenever a wide string is required. That is exactly what MultiByteToWideChar function does above. If you use MFC, you can take advantage the CString class, which simplifies string management and conversions. The drawback is the performance penalty involved for all these conversions; unfortunately there's no way around it, except if you are willing to distribute separate ANSI and UNICODE versions of your programs.
  • Enumerators. These fancy-name objects are frequent denizens of the COM landscape. Any VB people in the audience will be familiar with the term collections. Enumerators are simple objects that hold collections of similar items. The internal organization is transparent; enumerators expose an IEnumxxx interface, as IEnumIDList. Once initialized, items can be accessed sequentially by calling the Next method repeatedly, until some error indicates that the list is exhausted. Personally I feel it's a grand omission that all those objects don't have a method like Count to give the total number of elements in the list. An important detail is that enumerators usually return duplicates of their listed items which you are responsible to cleanup. In the code sample above note that each pidl is Free'd after use.

You can now appreciate why people say that COM is a technology with a steep learning curve. One has to be familiar with dozens of details before even the simplest "Hello COM" program can be build. And you'd better hurry in that climbing while learning, because mikro$oft have already prepared the COM+ mountain for you to climb next, slippery slopes an'all. Will this torment ever end? <g>

Of course, these issues are all for starters. The main dish is learning about all the COM objects supplied by the framework, finding out what they can do for you, and how to work with them, what interfaces they support, etc. The online documentation is guaranteed to be the most complete and up-to-date source of reference information. As they say, if you don't like reading, probably software development is not your ideal vocation. What you read in that good book published in 1998 may already be obsolete, plus there will be dozens of new objects introduced since then.

ADVANCED: Fending for your address space
You may have noticed in the sample code the abundance of NULL arguments to interface methods, most of the time implying a default action. Although this is easy to do, there's a possible risk here, if the NULL is a pointer meant to receive some result from the method. Take for example pdwAttributes parameter of ParseDisplayName. The docs state clearly that by passing NULL you specify that are not interested to receive any attributes at this time. In an ideal world you would be safe, but in this world there are many cowboys out there developing shell and namespace extensions, who wouldn't think twice before attempting to write on a NULL pointer without doing the proper checks first. Since that offending amateur object runs in the same address space as your app, it will drag you down in its demise. The workaround is to provide dummy variables for all such potential trouble-makers; for our example this would mean defining a "DWORD dummyAttrs = 0;" and passing it on to ParseDisplayName, even if you don't have any intention of using it in the end.

Ok, but what about that namespace exploring?

Sorry folks, I got a bit carried away there. So, let's get back to the subject, folder contents enumeration. The EnumerateFolder() sample will produce almost the same results as a the filesystem version EnumerateFolderFS(). Even the order of the items is the same, which hints that EnumObjects down deep must be using FindFirstFile et al for doing the actual folder reading. But almost the same implies there are some differences:

  • We no longer read the '.' and '..' pseudo-items. That's progress since I consider these two plain nuisances. <g>
  • We don't get automatic filename filtering; the best we can do is specify whether we want files, folders or both, via the SHCONTF_FOLDERS and SHCONTF_NONFOLDERS flags that EnumObjects understands.

The most important difference however, is the file date/time information. SHGetDataFromIDList doesn't fill in the file details in WIN32_FIND_DATA as thoroughly as an equivalent FindFirstFile would. Only the modification date is filled in, and even that is rounded to the nearest even second. That's the reason why I mentioned that you need both COM and traditional API to obtain complete information for filesystem folders.

ADVANCED: Stale PIDLs
SHGetDataFromIDList gets all the file data directly from the PIDL, without accessing the disc at all. Microsoft's implementation of filesystem PIDLs stores quite a large amount of data in each SHITEMID (cf. my earlier suggestion), except for those unfortunate creation etc dates of course. This is an advantage since the cached information can be accessed quickly, but it has to be interpreted carefully. A PIDL you obtained yesterday won't necessarily contain accurate information, if for example the file was modified in the meantime. Still, even a stale PIDL is good enough to uniquely identify a file. To convince yourselves, take two PIDLs to the same file, obtained at different times, and see what CompareIDs will return.


Shell을 이용하여 디렉토리 정보등을 알아 올 때 알아야 할 것들을 알차게 설명해 놓았다.

How To Convert a File Path to an ITEMIDLIST

Windows 2007. 2. 6. 23:30 posted by deneb

How To Convert a File Path to an ITEMIDLIST

Article ID : 132750
Last Review : July 11, 2005
Revision : 1.3
This article was previously published under Q132750

SUMMARY

When developing an application that interacts with the Windows Explorer shell, you may need to convert an arbitrary path to a file to an ITEMIDLIST. You can do this using the IShellFolder::ParseDisplayName API.

MORE INFORMATION

Following is an example of how to use the IShellFolder interface to convert the path to the file Readme.txt in the current directory to an ITEMIDLIST. The example is written in C. If the program is written using Visual C++, accessing member functions through the lpVtbl variable is unnecessary.
   LPITEMIDLIST  pidl;
   LPSHELLFOLDER pDesktopFolder;
   char          szPath[MAX_PATH];
   OLECHAR       olePath[MAX_PATH];
   ULONG         chEaten;
   ULONG         dwAttributes;
   HRESULT       hr;

   // 
   // Get the path to the file we need to convert.
   // 
   GetCurrentDirectory(MAX_PATH, szPath);
   lstrcat(szPath, "\\readme.txt");

   // 
   // Get a pointer to the Desktop's IShellFolder interface.
   // 
   if (SUCCEEDED(SHGetDesktopFolder(&pDesktopFolder)))
   {
       // 
       // IShellFolder::ParseDisplayName requires the file name be in
       // Unicode.
       // 
       MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPath, -1,
                           olePath, MAX_PATH);

       // 
       // Convert the path to an ITEMIDLIST.
       // 
       hr = pDesktopFolder->lpVtbl->ParseDisplayName(pDesktopFolder,
                                                     NULL,
                                                     NULL,
                                                     olePath,
                                                     &chEaten,
                                                     &pidl,
                                                     &dwAttributes);
       if (FAILED(hr))
       {
           // Handle error.
       }

       // 
       // pidl now contains a pointer to an ITEMIDLIST for .\readme.txt.
       // This ITEMIDLIST needs to be freed using the IMalloc allocator
       // returned from SHGetMalloc().
       // 

       //release the desktop folder object
         pDesktopFolder->lpVtbl->Release();
   }
				

APPLIES TO
Microsoft Platform Software Development Kit-January 2000 Edition

ITEMIDLIST management library

Windows 2007. 2. 6. 23:18 posted by deneb
출처 : http://www.codeproject.com/shell/pxshlapi.asp

This library simplifies management of Windows Shell ITEMIDLISTs (further PIDLs). For me, it always has been trouble to keep track of all allocated PIDLs and to free them in time. So, I wrote this library.

As time goes, the library has became rather messy (it's because I put there all PIDL-related functions that may be reusable). But it still helps me a lot.

The core of this library is CPidl class. All other functions exported here are mostly supplemental.

Constructors

CPidl::CPidl()
Constructs empty CPidl instance
CPidl::CPidl(LPITEMIDLIST other)
Constructs CPidl instance and attaches (not copies) ITEMIDLIST allocated somewhere else. At destruction time attached ITEMIDLIST will be deallocated.
CPidl::CPidl(const CPidl& other)
Copy constructor. Copies one instance of CPidl into another.
CPidl::CPidl(LPCTSTR pszPath)
Constructs CPidl instance from file or folder path. In case of error, the PIDL will be empty. It uses IShellFolder::ParseDisplayName() for getting PIDL.
CPidl::CPidl(int nSpecialFolder)
Constructs CPidl instance from special folder ID. (See CSIDL_XXX constants in MSDN).

Member functions

LPITEMIDLIST CPidl::Detach()
Detaches contained PIDL from wrapper
LPITEMIDLIST CPidl::Copy()
returns a copy of contained PIDL
void CPidl::Free()
frees contained PIDL. This member function is called automatically at destruction time.
CPidl::operator bool()
conversion operator for using in boolean expressions. Will return true if contained PIDL is not NULL
CPidl::operator LPITEMIDLIST()
Useful conversion operator that allows to use CPidlas a function argument in place of LPITEMIDLIST
CPidl::operator LPITEMIDLIST*()
CPidl::operator LPCITEMIDLIST*()
Useful conversion operator that allows to use CPidl as a function argument in place of LPITEMIDLIST*. Usually the pointer to LPITEMIDLIST is used to receive when a PIDL from function. Make sure you call CPidl::Free() before using CPidl instance for receiving PIDLs!
CPidl& CPidl::operator=(LPITEMIDLIST other)
CPidl& CPidl::operator=(const CPidl& other)
Assignment operators

Global functions

IShellFolderPtr& GetDesktopFolder()
returns a reference to static instance of IShellFolder interface for root namespace folder.
IMallocPtr& GetMalloc()
returns a reference to static instance of IMalloc interface. This interface is essential for working with PIDLs.
int GetItemIDSize(LPCITEMIDLIST pidl)
returns PIDL size in bytes.
int GetItemIDCount(LPCITEMIDLIST pidl)
returns number of elements in PIDL. If you don't know what does it mean, reread "Working with Item ID Lists" article in MSDN.
LPBYTE GetItemIDPos(LPCITEMIDLIST pidl, int nPos)
gets pointer to nPos'th element in PIDL or NULL if nPos exceeds number of elements in PIDL.
LPITEMIDLIST CopyItemID(LPCITEMIDLIST pidl, int cb=-1)
makes a copy of PIDL. cb specifies number of bytes to copy. If it's equal -1, entire PIDL will be copied.
LPITEMIDLIST MergeItemID(LPCITEMIDLIST pidl,...)
Merges two or more PIDLs (usually relative ones) into absolute (or fully-qualified) PIDL. The programmer should know what he's doing when he calls this function :-). Typical usage is to make fully-qualified PIDL from folder PIDL and PIDL returned by IShellFolder::EnumObjects()
int CompareItemID(LPCITEMIDLIST pidl1,LPCITEMIDLIST pidl2)
int CompareItemID(LPCITEMIDLIST pidl1,int nSpecialFolder)
int CompareItemID(int nSpecialFolder,LPCITEMIDLIST pidl2)
Compares two PIDLs. Returns 0 if equal and -1 otherwise.
LPITEMIDLIST GetItemIDFromPath(LPCTSTR pszPath)
returns PIDL for file or folder name. Or NULL if error
HRESULT SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, VOID **ppv, LPCITEMIDLIST *ppidlLast)
Closely resembles standard shell function SHBindToParent(). It was neccessary to write it becuase it's not available on Windows 95/NT. Refer to MSDN for arguments description.
BOOL TrackItemIDContextMenu(LPCITEMIDLIST pidlShellItem, UINT nFlags, LPPOINT ptPoint, HWND hWnd)
BOOL TrackItemIDContextMenu(LPCTSTR pszShellItemPath, UINT nFlags, LPPOINT ptPoint, HWND hWnd)
This function builds, shows and tracks shell context menu for PIDL or or file/folder path. It returns TRUE if user clicked on some context menu item. In case of error or if user didn't choose anything from menu it returns FALSE.
  • LPCITEMIDLIST pidlShellItem, LPCTSTR pszShellItemPath: a PIDL or path name of the shell item to show context menu for.
  • UINT nFlags: a set of TPM_XXX flags. See function TrackPopupMenu() for description
  • LPPOINT ptPoint: a point in screen coordinates where menu should appear.
  • HWND hWnd: a handle to the window - owner of the menu. It cannot be NULL

쉘을 다루는데 있어서 애로사항이 꽃피는 경우가 파다한데 그나마 쉽게 접근 할 수 있는 클래스