'Program/C#'에 해당되는 글 27건

  1. 2008.04.17 Visual Studio Setup and Deployment / 비쥬얼 스튜디오 셋업 프로젝트 7
  2. 2008.04.10 EventLog
  3. 2008.04.02 네트워크 드라이브
  4. 2008.04.01 USB 및 하드웨어 인식
  5. 2008.04.01 XML Serialize
  6. 2008.03.07 Shallow Vs Deep Copy 깊은 복사
  7. 2008.03.07 컨트롤에 컨트롤 넣기 DataTemplate, FrameworkElementFactory 1
  8. 2008.03.06 CreateDirectory 사용권한
  9. 2008.03.05 클래스의 XML 문서화.
  10. 2008.02.29 차일드 컨트롤들의 열거...

Visual Studio Setup and Deployment / 비쥬얼 스튜디오 셋업 프로젝트

Program/C# 2008. 4. 17. 13:38

Visual Studio Setup and Deployment

여기저기 포스트를 뒤져보는데 셋업에 관련한 포스트는 없는 듯 하군요..
못찾는 것인지.. 
제가 사용하는 범위 내에서 셋업 프로젝트에 관해 알아보고자 합니다.
중간 중간 링크되는 URL 은 관련사항에 대한 문서입니다. 대부분이 MSDN 일텐데..
입맛에 안맞으신다거나 좀더 깊히 들어가고 싶으신분들은 참조 하시면 좋겠습니다.
혹 궁금한 사항이 있으시다면 글 남겨주시면 답변 드리겠습니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

환경 : VS 2008, .Net 2.0

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
프로젝트 생성

MSDN .Net 을 이용하여 설치 패키지를 만드는 방법
http://support.microsoft.com/kb/307353

사용자 삽입 이미지

사용자 삽입 이미지

셋업 프로젝트에서 제공되는 기능들에 대해서는 View 영역에서 확인하실 수 있습니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

프로젝트 속성
사용자 삽입 이미지
프로젝트 선택후 속성 창의 모습입니다.
[Localization] 은 기본 English 인데 , 이부분을 Korean 으로 바꿔 줍니다.
이부분을 영어로 했을경우 프로젝트내에 한글 인식이 안됩니다.
[Manufacture] 항목은 회사명으로 배포시 설치되는 경로가 됩니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
파일 포함하기
사용자 삽입 이미지
Application Folder : 응용프로그램 설치 폴더에 포함되는 파일들
User's Desktop : 바탕화면에 포함되는 파일들
User's Programs Menu : 시작 메뉴에 포함되는 파일들

[Application Folder]  항목에서 우클릭 메뉴를 확인하면, 파일을 추가 할 수가 있습니다.
이곳에 추가되는 파일들은 설치 응용프로그램 폴더에 포함됩니다.

바로가기 아이콘 만들기
http://support.microsoft.com/kb/307358/
[Application Folder] 에 포함된 파일중 바로가기 아이콘을 생성하고자 하는 실행 파일을 선택합니다.
실행파일 우클릭 메뉴를 확인하시고, 바로가기 아이콘을 생성합니다.
바로가기 아이콘은 같은 카테고리 안에 생성됩니다.
생성된 아이콘을 마우스 드래그 하여 User's Desktop, User's Programs Menu 항목에 추가 할 수 있습니다.
생성된 아이콘의 프로퍼티를 조정하여 Icon을 설정 하실 수 있습니다.
사용자 삽입 이미지
[Icon] [Browser] 클릭하여 Icon  파일을 연결합니다.

설치 경로 셋팅하기
이상태로 빌드를 한후, 설치를 해보게 되면 설치 되는 폴더의 경로가 Program Files \ Default Company로 설정될 것입니다.
이 경로에 대한 설정은 [Application Folder]의 프로퍼티에서 변경 할 수 있습니다.
사용자 삽입 이미지

DefaultLocation의 경로를 보게되면, [Manufacturer] 이라는 부분이 있는데 이부분이 회사명에 해당되는 곳입니다.
[Manufacturer]에 해당되는 곳에 회사 명을 포함하여 설치 경로를 조정할 수 있습니다.
예> [ProgramFilesfolder]MyCompany\[Productname]

여기까지의 진행만으로도 파일과 바로가기가 포함된 간단한 셋업 파일을 만들 수 있겠군요.


〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

UI Interface
사용자가 응용프로그램을 설치 할 때 보게 되는 다이얼로그의 UI에 해당하는 사항을 설정할 수 있는 부분입니다.
간단하게 메세지를 표현 할 수도 있고, CheckBox 등의 컨트롤을 추가할 수 있습니다.
http://msdn2.microsoft.com/en-us/library/ecaca8zb(VS.80).aspx
사용자 삽입 이미지

