ATL로 프로젝트를 만드는 이유 중의 하나는 가볍다는 것이다.
그러나 가볍게 만들기 때문에 의존성이 있는 라이브러리를 포함하지 않고 빌드한다.
이로인해 배포 후 다양한 사용자 환경 때문에 환장하는 결과가 찾아오기도 한다.

예전에는 그냥 같은 디렉토리에 포함되기만 해도 되었는데 2005이후 SxS Assembly 때문에 짜증나게 바뀌었다.

이에 대한 예방법이 기본적으로 Static으로 빌드를 하는 것이다. 이것은 atl90.dll 과 manifast 파일을 포함하게 된다. 이로서 최종 빌드된 파일의 용량은 대략 25k 정도 증가한다.

사용자 삽입 이미지




허나 이것으로 해결이 된 것이 아니다.

정적 빌드로 된 것으로 배포 후 사용하려 하면 다양한 의존성 관련 에러메세지를 내뱉어내고 ActiveX DLL인 경우는 죽어도 웹에 바인딩이 되지 않는다. 아주 환장할 노릇!

해결점은 다음과 같다.

0. VS의 셋업 프로젝트를 이용한다. -_-

1. Microsoft Visual C++ 2008 재배포 가능 패키지를 포함한다. -_-

2. .Net Framework를 설치한다. -_-

3. Private Assembly를 설치하는 것이다. Install 파일을 만들때 Microsoft.VC90.CRT.manifest, msvcp90.dll, msvcr90.dll를 포함하여 사용할 DLL과 같은 디렉토리에 설치하는 것이다. regsvr32등은 해줄 필요가 없다. 허나 새로운 버전의 DLL이 나왔을 때 패치되지 않는다.

여기 까지는 그나마 행복한 InstallShield를 사용했을 때다.

4. ActiveX를 위해 만든 ATL은 cab 파일을 만들 때 저 파일들을 포함시켜줘야 한다. 그리고 inf 파일에 [Add.Code]에 넣어주고 아래도 같이 적어주면 된다.

[Add.Code]
   msvcr90.dll=msvcr90.dll
   msvcp90.dll=msvcp90.dll
   Microsoft.VC90.CRT.manifest=Microsoft.VC90.CRT.manifest

[Microsoft.VC90.CRT.manifest]
   file-win32-x86=thiscab

[msvcp90.dll]
   file-win32-x86=thiscab

[msvcr90.dll]
   file-win32-x86=thiscab

대충 이렇다.

5. 이 짓들을 모두 무마하는 설정이 있으니... 그것은 바로바로바로바로바로...
런타임 라이브러리를 다중 쓰레드 DLL에서 다중 쓰레드로 변경하는 것이다. -_)
사용자 삽입 이미지

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 까지 다시 설치하고 설치 했다. -_-

리소스 전용 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에서는 도대체 무엇을 할 수 있지하고 머뭇대는 스스로의 모습을 보고 있노라면 무언가 섬득한 느낌이 지나간다.

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

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

.Net Framework 3.0(닷넷 프레임워크 3.0)

Windows 2007. 4. 20. 18:00 posted by deneb

WPF(Windows Presentation Foundation) : WPF는 윈도우 비스타의 UI처럼 화려한 화면 구현을 가능케 한다. 3D 화면뿐만 아니라 조작성을 포함한 애플리케이션의 사용 편의성을 개선할 수 있다. WPF와 관련해 마이크로소프트 익스프레션이 발표되었다. 이 제품을 사용하면 애플리케이션의 디자인과 개발을 완전하게 분리할 수 있게 된다. 결과적으로 디자이너가 제작한 이미지를 바탕으로 인터페이스나 조작성 구현이 가능해 개발자는 기능 개발에 주력할 수 있다.

WCF(Windows Communication Foundation) : WCF는 웹을 플랫폼화하는 기술이다. 구체적으로 서비스 지향 애플리케이션을 위한, 다양한 표준화 기술을 공통으로 사용하기 위한 클래스 라이브러리인 셈이다. WCF 적용시 서비스 이용자는 다양한 플랫폼에 분산되어 있는 서비스를, 통일된 방식으로 이용할 수 있다. 서비스 제공자도 이용자의 요구에 따라 각종 프로토콜이나 접속 규격에 대응할 수 있다.

WF(WIndows Workflow Foundation) : WF는 플로우 변화에 따른 유연성을 제공한다. 개개의 프로세스(프로그램)와 논리(워크플로우)를 분리시켜 상황 대처 능력이 뛰어난 시스템 구축을 돕는다.

WCS(WIndows CardSpace) : 마지막으로 WCS는 InfoCard로 불렸던 부분으로 다양한 암호화 토큰(사용자를 판별하는 기호, 사용자 이름이나 메일 주소 등)을 통합하고 동일한 인증 방식에서 인증되도록 하기 위한 도구이다. 실생활에서 카드로 물건 값을 지불하듯 다양한 사이트에 액세스할 수 있는 환경 구현이 가능하도록 한다.

XAML : XML의 일종으로 애플리케이션의 행동 등을 기술하기 위해 사용된다. WPF에서는 익스프레션으로 디자인된 내용이 XAML로 표현되어 닷넷 언어로 기술된 프로그램과 분리해 프로그램의 변경 없이 조작 편의성을 개선할 수 있다. WCF도 XAML가 사용된다. 통일화된 프로그래밍 방법으로 다양한 통신 수단에 대응할 수 있는 한편, 프로그램 변경 없이 통신 수단의 변화에 대응할 수 있다. 이 역시 XAML가 쓰인다. 예를 들어 XAML 기술 변경으로 프로그램의 개선 없이 HTTP에서 HTTPS(SSL)로 통신 수단을 바꿀 수가 있다.

WF에서는 워크플로우 기술에 XAML를 사용한다. 프로세스는 닷넷 언어로 기술된 프로그램이나 프로세스간의 관련 부분을 표현하는 워크플로우는 XAML로 기술된다. 워크플로우에 변화가 일어나더라도 프로그램은 변경 없이 유연하게 대응할 수 있다.

WCF와 WCS는 ‘표준’이라는 공통된 키워드가 있다. 2가지 의미가 있다. 다양한 통신 방식이나 인증 방식을 통일된 방식으로 사용할 수 있도록 한다는 의미에서의(사용자) 표준화라는 측면과 백그라운드에서 사용되는 기술이나 규격은 기존의 것을 이용한다는 점이다. 이에 따라 이용자, 개발자 모두에게 이익을 가져다주는 구조 설계가 가능하다.

닷넷 프레임워크 3.0은 혁신적인 사용 편의성을 구현하는 WPF, 서비스 지향 애플리케이션을 실현하는 WCF, 워크플로우·프로세스 제어를 실현하는 WF, 그리고 WCS 제공으로 닷넷 프레임워크 2.0상에서 구축된 시스템의 유연성과 확장성, 표준화를 앞당기는데 적잖은 역할을 할 것으로 기대된다.

대상 : 노트북 ThinkPad X31(2672-LK3)

모든 것이 완벽했다.
설치에도 이상 없었고 설치후에 지겹게 깔아야하는 업데이트 들도 모두 완벽했다.
그러나 결국 VGA Driver 설치에서 좌절...
기본적인 드라이버부터 무언가 이상하게 깔렸다.
스크린샷을 남기지 못했지만 기본으로 깔리는 드라이버 부터 사용자 컴퓨터 리소스에서 AGP와 메모리 충동을 내고 있었다. 그래도 괜찮으려니 하고 레노버 홈페이지에서 드라이버를 다운받아 설치를 했다.
압축도 풀리고 시스템 폴더로 카피도 되나 마지막에
"Setup terminates and ask me to try se a Standard VGA Driver before trying to install again!"
이라는 메세지를 뱉어주면서 드라이버 설치를 반사

혹시나 하는 마음에 구글 및 윈도우 포럼들을 찾아보니 http://www.driverheaven.net 에 약간의 정보가 있는 듯 하였으나 같은 증상에 대해서는 없었다.