트리의 각 항목들의 프로퍼티값을 조정하여 UI를 설정할 수 있습니다. 몇가지만 살펴보면..
[Welcome] CopyrightWarning, WelcomeText 설치 시 첫 페이지에 해당 메세지 들이 표시 됩니다.
[Finished] UpdateText 설치 종료시 표시되는 메세지 입니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
CustomAction

[CustomAction]은 설치 도중 사용자에 의해 행해지는 작업을 의미 합니다.
예를 들어 응용프로그램이 실행 되기 위해서 닷넷 2.0 이 설치 되어 있어야 한다면,
개발자는 배포시에 닷넷 2.0 또한 같이 배포 되길 원할 것입니다.
CustomAction 에는 4개의 카테고리(Install, Commit, Rollback, Uninstall)가 존재합니다.
각 카테고리는 설치 단계를 의미 합니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

사용자 선택에 따른 조건부 설치 설정

http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/vsintro7/html/vxwlkwalkthroughpassingdatatocustomaction.asp

Condition 라는 속성 값을 통해서 프로그램의 배포시에 특정 파일을 포함 시키거나
혹은 특정 CustomAction 을 행하느냐 하지 않느냐를 결정 할 수 있습니다.
사용자 삽입 이미지
Filesystem 에 두개의 임의로 제작한 실행 파일을 등록 하였습니다.

사용자 삽입 이미지

[User Interface] [Start] 우클릭 메뉴에서 2개의 라디오 버튼을 포함하는 다이얼로그를 추가 합니다.
다이얼로그를 Welcome 항목 밑에 위치 시킵니다.
<참조> 모든 사용자 지정 대화 상자는 설치 폴더 대화 상자 또는 웹 설치 프로젝트의 설치 주소 대화 상자 앞에 와야 합니다.

사용자 삽입 이미지

추가된 다이얼로그의 프로퍼티 창 입니다.
두개의 라디오 버튼중 1번째 버튼은 Yes 항목  2번째 버튼은 No 항목으로 설정 하였습니다.
ButtonProperty 프로퍼티의 BUTTON2  값은 변수와 같은 개념으로 이 값을 통해 선택된 라디오 버튼을 확인합니다.
사용자 삽입 이미지

FileSystem 에서 추가한 exe 실행 파일을 Custom Actions 에서 Actions 으로 추가합니다.
추가된 실행 파일의 프로퍼티 창을 보면 Condition 항목을 확인 할 수 있습니다.
사용자 삽입 이미지

Arguments 항목을 /Install 로 설정합니다.
Conditions 항목을 BUTTON2=1 로 설정합니다. 눈치 채셨겠지만 추가된 다이얼로그의 버튼 항목입니다.
BUTTON2 항목이 1값으로 선택되었을 경우 작동 합니다.
그냥 조건문이라 생각하시면 되겠군요
InstallerClass 항목을 False 로 설정 합니다.


사용자 삽입 이미지

Yes 선택시 CustomAction.exe 가 실행되고, No를 선택시 무시 됩니다.
이처럼 사용자의 선택에 따라 Custom Action을 지정할 수 있지만, 또한 응용프로그램에 포함되는 파일을 설치시 추가 제거 할 수 있습니다.
앞전에 FileSystem 에서 추가한 Setup_Application.exe 의 Condition 항목에 BUTTON2=1 이라고 설정하였다면
No를 선택시 CustomAction.exe가 설치 되지 않을 뿐만아니라
설치가 종료되고 해당 폴더를 확인하면 Setup_Application.exe가 포함되지 않았음을 알 수 있습니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
VerSionNT

http://www.tarma.com/support/tin3/0100-using/0035-symbols/0200-variables/versionnt.htm

조건부 설치 항목에서 Condition 속성에 대해서 알아 봤습니다.
Condition 속성을 이용하면 운영체제에 따른 조건부 설치를 진행 할 수 있습니다.
예를 들어 Condition 속성에  VersionNT>=500 값을 설정 합니다.
VersionNT 는 OS 의 버젼에 따른 값으로 아래와 같습니다.
사용자 삽입 이미지

이 표를 볼때 500 이상이라는 값은 Windows 2000 이상의 버젼을 의미 하겠군요

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
.Net의 재배포, 시작조건
http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/vsintro7/html/vxwlkwalkthroughpassingdatatocustomaction.asp

배포하려는 프로그램이 .Net의 특정 버젼을 필요로 한다면 개발자는 .Net을  같이 배포 하길 원할 것입니다.
Microsoft Data Access Componets 를 이용하여 시작 조건을 검사 .Net 을 배포 할 수 있습니다.

사용자 삽입 이미지

셋업 프로젝트의 우클릭 메뉴 속성 창을 열어 보면 우측 하단에 Prerequisites 을 발견 할 수 있습니다.
이는 셋업이 진행 되기 전에 필요한 MDAC 를 추가 하는 창으로거 필요한 컴포넌트에 체크를 하시면 됩니다.

체크 박스 리스트 아래 쪽으로 컴포넌트를 다운로드 하는 방법에 대해서 지정할 수 있는데요.
웹을 통해서, 로컬 경로를 통해서 등... 3가지 경우를 선택 할 수 있습니다.

2번째에 위치한 "응용프로그램과 같은 로컬 경로"를 선택 하였습니다.

이렇게 설정하신후 빌드를 하게 되면 셋업 파일 이외에 시작조건에 필요한 컴포넌트들이 포함된 폴더가 생성이 되는군요.

사실 Vista에서 .Net 3.0 은 Windows 기능으로 포함 되어 있어.. 실행 파일 형식으로 제공되는 .Net의 설치는 할 수 없었습니다.
설치를 시도 할경우 경고 메세지를 띄우게 되죠.
빌드후 생성된 파일은 EnableDotNet 이라는 파일이군요. 이 파일은 실제적으로 닷넷을 설치 하는 것이 아니라.
플렛폼에서 닷넷을 사용할 수 있도록.. 설치가 필요하면 설치를.. 혹은 기능의 추가를.. 해주나 봅니다.
그래서!! Vista 에서 무리 없이 동작하는 군요.

현재 MDAC 는 2.1 sp1 버젼까지 업데이트 되어 있군요.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
시작조건 검사

http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/vsintro7/html/vxwlkwalkthroughpassingdatatocustomaction.asp
배포의 시작시에 특정 프로그램의 설치 여부를 확인 할 수 있다면, 이를 확인하여 프로그램을 배포할 수가 있습니다.
WMP11 을 같이 배포 해야 했기에 이에 대해서 알아 보도록 하겠습니다.
[보기][시작조건] 을 클릭 하면 시작 조건 창을 열 수 있습니다.
사용자 삽입 이미지

팝업 메뉴를 보면 파일, 레지스트리, 윈도우 인스톨러, 닷넷, 서비스 등의 시작 조건을 검사 할 수 있습니다.
레지스트리 시작조건을 추가 해보면 [Search Target Machine]  [Luanch Conditions] 에 각각 레스스트리 탐색과, 시작 조건노드가 생성 됩니다.
말그대로 레지스트리 탐색은 레지스트리내 특정 키 값을 할당하고 프로퍼티화 합니다.
생성된 컨디션은 이 프로퍼티의 값을 비교 하여 특정 작업을 시행합니다.

WMP11의 버전을 확인 하여 없을 경우 설치 하는 작업을 진행 해보면..

사용자 삽입 이미지
Root 의 vsdrrHKLM 은 HKEY_LOCAL_MACHINE 를 뜻한다.
RegKey에 검색할 키 값을 채워준다.
Value 에 레지스트리 이름을 준다.
Property 는 외부로 노출되는 변수와 같은 개념으로 특정한 이름을 명명한다.
사용자 삽입 이미지
생선된 컨디션의 Condition 에 방금 생성한 레지스트리 탐색의 프로퍼티 값을 주고 값을 비교합니다.
"11,0,5721,5145"는 필자가 넣은 값으로 WMP11의 XP버젼의 레지스트리 값입니다.
위 조건을 만족하지 않는 경우에 Message 항목을 출력하고 InstallUrl의 경로를 실행합니다.
InstallUrl에 필자는 상대 경로를 주었는데.. 위 폴더는 빌드 Release 에 포함되어 있습니다.
CD 로 배포시에 이런 방법이 유용하고, 실제로 유효한 Web 주소를 주어도 해당 웹페이지를 실행 시켜 줍니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
파일 형식

http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/vsintro7/html/vxwlkwalkthroughpassingdatatocustomaction.asp

배포 되는 실행파일에 연결되는 문서 형식을 지정하는 곳입니다.
예를 들어 .hwp 파일을 클릭하면 한글이 실행되듯이..

사용자 삽입 이미지
우측에 [FileType on Target Marchine]의 우클릭 메뉴로 파일 타입을 생성 할 수 있습니다.
좌측은 생성된 파일 타입의 프로퍼티 창입니다.
Extension 란에 확장자를 넣어 주시면 되구요, 세미콜론(;)을 이용하여 여러개를 지정할 수 있습니다.

참고 파일 형식은 설치된 실행 파일 하나에만 연결할 수 있습니다.
두 개 이상의 실행 파일을 파일 형식과 연결하려면 먼저 각 실행 파일에 대한 조건을 지정하여 지정된 설치에 대해 하나만 설치되도록 해야 합니다.

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
마치며..

제가 직접 해보면서 작성한 포스트라 순서가 순차적이지 않을 수가 있습니다. 이해를 ^^;;
레지스트리 편집기에 대해선 알아보지 않았군요. 사용하진 않았지만 특별히 어려운 사항은 없으리라 생각합니다.
포스트중 제가 잘못 알고 있거나 놓친 부분이 있다면 댓글을 남겨주시면 감사하겠습니다