계속되는 삽질속에 http://www.driverheaven.net/modtool/ + 일반 배포버전 드라이버
(위 방법은 "An error occurred during the installation of the device. The System cannot find the file specified." 로 나오는 에러메세지에서 어느정도 통하는 방법이라고 하는데 해당되는 상황이 아니라 패스) 도 안되는 상황에서 gg

결국 WIndows XP SP2로 왔는데 WinFLP가 처음 나오고 2003에서 테스트로 설치 후 더욱 가벼운 느낌으로 사용하기 좋은 것 같아서 노트북의 윈도우가 험악한 환경에 자꾸 뻘짓을 하다보니 가볍게 사용하자고 시작한 것이 연휴를 빠져나올 수 없는 수렁으로 빠트려 주셨다. 덕분에 오늘 하루 멋지게 날렸다.

약간은 불안하지만 Ghost 시스템으로 가야 할 것 같다. 최근에 12도 베타테스트 하겠다. 트라이얼 이라도 아무 상관없는게 이미지 만들고 지우고 나중에 부팅 CD로 복구하면 되기에 트라이얼이 무색하다. 노트북에서 지원하는 완전복구는 Windows XP SP1 Home인 데다가 SP2를 덧씌워 주면 폭팔한다. 조만간 Ghost 12 + Boot CD를 이용한 백업/복구나 써봐야겠다.

WinFLP, nVidia의 글픽에서는 어떤지 궁금하다.

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

출처 : http://support.microsoft.com/kb/925336

Error message when you try to install a large Windows Installer package or a large Windows Installer patch package in Windows Server 2003 or in Windows XP: "Error 1718. File was rejected by digital signature policy"

SYMPTOMS

When you try to install a large Microsoft Windows Installer (.msi) package or a large Microsoft Windows Installer patch (.msp) package on a computer that is running Microsoft Windows Server 2003 or Microsoft Windows XP, you receive the following error message:
Error 1718. File FileName was rejected by digital signature policy.


CAUSE

This problem occurs when the computer has insufficient contiguous memory for Windows Server 2003 or Windows XP to verify that the .msi package or the .msp package is correctly signed.

WORKAROUND

To work around this problem, follow these steps:

1. Click Start, click Run, type control admintools, and then click OK.
2. Double-click Local Security Policy(로컬 보안 설정).
3. Click Software Restriction Policies(소프트웨어 제한 정책).
Note If no software restrictions are listed, right-click Software Restriction Policies(소프트웨어 제한 정책), and then click Create New Policy(정책 생성하기).
4. Under Object Type(개체 유형), double-click Enforcement(강요).
5. Click All users except local administrators(로컬 관리자를 제외한 모든 사용자), and then click OK.
6. Restart the computer.

Important
After you follow the previous steps, local administrators can install the .msi package or the .msp package. After the package is installed, reset the enforcement level by following the previous steps. In step 5, click All users instead of All users except local administrators.

MORE INFORMATION

Digital signatures help make sure that a package has not been tampered with. Windows Server 2003 and Windows XP use an additional level of security, Software Restriction Policies, when Windows Installer calls the SaferIdentifyLevel function.

When Windows Installer calls the SaferIdentifyLevel function together with the SAFER_CRITERIA_IMAGEHASH flag, the whole package is loaded into memory on the computer. The computer must have sufficient contiguous memory for the package size. If the computer has insufficient contiguous memory, an error occurs. Because an error occurs, Windows Installer cannot verify that the package is correctly signed. Therefore, you receive the error message that is mentioned in the "Symptoms" section.

The following log data shows the sequence of events when this problem occurs:
MSI (s) (BA:AD) [12:00:00:000]: SOFTWARE RESTRICTION POLICY: Verifying object --> 'D:\WINDOWS\Installer\50baad.msp' against software restriction policy
MSI (s) (BA:AD) [12:00:00:000]: SOFTWARE RESTRICTION POLICY: D:\WINDOWS\Installer\50baad.msp has a digital signature
MSI (s) (BA:AD) [12:00:00:000]: SOFTWARE RESTRICTION POLICY: SaferIdentifyLevel reported failure. Assuming untrusted. . . (GetLastError returned 5)
MSI (s) (BA:AD) [12:00:00:000]: The installation of D:\WINDOWS\Installer

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

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