'Program > C#' 카테고리의 다른 글

EventLog  (0) 2008.04.10
네트워크 드라이브  (0) 2008.04.02
USB 및 하드웨어 인식  (0) 2008.04.01
:

EventLog

Program/C# 2008. 4. 10. 11:46
프로그램의 런타임시에 어찌 돌아가는지 혹은 문제는 없는지 보통 Log 파일을 기록합니다.
무식하게 텍스트 파일에 때려 넣었었는데 아래와 같은게 있네요..
사용법은 간단합니다. 자세한 사항에 대해서는 귀찮아서 조사 안해봤네요...
MSDN 긁어왔습니다 -0-;

──────────────────────────────────────────────────

간단한 사용법

string 타입의 Source 와 LogName 이 필요합니다.

// Source 를 생성합니다.
if (!System.Diagnostics.EventLog.SourceExists("Source"))
                    System.Diagnostics.EventLog.CreateEventSource("LogName", ""Source");

// 이벤트를 기록합니다.
System.Diagnostics.EventLog.WriteEntry(LogFileName, Msg);
WriteEntry 함수는 여러 가지로 오버라이드되어 있군요.. 입맛에 맞게 사용하시면 될 것 같습니다.

──────────────────────────────────────────────────

비스타 기준  [제어판] [관리도구] [이벤트뷰어]
왼쪽 트리에 보시면 LogName 라고 확인 하실수 있을 겁니다.
사용자 삽입 이미지


──────────────────────────────────────────────────

EventLog 클래스

스레드로부터 안전한 방식

이 형식의 모든 public static(Visual Basic에서는 Shared) 멤버는 스레드로부터 안전합니다. 하지만 인스턴스 멤버는 스레드로부터 안전하지 않습니다.

설명

EventLog를 사용하면 중요한 소프트웨어 또는 하드웨어 이벤트 정보가 기록되어 있는 Windows 2000 이벤트 로그에 액세스하거나 사용자 지정할 수 있습니다. 예를 들어, EventLog를 사용하여 기존 로그를 읽고, 로그에 엔트리를 쓰고, 이벤트 소스를 만들거나 제거하고, 로그를 삭제하고, 로그 엔트리에 응답할 수 있습니다. 또한 이벤트 소스를 만들 때 새로운 로그를 만들 수도 있습니다.

CreateEventSource를 호출할 때 지정한 로그가 컴퓨터에 없으면 사용자 지정 로그가 새로 만들어지고 응용 프로그램이 해당 로그의 소스로 등록됩니다. 따라서 EventLog 클래스를 사용하면 적절한 액세스 권한이 있는 이벤트 로그에서 엔트리를 쓰거나 읽을 수 있습니다.

참고   보안 로그는 읽기 전용입니다.

이벤트 로그에 쓸 경우 Source 이벤트를 지정하거나 만들어야 합니다. Source 는 이벤트 로그에 응용 프로그램을 유효한 엔트리 소스로 등록합니다. Source를 사용하면 한 번에 하나의 로그에만 쓸 수 있습니다. Source 에는 여러 가지 문자열을 사용할 수 있지만 시스템에 있는 다른 소스와는 다른 이름을 사용해야 합니다. 대개 소스에는 응용 프로그램 이름 또는 다른 특정 문자열이 사용됩니다. 중복된 Source 값을 만들려고 하면 예외가 throw됩니다. 그러나 하나의 이벤트 로그에 여러 개의 소스를 연결할 수 있습니다.

로그를 읽으려면 EventLogLog 이름 및 MachineName (서버 컴퓨터 이름)을 지정합니다. 소스는 로그에 기록하는 경우에만 필요하기 때문에 Source를 지정할 필요가 없습니다. Entries 멤버는 자동으로 엔트리의 이벤트 로그 목록으로 채워집니다.

참고    Log/ MachineName 쌍을 지정하여 로그에 연결하는 경우 MachineName을 지정할 필요가 없습니다. MachineName을 지정하지 않으면 기본적으로 로컬 컴퓨터(".")가 지정됩니다.

이벤트 로그에 쓸 때 message 매개 변수와 함께 보낼 정보 형식을 지정할 수 있습니다. 메시지를 보내는 것 외에 메시지가 오류, 경고 또는 정보 엔트리 형식인지 여부를 나타내는 EventLogEntryType을 보낼 수 있습니다. 또한 응용 프로그램 정의 eventIdcategory 매개 변수를 지정하여 이벤트 뷰어의 형식 및 범주 열에 표시할 수 있습니다. 그리고 지정한 이벤트에 추가 정보를 연결하는 경우 이벤트 엔트리에 이진 데이터를 첨부할 수도 있습니다.

EventLog 클래스는 개별 이벤트 로그 및 해당 엔트리에 대한 액세스 뿐만 아니라 모든 이벤트 로그 컬렉션에 대한 액세스도 제공합니다. EventLog의 정적(Visual Basic에서는 Shared) 멤버를 사용하여 로그를 삭제하고, 로그 목록을 가져오고, 소스를 만들거나 삭제하고, 컴퓨터에 특정 소스가 이미 포함되어 있는지 여부를 확인할 수 있습니다.

Windows 2000에는 응용 프로그램, 시스템 및 보안의 3가지 기본 로그가 있습니다. 다른 응용 프로그램이나 Active Directory와 같은 서비스가 설치되어 있으면 이벤트 로그가 더 있을 수 있습니다. EventLog를 사용하여 서버의 이벤트 뷰어를 통해 볼 수 있는 사용자 지정 이벤트 로그를 만들 수 있습니다.

이벤트 로그에 쓰는 경우 디스크 공간, 프로세서 시간 및 기타 시스템 리소스가 사용됩니다. 따라서 필수 정보만 기록해야 합니다. 또한 성능에 좋지 않은 영향을 주지 않도록 기본 코드 경로 대신 오류 경로에 이벤트 로그 호출을 배치하는 것이 좋습니다.

EventLog 인스턴스의 초기 속성 값 목록을 보려면 EventLog 생성자를 참조하십시오.

:

네트워크 드라이브

Program/C# 2008. 4. 2. 20:10
네트워크 드라이브의 목록 정보를 가져오고, 설정하는 방법입니다.

유경상님의 닷넷 블로그로 설명이 잘되어 있네요

네트워크 드라이브 설정
http://www.simpleisbest.net/archive/2005/06/07/157.aspx

네트워크 드라이브 목록
http://www.simpleisbest.net/archive/2005/08/26/211.aspx

'Program > C#' 카테고리의 다른 글

EventLog  (0) 2008.04.10
USB 및 하드웨어 인식  (0) 2008.04.01
XML Serialize  (0) 2008.04.01
:

USB 및 하드웨어 인식

Program/C# 2008. 4. 1. 18:35

환경 : VS2008, WPF, C#

컴퓨터가 하드웨어를 인식했을때 이에 대한 이벤트를 처리하는 부분입니다.
C# 에서 API를 사용해서 구현하는 방법에 대해 알아보겠습니다.

알아야 할 것은 두가지 입니다.
하드웨어가 인식되었을대 어떠한 메세지가 오느냐?
이 메세지에 포함된 값을 어떻게 확인하느냐?

답을 먼저 말한다면
하드웨어를 인식했을 경우 WM_DEVICECHANGE 라는 메세지가 날라옵니다.
USB 의 인식 및 제거를 확인하기 위해서 아래와 같은 상수 값들이 필요합니다.

            UInt32 WM_DEVICECHANGE    = 0x0219;
            UInt32 DBT_DEVTUP_VOLUME = 0x02;
            UInt32 DBT_DEVICEARRIVAL = 0x8000;
            UInt32 DBT_DEVICEREMOVECOMPLETE = 0x8004;

UInt32는 닷넷에서 메세지 상수값에 대응하는 타입입니다.
각 값들에 대해서는 MSDN 및 구글을 검색하시면 쉽게 아실 수 있습니다.
만약 USB 가 아닌 다른 장치를 인식해야 한다면.. 그에 해당하는 상수값들을 사용하면 될 것입니다.

첫번째, 우선 메세지 프로시져를 만들어야 합니다.

protected override void WndProc(ref Message m)

닷넷에서는 WndProc 를 오버라이드 함으로서 메세지를 가로챌 수 있습니다.


두번째, 장치가 인식되었는지를 확인해야 합니다.

if (m.Msg == WM_DEVICECHANGE)

장치의 변화는 확인하였군요...


셋째, 어떠한 장치인지를 확인해야 합니다.
   int devType = Marshal.ReadInt32(m.LParam, 4);
   (devType == DBT_DEVTUP_VOLUME)

Marshal(마샬) 클래스는 언메니지드 코드에 접근할 수 있고,
기타 포인터및 C 스타일의 자료형들을 사용할 수 있도록 지원하는 클래스다라고..
알고 있습니다. 정확히 알아보진 않았고 대략 그런 용도로 사용하고 있느니까요..
이에 대해선 좀더 자세히 알아 보시길 바랍니다.
어쨌건 마샬 클래스를 통해서 LParam 값을 읽어 장치의 타입을 검색하는 군요..

넷째, 그렇다면 장치의 인식인지, 제거 인지를 판단해야 합니다.
if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL)
if (m.WParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE)

추가로, 볼륨 장치 일경우 드라이브의 형태로 잡힐텐데요. 드라이브명까지 알아본다면

DEV_BROADCAST_VOLUME 라는 구조체를 정의합니다.
LParam 에서 볼륨 정보를 가지고 있는 놈이지요.

[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
        public struct DEV_BROADCAST_VOLUME
        {
            public int dbcv_size;
            public int dbcv_devicetype;
            public int dbcv_reserved;
            public int dbcv_unitmask;
        }

TJ.TJUtil.DEV_BROADCAST_VOLUME vol;
vol = (DEV_BROADCAST_VOLUME)Marshal.PtrToStructure(m.LParam, typeof(DEV_BROADCAST_VOLUME));

vol.dbcv_unimask 값으로 드라이브 명을 얻을 수가 있는데요...
값을 바로 주진 않는군요... 아래 함수를 정의 해 봅니다.
public static char DriveMaskToLetter(int mask)
        {
            char letter;
            string drives = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            int cnt = 0;
            int pom = mask / 2;
            while (pom != 0)
            {
                pom = pom / 2;
                cnt++;
            }

            if (cnt < drives.Length)
                letter = drives[cnt];
            else
                letter = '?';

            return letter;
        }

vol.dbcv_unimask 값을 파라미터로 받아서 드라이브 명의 문자를 리턴 합니다.


'Program > C#' 카테고리의 다른 글

네트워크 드라이브  (0) 2008.04.02
XML Serialize  (0) 2008.04.01
Shallow Vs Deep Copy 깊은 복사  (0) 2008.03.07
:

XML Serialize

Program/C# 2008. 4. 1. 12:00
환경 : VS2008, WPF 프로젝트

Xml Selralize 를 사용하는데 있어서 좋은 정보를 제공하는 곳입니다.
http://www.ensimple.net/enSimple/show.aspx?cnum=68&b_id=study_csharp&page=1

http://www.topxml.com/xmlserializer/serialize_class.asp

Serialize 를 사전에서 찾아보면 "번호순으로 나열하다" 라는 군요..
데이터를 스트림의 형식으로 표현하여 읽고 쓰기를 한다는 의미 같습니다.

제가 Serialize 를 사용하게 된 계기는 XML 문서를 메모리 상에 클래스로 구조화 하기 위해서 였습니다.
그러기 위해선 우선 해당 XML 문서의 형식에 맞는 클래스가 존재 하여야 할 것입니다.

MSDN을 에서 XSD를 검색해보면 ..
XML 문서의 스키마를 생성하고 이를 클래스 화 하는 방법에 대해서 아실 수 있을 겁니다.
이렇게 생성된 클래스를 사용하는데 있어서 주의 할 점은..
기본값의 사용입니다. XML 무서의 특정 노드에 값이 없을경우 클래스는 기본 값 설정을 하여야 할 것입니다.
또한 노드 컬렉션에 값이 없을경우 이런 경우 클래스의 컬렉션은 null 값 조차 가지지 않습니다.
해당 컬렉션의 유효성을 판단하기 위해 null 비교 하였다면 바로 에러가 날 것입니다.
스키마 혹은 클래스를 조작하여 이런 경우에 대비 할수가 있습니다만,
이번 포스트의 범위가 아니므로 넘어가도록 하겠습니다.

XML 문서의 구조가 비교적 간단 하다하면 위와 다르게 직접 클래스를 생성하셔도 될것입니다.
XML 시리얼 라이져는 프로퍼티 및 public 영역에 대해 XML 문서와의 매칭을 하게 됩니다.

[XmlAttribute()]
public string book {get; set;}

이런식으로 선언하게 되면 book 이라는 에트리 뷰트가 생성되게 되는 거죠...
주목할 점은 [] 부분 입니다.
사실 대괄호 안의 값을 변경함으로서 우리는 좀 더 테크니컬할 클래스를 생성 할 수가 있습니다.
이에 대한 설명은 상단의 두번째 링크된 페이지를 참조 하시면 될 것입니다.

클래스의 이름은 노드가 되고 클래스 내에 설정된 에트리 뷰트 및 노드들은 클래스 노드의 자식노드가 됩니다.
만약 클래스가 컬렉션을 포함하고 있다 해도 같은 원리가 되는 것이지요..
사용자 삽입 이미지


읽어드리는.. 디시리얼 라이즈 하는 부분입니다.
Page 라는 클래스는 제가 정의한 클래스 입니다.
이 클래스 타입에 맞는 시리얼라이져를 생성한후,
읽어드릴 XML 문서의 경로에 해당하는 XmlTextReader 를 생성합니다.
그리고 디시리얼라이즈.. 간다하죠..

그렇다면 쓰기.. 시리얼라이즈 하는 부분에 대해서 알아볼까요..
사용자 삽입 이미지


기본 디시리얼라이즈에 역순입니다.
XmlSerializerNamespaces 라는 것은 시리얼라이즈시에 루트 노드의 네임스페이스를 셋팅하는 부분입니다.
저부분을 삭제하고 실행 해보면 기본 네임스페이스(?? 기억이..)가 들어가는 것을 보실 수 있습니다.

잦은 시리얼라이즈의 사용은 프로그램에 부하가 된다고 합니다만.. 전 아직 잘 모르겠군요..
잦은 이라는 정도가 어느 선까지를 말하는지...

이제 시리얼라이즈의 대상이 되는 클래스를 만드는 부분과 DOM 에 대한 이해만 충분하다면
XML 문서를 조작하는데 있어서는 무리 없을 것 같습니다.

이는 다음 기회에 ~
:

Shallow Vs Deep Copy 깊은 복사

Program/C# 2008. 3. 7. 15:25

C# 은 기본 적으로 얕은 복사를 기반으로 합니다.
C/C++ 의 포인터 개념처럼...
처음 C# 을 하게 되면서 의식하지 않고 놓쳤던 부분이네요..

엄밀히 말하면 구조체는 깊은 복사, 클래스는 얕은 복사를 기본으로 하죠..
C# 에서 타입은 클래스로 되어 있습니다.
그렇다면 모든 타입의 인스턴스에 대한 복사는 얕은 복사인가..
그렇지 않습니다.
실제적으로  int  를 예로 들면 깊은 복사가 행해 집니다.
이는 내부적으로 깊은 복사의 처리를 대행 하기 때문입니다.

그렇다면 우선 깊은 복사가 진행되는 타입과 얕은 복사가 진행되는 타입에 대해서 먼저 숙지 해야 할 것입니다.
MSDN ㄱㄱ 잠깐 보면 대충 감이 잡히실 겁니다.

그럼 깊은 복사를 하는 방법을 알아보도록하죠..
깊은 복사를 하는 함수를 따로 빼도 되고 IClonable 인터페이스를 상속받은후
Clone() 함수를 구현 해줘도 됩니다..

방법 1 :  MemberwiseClone()함수를 이용

ICloneable 함수를 상속 받았다 가정하면..
object Clone()
{
       return this.MemberwiseClone();
}

간단하죠? 이렇게 쉽게 끝날리가 없습니다. ㅎㅎ
MSDN 에 MemberwiseClone 함수를 검색해 보면 Shallow Copy 라고 명시하고 있습니다.
요놈은 확실히 얕은 복사 입니다.
정확히 말하면 복사하려는 클래스가 가진 필드중..
값을 가지는 필드에 대해서는 깊은 복사를 참조를 가진 필드에 대해서는 얕은 복사를..
수행하게 됩니다.
간단히 예제를 만들어서 요놈으로 깊은 복사를 시도 해보신분들은 착각하기 딱 좋죠..

방법 2 : 메모리 시리얼라이징

            MemoryStream mem = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();

            bf.Serialize(mem, obj);
            mem.Position = 0;

            object result = bf.Deserialize(mem);
            mem.Close();

이렇게 한 후 result 를 리턴 해주게 되면.. 메모리 상의 깊은 복사가 됩니다.
시리얼라이즈를 자주 사용하게 되면 시스템이 느려진다 던데..
그것 까진 잘 모르겠군요...

방법 3 : 이건 생각만 해본 바 인데...
MemberwiseClone() 를 참조 필드마다 모두 적용시킨다면..?
참조 필드가 많고 다층이라면 빡시겠군요...

'Program > C#' 카테고리의 다른 글

XML Serialize  (0) 2008.04.01
컨트롤에 컨트롤 넣기 DataTemplate, FrameworkElementFactory  (1) 2008.03.07
CreateDirectory 사용권한  (0) 2008.03.06
:

컨트롤에 컨트롤 넣기 DataTemplate, FrameworkElementFactory

Program/C# 2008. 3. 7. 12:30

리스트 뷰 칼럼에 체크 박스를 넣는 방법에 대해서 알아 보겠습니다.
자료를 찾아보면 이를 Xaml 코드로 수행하는 방법에 대해서는 쉽게 보실 수 있을 겁니다.
전 코드로 이러한 작업을 하는 방법에 대해 알아보죠..

우선 수행순서를 알아보면..(일부순서는 바뀌어도 됩니다.)
1. 컬럼의 생성
            col = new GridViewColumn();
            col.Header = "사용";


2. 데이터 템플릿 생성
            DataTemplate dt = new DataTemplate();

3. 컬럼에 데이터 템플릿 연결
            col.CellTemplate = dt;

4. 팩토리 생성
            FrameworkElementFactory Factory = new FrameworkElementFactory(typeof(CheckBox));

5. 데이터 템플릿에 연결
            dt.VisualTree = Factory;

6. 원하는 프로프티(값)을 팩토리에 바인딩
            Bind = new Binding("isuse");
            Bind.Converter = new IsUseChkConvert();
            Factory.SetBinding(CheckBox.IsCheckedProperty, Bind);
            Factory.AddHandler(CheckBox.LoadedEvent, new RoutedEventHandle(Check_Load));

프로퍼티에 값을 기록 하는 것 이외에 런타임 이벤트 또한 생성 할 수가 있습니다.
이런 식으로 해당 컨트롤에 대한 이벤트를 추가 하여도 되고
로드 이벤트만 걸어주고 로드 이벤트 핸들러 내에서 런타임 이벤트를 생성해도 됩니다.
아무래도 이 방법이 좀더 친숙하겠죠 ^^;

제가 설명한 예제는 리스트 뷰의 컬럼에 체크 박스를 넣는 내용입니다.
여기서 주목할 것은
DataTemplate, FrameworkElementFactory 클래스 입니다.
http://msdn2.microsoft.com/ko-kr/library/system.windows.frameworkelementfactory.aspx
위 링크의 내용을 보면 Xaml 이 아닌 코드로의 사용은 비추천 한다고 나오네요.
하지만 테크니컬한 조작을 하지 않는다면 큰 무리는 없어보입니다.
http://msdn2.microsoft.com/ko-kr/library/system.windows.datatemplate.aspx
위 링크는 데이터 템플릿에 대한 글입니다.
내용을 읽어 보시면 System.Windows..::.FrameworkTemplate 클래스를 상속받는군요..
팩토리는 프렘웍 템플릿을 상속받은 템플릿에는 적용이 가능하다..??

'Program > C#' 카테고리의 다른 글

Shallow Vs Deep Copy 깊은 복사  (0) 2008.03.07
CreateDirectory 사용권한  (0) 2008.03.06
클래스의 XML 문서화.  (0) 2008.03.05
:

CreateDirectory 사용권한

Program/C# 2008. 3. 6. 17:18
public FileSystemAccessRule (
	IdentityReference identity,
	FileSystemRights fileSystemRights,
	InheritanceFlags inheritanceFlags,
	PropagationFlags propagationFlags,
	AccessControlType type
)
 
또는
public FileSystemAccessRule (
	string identity,
	FileSystemRights fileSystemRights,
	InheritanceFlags inheritanceFlags,
	PropagationFlags propagationFlags,
	AccessControlType type
)
account는 사용자 식별타입입니다.
Domain 사용자라면 Domain\사용자ID
아니라면 컴퓨터명\사용자ID
등으로 사용할 수도 있습니다.
:

클래스의 XML 문서화.

Program/C# 2008. 3. 5. 10:17
XMLSerializer 를 이용하여 클래스를 XML 문서화 할 수 있다.
클래스는 직접 만들어 질 수도 있고, Xsd.exe 를 통해서 생성될 수 있다.

    XmlRootAttribute xRoot = new XmlRootAttribute();
    xRoot.ElementName = "CustomRoot";
    xRoot.Namespace = "http://www.cpandl.com";
    xRoot.IsNullable = true;
     
    XmlSerializer serializer = new XmlSerializer(typeof(OrderedItem),xRoot);
     
    OrderedItem i = new OrderedItem();
     
    TextWriter writer = new StreamWriter(filename);
    
    serializer.Serialize(writer, i);
    writer.Close();

XmlSerializer 생성자들을 살펴 보면 다양한 형태의 저장이 가능하다.
위 에제에서 xRoot를 사용한 이유는 저장될때 노드의 네임이 클래스의 네임을 그대로 인용하는데, 전 노드의 이름을 따로 주어야 했기 때문이다.

Korea MSDN 링크
http://msdn.microsoft.com/library/kor/default.asp?url=/library/KOR/cpref/html/frlrfSystemXmlSerializationXmlSerializerClassTopic.asp

'Program > C#' 카테고리의 다른 글

CreateDirectory 사용권한  (0) 2008.03.06
차일드 컨트롤들의 열거...  (0) 2008.02.29
전역 변수, Properties  (0) 2008.02.29
:

차일드 컨트롤들의 열거...

Program/C# 2008. 2. 29. 14:27
< 환경 : WPF 프로젝, VS2008 >

WPF 윈도우 내의 그리드에 네임을 붙혀주고.. 해당 그리드의 칠드런에 접근하면 된다..
아래는 다수의 콤보박스의 크기를 일정하게 해주는 작업이고...
콤보박스의 이름이 "cbPost" 인 것은 제외 시킨다.

foreach (UIElement Combo in this.PageSettingGrid.Children )
            {
                if (Combo is ComboBox)
                {
                    if ((Combo as ComboBox).Name != "cbPost")
                    {
                        (Combo as ComboBox).SelectedIndex = 0;
                       
                        (Combo as ComboBox).Width = 40;
                        (Combo as ComboBox).Height = 20;
                    }
                }
            }

'Program > C#' 카테고리의 다른 글

클래스의 XML 문서화.  (0) 2008.03.05
전역 변수, Properties  (0) 2008.02.29
Num foramt 숫자의 출력 형식  (0) 2008.02.29
: