• 카테고리
    • 전체 글

    • 카테고리1
    • 카테고리2
    • 카테고리3
    • 카테고리4
  • 태그
  • 방명록

'기술자료'에 해당되는 글 351건

  • 2007.01.30 XPath의 마술 - 1
  • 2007.01.08 빌드 이벤트 9009가 발생하는 경우
  • 2007.01.08 MOSS 2007을 Administrators 이외의 계정을 관리자로 부여할 때.
  • 2006.12.26 C#에서 ListBox의 DataSource 속성 활용하기. 1
  • 2006.11.30 The COM Elevation Moniker
  • 2006.10.09 RAM, Virtual Memory, Pagefile and all that stuff - 요약본
  • 2006.10.02 처음하는 프로그래밍 [1] - 머릿말
  • 2006.09.25 SMS 2003에서 SQL 2005를 지원하는가?

XPath의 마술 - 1

기술자료/Web 2007. 1. 30. 23:09
XML을 이용한 기술 중에 데이터 검색을 위한 기능을 모아 둔 것이 바로 XPath이다.
전에 코리에서 근무할 때는 이 Xml 부분에 대한 대부분은 당시 석사 과정이던
김주원씨에게 전부 맡기다 시피 해서, 내가 필요로 하는 데이터를 가져오는 방법만
이야기하고 결과는 항상 Parser를 만들어 뽑아냈다.

지금 C#을 하는데, 여기서 껄덕하면 나오는 것이 Xml 데이터 형이고,
이를 이용해서 하는 작업의 난이도도 슬슬 높아지고 있다.

이때, 각종 데이터 검색 및 조작을 위해 XPath에 대해서 하나씩 실험을 해보았고,
그 중 꼭 기억했으면 하는 것들을 나열해 보도록 하겠다.

1. 같은 내용을 제외하고 얻을 수 있는 방법
< A >
  < B  aa = '4' / >
  < B  aa = '4' / >
  < B  aa = '5' / >
< /A >

위와 같은 Xml이 있을 때, B라는 데이터를 뽑고 싶은데 그 중 aa 값이 겹치는 것은 제외하고 싶을 때다. 이 때 사용하는 XPath 식은 다음과 같다.

  "A/B[ not ( @aa = preceding-sibling::A/B@aa) ]"

즉 여기서의 핵심은 preceding-silbiling 이라는 문구 인데, 이 문구를 앞에 두면,
:: 뒤에 있는 모든 노드들을 꺼내오게 된다. 이 값을 @aa와 비교하는데, 그 중
같은 값들을 제외하는 값이라는 의미이다.

2. 찾고자 하는 노드의 값만 알 때.
< A >
  < B > 111 < /B >
  < B > 222 < /B >
  < B > 333 < /B >
<A >

만일 위와 같은 Xml 이 있을 때 B 노드안의 값이 222 인 B 노드만을 가져오고 싶을 때 쓰는 XPath 식은 다음과 같다.

 "A/B[. = '222']"

.  이라는 기호를 이용하여 현재 값을 기준으로 가져오게 된다. 만일 아래와 같은 XPath를 쓰게 되면 전혀 다른 결과를 가져오게 된다.

"A/[B = '222']"

위와 같이 하게 되면 B라는 노드 대신 A라는 노드를 가져오게 된다.


 
728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

빌드 이벤트 9009가 발생하는 경우

기술자료/OS 2007. 1. 8. 09:56

이 팁은 Visual Studio 2005에 관한 팁입니다.

문제 유형
C#을 이용해 독립적인 클래스를 하나의 DLL로 만들어 GAC에 등록하는 경우가 종종있습니다.특히 서버용 구성요소를 만들다 보면 자주 이런 식으로 구현하게 되는데,이 경우 자동으로 Gac에 등록되게 할 수 있도록 프로젝틔 속성 내에 있는 빌드 이벤트를 이용하곤 합니다.
빌드 이벤트 내에 아래와 같은 형태로 넣을 수 있습니다.


빌드 전 이벤트 명령줄(R)
gacutil.exe /u $(ProjectName)

빌드 후 이벤트 명령줄(O)
gacutil.exe /i $(TargetFileName)


해당 항목에 위의 굵은 줄 부분을 넣게 되면, 자동적으로 빌드 하기 전에 GAC에
등록되어 있는 어셈블리를 해제 했다가, 빌드가 완료된 후 다시 GAC 상에 등록 해주게 됩니다. 일반적으로 간단한 DLL에서는 위와 같이 작업하게되면 큰 문제없이 컴파일 되며
정상적으로 동작합니다.

그러나 팀 작업이나 기타 다른 이가 작성한 프로젝트를 가져와 작업하는 경우
위의 설정에서 오류가 발생할 수 있습니다.
저 같은 경우에는 아래와 같은 오류 메시지가 뜹니다.(XXX.XXXX.XXXXX는 어셈블리
이름입니다.)

오류    1   "gacutil.exe /u XXX.XXXX.XXXXXX"
명령이 9009 코드에서 끝났습니다.

문제 원인 분석
오류에서 나타내고 있는 9009 코드라는 것에 대한 정확한 의미를 찾을 수 없습니다.
일단 각종 포럼에서 제시한 문건들을 보면 Gacutil.exe 뿐만 아니라, 다양한 명령줄
실행 중에 발생한다는 것을 쉽게 발견하실 수 있습니다. 그래서 여기서는 Gacutil.exe
만을 가지고 판단하도록 하겠습니다
제가 gacutil.exe를 버전 별로 실행해본 결과,
위와 같은 오류가 발생되는 원인이 1.1.4X 버전의 .NET Framework 내에
있는 Gacutil.exe가 불려져서 발생되는 경우가 가장 많습니다.(최소한 저와 같은
환경에서는 그렇습니다.) 왜 그런지는 알 수 없지만 VS 2005의 빌드 이벤트 명령줄은
Gacutil.exe를 2.0 용이 아닌 1.0 버전용을 먼저 호출 되고 있다고 판단됩니다.

해결 방법
1. 전체 경로로 바꾸어 처리하기.
이 경우 외국 사이트 등을 방문하여 해당 문건에 대해 처리하는 방법에 대한 각종
질의 답변 글을 보면 다음과 같은 방법으로 해결하라고 적혀 있습니다.

gacutil.exe /u $(ProjectName)
->
"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe"
/u $(ProjectName)

즉 실행하려면 파일에 대한 전체 경로와 파일명을 넣어주고 처리해주면 된다는
것입니다.실제로 저 같은 경우에도 프로젝트의 속성에 들어가 빌드 이벤트 항목의 두 문장을
위와 같이 수정했으며 정상적으로 컴파일 되는 것을 확인했습니다.

2. 검색 경로에 포함시키기.
그러나 프로젝트 파일에 대한 수정권한이 없는 경우가 있습니다. 특히 팀 프로젝트를
하게 되는 경우 이 프로젝트 파일을 수정할 수 없습니다. 수정하지 않고 위의 방법을 적용하는 마땅한 방법이 없습니다.
그러나 %PATH% 경로의 내용에 위의 BIN 폴더의 경로를 넣으면 해결됩니다.
방법은 아래와 같습니다.

- 내 컴퓨터 -> 속성 -> 고급 -> 환경 변수에 들어가 각종 환경
변수 설정 창을 띄웁니다.
- 시스템 변수 쪽에서 Path 라는 항목을 더블 클릭해서 편집 창을 띄웁니다.
- 각종 경로들 중 windows 시스템 폴더들을 가르키는 부분 뒤쪽에 넣습니다.
   (위치는 크게 관계 없지만, 가급적 앞쪽으로 배치하는 것이 좋습니다.
     저 같은 경우 %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;
뒤에 놓았습니다. )  

- Visual Studio 2005를 다시 시작합니다.

경로를 변경해 본 결과 큰 문제없이 컴파일이 되며 정상적으로 gacutil.exe가
실행된 것을 확인할 수 있었습니다.

마무리
해결방법이라고 두가지를 제시해 드렸지만, 소 뒷걸음 치다 쥐잡은 것과 같은
결과 입니다. 일단 컴파일 중 오류로 나타낸 코드 9009 의 정체는 아직 찾지 못했읍니다
왜 갑자기 v1.0용 Gacutil.exe를 실행하는 것인지는 모르겠지만,
아마 다른 서버 제품이 설치되어 있어 발생되는 것인지도 모르겠습니다.
(현재 제 개발용 PC내에는 SQL 2005와 SPS 2007이 설치되어 있습니다.)
나중에 더 많은 내용을 알게 되면 추가해서 적어보도록 하겠습니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

MOSS 2007을 Administrators 이외의 계정을 관리자로 부여할 때.

기술자료/OS 2007. 1. 8. 09:54

MOSS 2007을 설치 할 때 Administrators가 아닌 사용자로 등록 설치를 하는 경우
이벤트 로그 상에 문제가 발생한다.

이 이벤트 로그 상에 남은 내용을 분석하면 특정 컴포넌트의 CLSID를 볼 수 있다.
<CODE>
The application-specific permission settings do not grant Local Activation permission for the COM Server application with CLSID
{61738644-F196-11D0-9953-00C04FD919C1}
to the user NAOKO\spsadmin SID (S-1-5-21-3407409610-886466911-3668891564-1015).  This security permission can be modified using the Component Services administrative tool.
</CODE>
이 컴포넌트를 regedit를 이용해서 찾으면 다음과 같은 위치에서 발견 될 것이다.
이름을 확인해 본 결과 IIS WAMREG admin Service 이다.
이 서비스 내에 작업을 하는 중 spsadmin(이것이 User 권한만을 가진 MOSS 2007 관리자다.)가 이 컴포넌트에 대해 Local Activation 권한이 없어 실행되지 않았다고 한다.

이에 대한 권한 설정은 Component Service를 실행한 뒤 다음 위치에서 찾아보면 찾을 수 있다.
이 컴포넌트의 속성에 들어가서 속성 창에서 보안 부분을 열도록 한다.

Edit 버튼에 들어가서 해당 사용자를 추가 한뒤 Local Lauch와 Local Activation에 대해 권한을 허용해 준다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

C#에서 ListBox의 DataSource 속성 활용하기.

기술자료/CPP 2006. 12. 26. 20:34

C#에 있는 WinForm을 이용하여 ListBox 상에 데이터를 추가할 때 여러가지 방법이 있지만
나름대로 상당히 좋은 방법이 있어 여기에 기록합니다.

ListBox 상에 데이터를 넣는 방법은 보통 ListBox 객체 내에 있는 items를 이용하여
추가/삭제를 시도하게 됩니다. 하지만, 만일 ListBox 내에 표시되는 내용과 실제 사용하게
될 데이터가 틀린 경우에는 조금 다른 문제가 발생합니다.

여기서는 두가지 방법을 제시하려 합니다.
첫번째 방법은 가장 일반적인 방법으로 ListBox.items 라는 콜렉션 내에 추가하는 방법입니다.
가장 직관적이고 빠르게 처리할 수 있는 방법이죠.
두번째 방법은 DataSource 속성을 이용해 별도 데이터를 담은 콜렉션을 만들어 이 ListBox와 연결해주는 방법입니다.


1. ListBox.items 를 이용하는 방법


ListBox.items 콜렉션을 이용하는 방법은 보통 다양한 초보 서적에서 보기 쉬운 방법입니다. ListBox.items 콜렉션을 보시면 Object 객체의 콜렉션으로 나타내게 되는데, 여기에는 다양한 형이 들어갈 수 있습니다. 사실 Object를 상속 받은 모든 형태의 객체가 들어가므로 int 든 string 이든 거의 대부분의 값이 들어가게 됩니다.
그런데, 사실 찬찬히 이 items에 담긴 내용이 리스트 컨트롤에 출력될 때는 item[n].ToString() 을 해서 얻는 문자열로 나타낸다는 것입니다. 이를 이용하면 실제 출력될 문자열과 다양한 데이터를 담은 강력 리스트 박스를 얻을 수 있습니다.
다음 코드 내용이 바로 이 기능을 이용한 방법입니다.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace ConsoleApplication1
{
  class Program
  {
      
       static void Main(string[] args)
       {
           Application.EnableVisualStyles();
           Application.SetCompatibleTextRenderingDefault(false);
           Application.Run(new MainForm());
          
       }
  }

  class DataType1 : Object // 데이터와 텍스트를 모두 들고 있는 객체입니다.
  {
       private string _name;
       private System.Drawing.Point _point;

       public string Name
       {
           get { return _name; }
           set { _name = Name; }
       }

       public Point Pos
       {
           get { return _point; }
           set { _point = Pos; }
       }

       public DataType1(string name, System.Drawing.Point pos)
       {
           _name = name;
           _point = pos;
       }

       public override string ToString() // 실제 리스트 박스에 출력되는 문자열이 만들어지는 부분입니다.
      {
           StringBuilder sb = new StringBuilder();
           sb.Append(_name);
           sb.Append(" [ ");
           sb.Append(_point.X.ToString());
           sb.Append(",");
           sb.Append(_point.Y.ToString());
           sb.Append(" ]");
           return sb.ToString();
       }

  }

  class MainForm : Form
  {
       ListBox listTest;

       public MainForm()
       {
           listTest = new ListBox();
           this.listTest.FormattingEnabled = true;
           this.listTest.Location = new System.Drawing.Point(5, 5);
           this.listTest.Name = "TestListBox";
           this.listTest.Size = new System.Drawing.Size(300, 400);
           this.listTest.TabIndex = 1;
           this.Load += new System.EventHandler(this.OnLoad);
       }

       private void OnLoad(object sender, EventArgs e)
       {
           this.Controls.Add(listTest);

           listTest.Items.Add(new DataType1("항목1",new Point(1,1)));
           listTest.Items.Add(new DataType1("항목2",new Point(5,6)));
           listTest.Items.Add(new DataType1("항목3",new Point(2,1)));
       }

  }
}


2. DataSource를 이용한 방법

자 이젠 DataSource를 이용한 방법입니다.
DataSource를 이용하려면 몇가지 준비사항이 있는데, 앞의 방법에서는 ListBox.items에
직접 데이터를 넣어 처리했다면, 이번에는 데이터를 별도로 저장할 자료구조 인스턴스
를 만드는 것입니다. 원래는 DB와 같은 데이터 원본을 갖추는 형태를 잘 활용할 수 있도록
제공된 기능이지만, 이런 부분에서 더 큰 장점이 될 수 있으리라 생각됩니다.

먼저 List<T> 라는 제네릭으로 객체를 만듦니다. 이 안에 리스트 박스에 넣을 데이터
원본을 기록하고, 이 원본을 리스트 박스와 바인드(연결) 하게 되는 것이죠.

그럼 그 방법을 소스로 표현하면 다음과 같습니다.

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;_

namespace ConsoleApplication1
{
  class Program
  {
      
       static void Main(string[] args)
       {
           Application.EnableVisualStyles();
           Application.SetCompatibleTextRenderingDefault(false);
           Application.Run(new MainForm());
          
       }
  }

  class DataType1 : Object
  {
       private string _name;
       private System.Drawing.Point _point;
       public string Name
       {
           // 이전 소스의 ToString()의 내용이 여기를 통해 처리하게 됩니다.
           get
           {
               StringBuilder sb = new StringBuilder();
               sb.Append(_name);
               sb.Append(" [ ");
               sb.Append(_point.X.ToString());
               sb.Append(",");
               sb.Append(_point.Y.ToString());
               sb.Append(" ]");
               return sb.ToString();
           }
           set { _name = Name; }
       }
       public Point Pos
       {
           get { return _point; }
           set { _point = Pos; }
       }
       public DataType1(string name, System.Drawing.Point pos)
       {
           _name = name;
           _point = pos;
       }
       // 이제 이 부분은 더이상 쓰이지 않습니다.
       //public override string ToString()
       //{
       //    StringBuilder sb = new StringBuilder();
       //    sb.Append(_name);
       //    sb.Append(" [ ");
       //    sb.Append(_point.X.ToString());
       //    sb.Append(",");
       //    sb.Append(_point.Y.ToString());
       //    sb.Append(" ]");
       //    return sb.ToString();
       //}
  }
  class MainForm : Form
  {
       ListBox listTest;
       List<DataType1> listDataSource;
       public MainForm()
       {
           listTest = new ListBox();
           listDataSource = new List<DataType1>(); // 데이터 소스 개체 생성
          
           this.listTest.FormattingEnabled = true;
           this.listTest.Location = new System.Drawing.Point(5, 5);
           this.listTest.Name = "TestListBox";
           this.listTest.Size = new System.Drawing.Size(300, 400);
           this.listTest.TabIndex = 1;
           this.Load += new System.EventHandler(this.OnLoad);
       }
       private void OnLoad(object sender, EventArgs e)
       {
           this.Controls.Add(listTest);
           listDataSource.Add(new DataType1("항목1",new Point(1,1)));
           listDataSource.Add(new DataType1("항목2",new Point(5,6)));
           listDataSource.Add(new DataType1("항목3",new Point(2,1)));
           this.listTest.DataSource = listDataSource; // ListBox와의 바인딩(연결)
           this.listTest.DisplayMember = "Name"; // DataType1의 Name 프로퍼티의 Get 내용이 출력
           this.listTest.ValueMember = "Pos"; // DataType1의 Pos 프로퍼티의 Get 내용이 내장 값
       }

  }
}

자 그럼 이게 무엇을 뜻하는 것일까요?
바로 Data와 View의 분리를 완전하게 선언 할 수 있게 됩니다.
지금은 예제를 위해 Console 프로그램에서 Windows.Form을 띄워 처리했지만,
Visual Studio의 Template로 제공하는 Windows application을 만들게 되면,
보통 Form용 클래스가 만들어집니다.
그러나 대부분이 이 Form 안에 Data든 View든 Control 이든 모든 로직을
이 클래스 하나에만 넣게 됩니다. 그렇게 되면 프로그램도 복잡해지고
소스관리도 어려워 지며 나중에 유지 보수 할 때도 애먹게 됩니다.

그러나 이 처럼 Data와 View를 분리해서 짜다보면 이런 문제점을 위의 문제를
수월하게 제어 하실 수 있게 됩니다.



3. ListBox 데이터 바인딩 팁.
이 글을 쓰게된 가장 중요한 사항인데, 사실 DataSource를 이용해 데이터 객체와 바인딩 하고 난뒤 이후의 처리가 굉장히 황당한 경우가 있습니다. 특히 원본 데이터 부분을 업데이트 했는데도 불구하고, ListBox내의 내용이 전혀 변화가 없는 경우입니다.
처음에 저는 다음과 같은 함수를 만들어 위의 문제를 해결해 보려고 했었습니다.

[CODE] private void UpdateList(ListBox listbox, List<DataType1> list)        {            try            {                BindingManagerBase bm;                bm = listbox.BindingContext[list];                bm.CancelCurrentEdit();                bm.ResumeBinding();            }            catch (Exception ex)            {                MessageBox.Show(ex.Message);            }            listbox.Refresh();        } [/CODE]
보통 컨트롤 내에 데이터 바인딩 기법을 사용하게 되면 데이터 바인딩에 관련된 기능들을 이용할 수 있는데, 여기서 데이터 바인딩 매니저를 이용하여 업데이트 하게 끔 만든 것입니다.
그러나 최악의 문제가 원본 데이터가 완전히 비어 있는 경우 입니다.
이 경우 원본 데이터가 비어 있으므로 ListBox의 컨트롤 데이터가 전혀 변화가 없게 됩니다.
그래서 결국 위의 내용을 다음과 같이 변경 했습니다

[CODE] private void RebindingListBox(ListBox listbox, List<DataType1> list, string DisplayName, string ValueName)        {            listbox.DataSource = null;            listbox.DataSource = list;            listbox.DisplayMember = DisplayName;            listbox.ValueMember = ValueName;        } [/CODE]

코드를 보시면 알겠지만, 바로 바인딩 작업을 완전히 리셋한 뒤 다시 바인딩을 시도했습니다.
이 경우 바인딩 정보가 완전히 리셋되기 때문에, 원본 데이터 내용이 비어 있어도,
정상적으로 처리가 됩니다.

물론 위의 방법은 제가 발견한 팁일 분, 프로그래밍의 정답은 아닙니다.
개인적으로도 위의 방법은 비용이 조금 비쌀듯 해보입니다. 바인딩 정보를 완전히
날리고, 다시 재 바인딩 하기 때문에, 무언가 비용이 많이 들어갈 것 같습니다.
하지만, 현재 제가 발견한 방법 중에 확실하게 처리되는 것 같아 제시한 것입니다.

더 좋은 방법이나 다른 의견 있으시면 댓글을 통해 말씀해주시면 고맙겠습니다.
728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

The COM Elevation Moniker

기술자료/OS 2006. 11. 30. 22:50

이 문서내의 내용의 오역으로 인한 피해에 대해서는 절대 책임지지 않습니다. 반드시 원문을 보시고, 제가 작성한 문서는 단지 참고만 하시기 바랍니다.

문서 원본 위치
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/com/html/1595ebb8-65af-4609-b3e7-a21209e64391.asp
The COM Elevation Moniker  
- Windows Vista에서 COM 개체의 접근 권한 상승 시키기.

COM을 이용한 권한 상승 Moniker란, 사용자 계정 권한 제한(Limited User Accout : LUA )하에서 동작 해야 하는 응용 프로그램이 권한 상승을 할 수 있도록, COM 클래스의 활성화 작업을 수행하는 것입니다. LUA에 대한 더 자세한 사항은 Security in Longhorn : Focus on Least Privilege을 보시기 바랍니다.

Elevation Moniker를 사용할 때
Elevation moniker란, 권한이 제한된 상태로 실행 중인 COM 클래스가 시스템 날짜 및 시간을 설정하는 것과 같이,높은 권한을 필요로 하는 경우 해당 권한을 활성화 주는 것을 말합니다.
권한 상승 작업은 COM 클래스 자체 뿐만 아니라, COM 클래스를 사용하는 클라이언트까지, 두가지다 필요합니다. 먼저 COM 클래스는 권한 상승을 하기 위한 설정 작업으로 자신의 레지스트리 항목 중 Requirements 섹션에 별도의 기록을 수행해야 합니다. 그리고, COM 클라이언트는 별두 작업을 수행하기 보다, 권한 상승 Moniker을 이용하여 권한 상승요청을 하면 됩니다.
권한 상승 Moniker 자체는 응용 프로그램 호환성을 고려하여 구성하지 않았습니다. 즉 보안을 중심으로 고려하였기 때문에, 별도의 우회적인 회피방법을 제시하진 않습니다. 그래서 과거의 COM 클래스와 클라이언트 간의 권한 상승 문제로 응용 프로그램 호환성 오류가 발생할 수 있습니다. 예를 들어, WinWord와 같이 권한 상승을 높아야 하는 기존 COM 클래스를 COM 클라이언트에서 실행하려면, COM 클래스 뿐만 아니라, COM 클래스를 이용하는 클라이언트도 권한 상승 Moniker로 활성화 시켜야 합니다.
단, 기존 COM 클래스의 CLSID로 CoCreateInstance를 호출해 COM 클라이언트의 권한을 상승 시켰어도, COM 클라이언트의 권한은 COM 서버 프로세스의 권한을 따라가게 됩니다.  물론, 모든 COM 자체의 기능 수행에 반드시 권한 상승이 필요한 것은 아니지만, 다음과 같은 제한들로 정상적으로 동작하지 않을 것입니다.

  • COM 클라이언트의 권한이 높더라도 원격 COM 서버의 권한까지 높아지는 것은 아닙니다. 클라이언트가 권한 상승 Moniker로 권한 상승을 했다고 하더라도, COM 서버 자체가 자동적으로 권한 상승되진 않습니다.
  • 만일 권한 상승된 COM 클래스가 COM 호출 시 impersonation(가장화)를 사용할 때, impersonation(가장화) 중에 상승된 권한을 잃게 될지 모릅니다.
  • 만일 권한 상승된 COM 서버가 Running Object Table(ROT)상에 클래스를 등록할 때, 권한 상승되지 않은 클라이언트에서는 그 클래스를 활용하지 못합니다.
  • 중간(Medium) 보다 높은 통합 레벨(Integraity Level : IL )로 동작하는 프로세스는 COM 활성화 중에 사용자 별 클래스를 적재 할 수 없습니다. 만일 COM 응용 프로그램이 Administrators 급 계정이던 아니던 간에 사용하게 하려면, HKEY_LOCAL_MACHINE 레지스트리 상에 응용 프로그램의 COM 클래스가 설치되어 있어야 합니다. 만일 Administrators 급 계정에서만 응용 프로그램을 사용하게 된다면 응용 프로그램 COM 클래스는 반드시 HKEY_USERS 쪽에 설치하셔야 합니다.
  • 권한 상승되지 않은 응용 프로그램에서 상승된 응용 프로그램쪽으로 드래그 앤 드랍을 지원하지 않습니다.

필요사항
COM 클래스를 활성화 하기 위해 권한 상승 Moniker를 사용하기 앞서 클래스는 반드시 실행 사용자 또는 '활성자로써 활성화(Activate as Activator)'의 응용 프로그램 ID로 실행 할 수 있도록 설정되어 있어야 합니다. 만일 클래스가 여타 다른 ID하에서 실행되도록 설정하려면, Activation에서는 CO_E_RUNAS_VALUE_MUST_BE_AAA 에러를 돌려주게 됩니다.
클래스에서는 반드시 다중 언어 사용자 인터페이스(MUI) 호환이 되는 "친숙한" 표시 이름으로 되어 있어야 합니다. 여기서는 다음과 같은 레지스트리
항목이 필요하게 됩니다.:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID\

  {CLSID}\LocalizedString = <displayname>

만일 항목이 빠진 경우, Activation에서는 CO_E_MISSING_DISPLAYNAME 에러를 돌려주게 됩니다. 만일 MUI 파일이 빠진
경우 RegLoadMUIStringW API에서 에러 코드를 돌려주게 됩니다.
추가적으로, LUA 사용자 인터페이스에서 보여주게 될 응용 프로그램 아이콘을 표시하려면 다음 레지스트리 키를 추가해 줍니다.:

HKEY_LOCAL_MACHINE\Software\Classes\CLSID\

  {CLSID}\IconReference = <applicationicon>

COM 클래스에서는 LUA-Enabled 와 같은 표시가 반드시 필요합니다. 이 사항을 적용하려면 다음과 같은 레지스트리 항목을 추가하시면 됩니다.

HKEY_LOCAL_MACHINE\Software\Classes\CLSID\

  {CLSID}\Elevation\Enabled = 1

만일 항목이 빠져 있는 경우 Activation에서는 CO_E_ELEVATION_DISABLED이라는 에러를 돌려주게 됩니다.
HKEY_LOCAL_MACHINE 항목 상에 이들 항목이 있는 경우, HKEY_CURRENT_USER 및 HKEY_USERS 항목에서는 없어야
합니다. 이는  COM 클래스의 권한 상승을 레지스트리 등록 권한이 없는 사용자가 멋대로 등록하는 경우를 방지하기 위해서 입니다.

권한 상승 Moniker 및 권한상승 UI
만일 클라이언트가 이미 권한 상승 Moniker로 권한 상승이 된 경우, 권한 상승 UI를 보여주지 않게 합니다.

권한 상승 Moniker를 사용하는 방법
권한 상승 Moniker는 표준 COM Moniker이며, 세션, 파티션 또는 큐 형태의 Moniker들과 유사합니다. 특정 권한 레벨을 특정 서버에 활성 요청을 관리합니다.Moniker 문자열에서 활성화 할 CLISID를 나타냅니다.
권한 상승 Moniker에서는 다음과 같은 실행 레벨 토큰들을 지원합니다.

  1. Administrator(관리자).
  2. Highest(높음).

이 사항에 대한 문접은 다음과 같습니다.

[code]
Elevation:Administrator!new:{guid}
Elevation:Highest!new:{guid}
[/code]

앞의 문법 중에서 해당 GUID의 COM 클래스의 새로운 인스탄스를 받으려면 "new" Moniker를 사용하면 됩니다. 여기서 "new" Monker에서는 클래스 객체를 탑재한 후 IClassFactory::CreateInstance를 호출하기 위해 IClassFactory interface 를 내부적으로 사용한다는 것에 주의해주시기 바랍니다.
또한 권한 상승 Moniker가 IClassFactory를 구현하기 위해 클래스 객체를 얻을 때 이용 될 수 있습니다.그리고 호출자에서는 객체 인스탄스를 얻기 위해 IClassFactory::CreateInstance 를 호출하게 됩니다. 이 사항에 대한 문법은 다음과 같습니다.

[CODE] Elevation:Administrator!clsid:{guid} [/CODE]

예제 코드
다음 예제 코드에서는 어떻게 권한 상승 Moniker를 사용하는지에 대한 내용입니다. 이 부분의 의미하는 사항은 현재 쓰레드 상에서 이미 초기화 된 COM을 나타내는 것입니다.

[CODE] HRESULT CoCreateInstanceAsAdmin(HWND hwnd, REFCLSID rclsid, REFIID riid, __out void ** ppv) {   BIND_OPTS3 bo;   WCHAR  wszCLSID[50];   WCHAR  wszMonikerName[300];

  StringFromGUID2(rclsid, wszCLSID, sizeof(wszCLSID)/sizeof(wszCLSID[0]));   HRESULT hr = StringCchPrintf(wszMonikerName, sizeof(wszMonikerName)/sizeof(wszMonikerName[0]), L"Elevation:Administrator!new:%s", wszCLSID);   if (FAILED(hr))        return hr;   memset(&bo, 0, sizeof(bo));   bo.cbStruct = sizeof(bo);   bo.hwnd = hwnd;   bo.dwClassContext  = CLSCTX_LOCAL_SERVER;   return CoGetObject(wszMonikerName, &bo, riid, ppv); } [/CODE]

BIND_OPTS3은 Windows Vista에서 새롭게 등장한 사항입니다. 이 부분은 BIND_OPTS2에서 상속 받은 사항으로 다음과 같은 형태로 정의되어 있습니다.

[CODE] typedef struct tagBIND_OPTS3 : tagBIND_OPTS2 {   HWND hwnd; } BIND_OPTS3, * LPBIND_OPTS3; [/CODE]

한가지 추가적인 사항은 HWND 필드, hwnd가 있습니다.이 핸들은 대부분의 경우 권한 상승 UI의 부모가 될 윈도우를 나타내게 됩니다.
만일 hwnd가 NULL인 경우 COM은 현재 스레드에 관련된 Window Handle을 찾기 위해 GetActiveWindow를 호출하게 됩니다. 클라이언트가 스크립트로 구성되어, 발생되는 경우로 BIND_OPT3 구조체의 정보가 불완전하게 담기게 됩니다. 이 경우, COM에서는 스크립트 스레드와 관련된 Window를 사용하도록 시도하게 됩니다.

Over-The-Shoulder 권한 상승(OTS)
Over-the-shoulder 권한 상승 (Over-the-shoulder elevation : OTS)은 사용자 자체 권한 이라기 보다 관리자 권한을 가진 사용자의 권한으로 COM 서버가 동작하는 클라이언트에서 볼 수 있는 시나리오 상황 입니다.(Over-the-shoulder 의 의미는 사전적으로 훔쳐보다로써, 클라이언트가 서버를 동작시키는 것과 같이 클라이언트 권한 밖에서 관리자 처럼 동작시키는 것을 의미합니다.)
이 시나리오에서는 서버로 COM을 호출하는 문제를 발생시킬 수 있습니다. 그 이유로는 서버가 명확하거나(대부분 프로그램 로직상으로), 무조건적으로(정확히 말하자면, 레지스트리를 이용하여) CoInitializeSecurity를 호출하지 못하기 때문입니다. 그런 서버들 때문에, COM에서는 서버로 COM을 호출 할 수 있도록 SELF, SYSTEM 및 Builtin\Administrators를 나타내는 보안 명세서를 산정하게 됩니다.이 명세서는 OTS 시나리오에서 동작하지 않습니다. 대신에 서버는 INTERACTIVE SID 및 System Group을 포함하는 ACL을 명시에 명확하고 무조건적적으로 방법을 벗어나 CoInitializeSecurity를 반드시 호출하게 해줍니다.
다음 예제 코드에서는 INTERACTIVE group SID로 보안 명세서(security descriptor : SD)를 어떻게 생성하는지 보여주게 됩니다.

[CODE] BOOL GetAccessPermissionsForLUAServer(SECURITY_DESCRIPTOR **ppSD) { // Local call permissions to IU, SY   LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0x3;;;IU)(A;;0x3;;;SY)";   SECURITY_DESCRIPTOR *pSD;   *ppSD = NULL;   if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))   {        *ppSD = pSD;        return TRUE;   }    return FALSE; } [/CODE]

다음 예제 코드는 이전 예제 코드에서 SD로 명확하게 CoInitializeSecurity를 호출하는 방법을 보여줍니다.

[CODE] // hKey is the HKCR\AppID\{GUID} key BOOL SetAccessPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD) {   BOOL bResult = FALSE;   DWORD dwLen = GetSecurityDescriptorLength(pSD);   LONG lResult;   lResult = RegSetValueExA(hkey,        "AccessPermission",        0,        REG_BINARY,        (BYTE*)pSD,        dwLen);   if (lResult != ERROR_SUCCESS) goto done;   bResult = TRUE; done:   return bResult; } [/CODE]

다음 코드는 SD 상위의 권한으로 무조건적으로 CoInitializeSecurity를 호출하는 방법을 보여줍니다.

[CODE] // Absolute SD values PSECURITY_DESCRIPTOR pAbsSD = NULL; DWORD AbsSdSize = 0; PACL  pAbsAcl = NULL; DWORD AbsAclSize = 0; PACL  pAbsSacl = NULL; DWORD AbsSaclSize = 0; PSID  pAbsOwner = NULL; DWORD AbsOwnerSize = 0; PSID  pAbsGroup = NULL; DWORD AbsGroupSize = 0;

MakeAbsoluteSD (   pSD,   pAbsSD,   &AbsSdSize,   pAbsAcl,   &AbsAclSize,   pAbsSacl,   &AbsSaclSize,   pAbsOwner,   &AbsOwnerSize,   pAbsGroup,   &AbsGroupSize ); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) {   pAbsSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LMEM_FIXED, AbsSdSize);   pAbsAcl = (PACL)LocalAlloc(LMEM_FIXED, AbsAclSize);   pAbsSacl = (PACL)LocalAlloc(LMEM_FIXED, AbsSaclSize);   pAbsOwner = (PSID)LocalAlloc(LMEM_FIXED, AbsOwnerSize);   pAbsGroup = (PSID)LocalAlloc(LMEM_FIXED, AbsGroupSize); if ( ! (pAbsSD && pAbsAcl && pAbsSacl && pAbsOwner && pAbsGroup)) {    hr = E_OUTOFMEMORY;   goto Cleanup; } if ( ! MakeAbsoluteSD(        pSD,        pAbsSD,        &AbsSdSize,        pAbsAcl,        &AbsAclSize,        pAbsSacl,        &AbsSaclSize,        pAbsOwner,        &AbsOwnerSize,        pAbsGroup,        &AbsGroupSize        )) {      hr = HRESULT_FROM_WIN32(GetLastError());      goto Cleanup; } else {      hr = HRESULT_FROM_WIN32(GetLastError());      goto Cleanup; } // CoinitilizeSecurity 호출 [/CODE]

COM 권한 및 위임 접근 라벨(COM Permissions and Mandatory Access Labels)
Windows Vista에서 보안 상세서(security descriptors : SD)에 있는 위임 접근 라벨에 대한기본적인 내용을 소개하였습니다.라벨에서는 클라이언트가 COM 객체로 접근 실행할 수 있도록 지시하게 됩니다. 라벨에는 보안 명세서의 시스템 접근 제어 리스트(system access control list : SACL)내에 명시되어 있습니다. Windows Vista에서는 COM 자체적으로 SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP 라벨을 지원합니다. Windows Vista 이전 운영체제에서는 COM 권한 내의 SACLs들의 내용이 무시되었습니다.
Windows Vista에서는 dcomcnfg.exe가 COM 권한 내에서 더 이상 통합 레벨(IL) 변경을 지원하지 않습니다. 반드시 프로그렘 적으로 설정하게끔 되어 있습니다.
다음 예제 코드에서는 모든 낮은 IL 클라이언트에서 실행/활성화 요청을 할 수 있도록 라벨을 이용하여 COM 보안 명세서를 어떻게 생성하는지에 대해 나타내고 있습니다. 이렇게 하면, 일정한 IL을 가진 클라이언트에서 실행, 활성화 또는 호출에서 실패된 COM 서버를 쓸 수 있게 됩니다.통합 레벨(IL)에 대한 더 자세한 사항은 Understanding and Working in Protected Mode Internet Explorer 안에 있는 "Understanding Windows Vista's Integrity Mechanism" 섹션을 보시기 바랍니다.

[CODE] BOOL GetLaunchActPermissionsWithIL (SECURITY_DESCRIPTOR **ppSD) { // Allow World Local Launch/Activation permissions. Label the SD for LOW IL Execute UP   LPWSTR lpszSDDL = L"O:BAG:BAD:(A;;0xb;;;WD)S:(ML;;NX;;;LW)";   if (ConvertStringSecurityDescriptorToSecurityDescriptorW(lpszSDDL, SDDL_REVISION_1, (PSECURITY_DESCRIPTOR *)&pSD, NULL))   {        *ppSD = pSD;        return TRUE;   } } BOOL SetLaunchActPermissions(HKEY hkey, PSECURITY_DESCRIPTOR pSD) {   BOOL bResult = FALSE;   DWORD dwLen = GetSecurityDescriptorLength(pSD);   LONG lResult;   lResult = RegSetValueExA(hkey,        "LaunchPermission",        0,        REG_BINARY,        (BYTE*)pSD,        dwLen);   if (lResult != ERROR_SUCCESS) goto done;   bResult = TRUE; done:   return bResult; }; [/CODE]

CoCreateInstance 및 통합 레벨(IL)
CoCreateInstance의 기능은 Windows Vista에 이르러 낮은IL 클라이언트에서 기본적으로 COM 서버를 연결하는 것을 방지하게 끔 변경되었습니다. 서버는 반드시 SASL로 명시하여 연결해야 명확하게 연결되게 됩니다.CoCreateInstance의 변화된 사항은 다음과 같습니다.

  • COM 서버 프로세스를 실행할 때, 서버 프로세스 토큰 내 IL이 클라이언트 또는 서버 토큰 IL으로 설정되어 있어야 하며, 무엇보다 IL이 낮아야 합니다.
  • 기본적으로, COM은 어떠한 COM 서버의 인스탄스를 실행하기 위해 낮은 IL 클라이언트이 연결하는 작업 자체를 배제합니다.연결을 허용하려면, COM 서버의 실행/활성화 보안 명세서(Launch/Activation security descriptor)가 낮은 IL 라벨 상에 명시되어 있는 SACL이 담겨 있어야 합니다.(이와 같은 보안 명세서를 생성하기 위한 예제 코드를 이전 섹션에서 보실 수 있습니다.)

권한 상승된 서버 및 ROT 등록
만일 COM 서버에서 실행 객체 테이블(Running Object Table : ROT)에 등록하는 경우나 기타 클라이언트 상에서 등록을 할 수 있도록 하려면, 제일 먼저 을 원하는 경우 ROTFLAGS_ALLOWANYCLIENT 플래그를 사용하셔야 합니다. 단, '활성자로써 활성화(Activate as Activator)' 형태의 COM 서버에서는 ROTFLAGS_ALLOWANYCLIENT를 명시해줄 수 없는데 그 이유는 DCOM 서비스 컨트롤 관리자(DCOMSCM)에서 강제적으로 이 플래그에 대한 속임수 체크를 수행하기 때문입니다. 그러므로 Windows Vista에서는 COM에서 새로운 레지스트리 항목에 대한 지원을 추가해야 합니다. 새로운 레지스트리 항목은 클라이언트에 가능하게 만들어주는 ROT 등록을 명시적으로 할 수 있도록 서버를 허용하는 항목입니다.

HKEY_LOCAL_MACHINE\Software\Classes\AppID\

{ APPID }

REG_DWORD_ROTFlags

단 한개의 이 항목에 대해 적용가능한 값은 다음과 같습니다.

[CODE] ROTREGFLAGS_ALLOWANYCLIENT 0x1 [/CODE]

이 항목은 HKEY_LOCAL_MACHINE 영역에 있어야 합니다.
그리고 ROTFLAGS_ALLOWANYCLIENT 로 RunAs server가 제공되는 기능을 '활성자로써 활성화(Activate as Activator)'와 동일하게 동작하기 위한 사항입니다.

추가적인 사항
Reference
BIND_OPTS3

기타 자료
Understanding and Working in Protected Mode Internet Explorer



728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

RAM, Virtual Memory, Pagefile and all that stuff - 요약본

기술자료/OS 2006. 10. 9. 12:06

전체 원본 내용 : http://members.shaw.ca/bsanders/WindowsGeneralWeb/RAMVirtualMemoryPageFileEtc.htm

원본 : http://support.microsoft.com/kb/555223

윈도우를 포함한, 최신 운영체제 대부분은 응용 프로그램이나 각종 프로세스를 실행할 때, 실제 메모리 주소 공간과 매핑되어 있는 가상 메모리 주소 공간 상에서 항상 실행되도록 되어 있습니다. 단지 운영체제 핵심 커널만 실제 메모리 주소 공간을 이용하게 됩니다.
가상 메모리를 항상 이용 함으로써 시스템 상에 설치된 물리적인 램 크기를 넘어서는 용량이 필요한 프로세스들도 정상적으로 동작하게 됩니다.

 

프로세스와 주소 공간
32 비트 윈도우에서는 실제 시스템 상에 메모리가 얼마이든 간에 모든 프로세스는 4G(Giga Byte)[ 2 ^ 32 -1) ]의 용량의 가상 메모리 주소 공간을 가져올 수 있습니다.
기본 윈도우 설정을 기준으로 4G 중 2G 부분은 프로세스 개별적으로 이용하게 되는 주소 공간이고 나머지 2G는 다른 프로세스 및 운영체제와 공유해서 이용하게 되는 주소 공간입니다.
그래서 보통 응용 프로그램(메모장, 엑셀, 인터넷 익스플로어 등)은 2G 개별 주소 공간내에서 실행되도록 구성 되게 됩니다. 이 때 운영체제는 단지 응용 프로그램에서 필요로 하는 용량 만큼 가상 메모리 페이지 크기에 맞게 RAM상에 페이지 프레임(Page Frame)을 지정하게 됩니다.

여기서 물리 주소 확장(Physical Address Extention : PAE)이라는 기능이 있는데, 물리 메모리 주소를 36 비트로 확장해주는 32비트 아키텍처 입니다.(역주: 32비트 컴퓨터에서는 보통 32 비트의 물리 메모리 주소, 즉 최대 4G [ 2 ^ 32 - 1 ]의 주소공간을 가질 수 있읍니다. 이를 36비트로 확장한다는 의미입니다. 그러므로 최대 64G[ 2 ^ 36 - 1 ]의 주소공간을 가질 수 있게 됩니다.) - 참고 할 만한 정보로는 http://support.microsoft.com/kb/268363 를 보시면 됩니다. 그러나 이 가상 메모리는 PAE로 인해 크기적인 변화가 없으며 단지, 프로세서(CPU)에서 시스템 내에 설치된 메모리의 주소 영역만 확장되는 것입니다.
이 때 프로세스 내에서 동작되는 32Bit 기준의 가상 메모리 주소 공간과 36Bit 메모리 주소 공간 간의 변환 작업은 운영체제에서 관리하는 변환 표(Translate Table)에 따라 하드웨어 상에서 자동적으로 제어되며 투명하게 변환이 됩니다.

다음 목록은 각각 윈도우 버전 및 에디션에 따른 지원되는 최대 램용량입니다.(2004년 11월 현재 기준)
  Windows NT 4.0: 4 GB
  Windows 2000 Professional: 4 GB
  Windows 2000 Standard Server: 4 GB
  Windows 2000 Advanced Server: 8GB
  Windows 2000 Datacenter Server: 32GB
  Windows XP Professional: 4 GB
  Windows Server 2003 Web Edition: 2 GB
  Windows Server 2003 Standard Edition: 4 GB
  Windows Server 2003 Enterprise Edition: 32 GB
  Windows Server 2003 Datacenter Edition: 64 GB

페이지 파일
램은 제한 적인 자원인 반면, 가상 메모리는 이상적인 주소 공간이기 때문에 이론적으로 제한이 없습니다. 물론 프로세스 별 최대 할당될 수 있는 주소 크기는 2G입니다. 모든 프로세스들이 사용하는 총 메모리 용량이 실제 메모리의 총 용량을 넘어서면, 운영체제에서는 하나 혹은 여러개의 가상 메모리 주소의 페이지(4Kb 단위의 조각)를 하드 디스크 상에 옮기고, 옮겨진 양 만큼의 메모리 공간을 회수 하게 됩니다. 윈도우 시스템에서는 이들 "페이지 아웃(Paged Out)"된 를 pagefile.sys라고 불리는 파일을 한개 혹은 여러 개로, 시스템 하드 디스크의 루트 디렉토리 상에 저장하게 합니다. 물론 이 파일을 각 하드 디스크의 파티션 별로 하나씩 담을 수도 있습니다. 이 부분에 대한 설정은 시스템 등록정보, 고급, 성능(설정 탭을 클릭)에서 하실 수 있습니다.

가장 많은 질문 내용 중에 "페이지 파일을 얼마나 크게 잡아야 되나요?" 라는 것이 있는데, 사실 이 질문에 대한 정확한 한가지 답은 없습니다. 그 이유는 설치된 램 크기와 작업 중에 가상 메모리 사용량에 따라 달라지기 때문입니다. 그 외 특별한 사항이 없다면, 일반적으로 설치된 메모리의 1.5 배의 용량으로 구성하는 것이 가장 좋은 형태라고 권장하고 있습니다. 서버 시스템 중 일반적인 목적을 위해 구성되어 충분한 램 용량을 갖추어 있다면 굳이 페이지 파일을 구성할 필요는 없습니다. 이런 시스템에서는 큰 페이지 파일을 만들어 제공할 필요가 거의 없는 것이죠. 그러나 다른 한편으로는 간혹 발생될 큰 규모의 메모리 할당이 요구 될 시, 시스템 불안정한 상황이 발생할 수 있습니다. 이런 경우를 대비하기 위해 통상 앞서 말씀 드린 1.5배 이상의 가상 메모리를 미리 잡아 두는 것도 나쁘지는 않습니다.

성능, 아키텍처 상 제한 과 RAM
어느 컴퓨터 시스템이든 간에, 작업량(사용자 수, 업무를 수행하는 개수)이 증가되면 성능(업무를 처리하는데 걸리는 시간)은 감소되게 됩니다. 하지만 이 관계는 비 대칭형으로 진행되게 됩니다. 작업량 증가의 형태가 어느 정도였든간에, 극적인 성능 감소를 넘어서는 지점을 넘어서게 됩니다. 이 의미는 몇몇 자원들이 최악으로 소량 제공되어 결국 병목현상을 불러 일으킨다는 것입니다.

몇몇 지점에서는 최악으로 소량 제공되는 자원들이 증가되지는 않게 됩니다. 이는 아키텍쳐 상 제한에 도달했다는 것을 의미합니다. 윈도우의 아키텍쳐 상 제한에 대한 몇가지 보고 내용은 다음과 같습니다.
  1. 시스템 상의 2 GB의 공유 가상 주소 공간
  2. 프로세스 당 2 GB의 개별 가상 주소 공간
  3. 660 MB 시스템 PTE 저장공간
  4. 470 MB 페이지 풀 저장공간
  5. 256 MB 페이지 되지 않은 풀 저장 공간

위의 내용은 Windows 2003 기준으로 나열된 사항입니다.(KB 294418 글 참조). 그러므로 Windows XP 및 2000에서는 위의 사항과 다를 수 있습니다.
보통 쉽게 접할 수 있는 권장 사항이 다음과 같은 경우 입니다.
&nbsp; 터미널 서버를 사용하는데, 4GB를 사용하기 전에 공유 메모리인 2G를 완전히 활용하시오.

대부분의 경우 맞기도 하지만, 여러분이 겪는 상황에 따라 다를 수 있습니다. 몇몇 유형 중에, 특정 Windows NT 4.0 또는 Windows 2000 Server에서 충돌이 발생하거나, Windows Server 2003 중에서 불필요할 수도 있습니다. Windows Server 2003으로 넘어오면서 크게 바뀐 부분 중에 보다 효율적으로 이 아키텍쳐상 제한이 발생되는 가능성을 줄였다는 것입니다. 예를 들면 커널 상의 몇가지 프로세스들을 커널 프로세스에서 제외시킴으로써 공유 가상 메모리 사용량을 대폭 줄였습니다.

RAM 및 가상 메모리 사용량 감시하기
성능 감시기(시작, 관리자 도구, 성능)은 시스템의 성능을 측정하고 병목 현상을 실제 일으키는 사항이 무엇인지를 파악할 수 있도록 도와주는 중요한 도구 입니다. 아래에는 이 도구를 이용하여 측정할 수 있는 중요한 정보들에 대한 요약들을 나열합니다.

Memory, Committed Bytes
- 여기서는 가상 메모리의 의존도를 측정하게 됩니다. 운영체제에서 페이지 파일 내에 RAM 페이지 프레임 또는 페이지 슬롯을 적용한(Commited) 바이트 수와 프로세스 상에서 할당한 바이트수가 얼만큼인지를 보여줍니다.(대부분 2가지 동시에). 이 적용 바이트(Committed Byte) 수는 허용된 RAM 용 보다 늘어나게 되면, 페이징이 증가되며, 사용하는 페이지 파일의 총 용량도 증가됩니다. 몇몇 지점에서는 페이징 작업 자체가 실제적인 성능과 직결되어 영향을 미치기 시작할 것입니다.

Process, Working Set, _Total
- 여기서는 "active"하게 사용되는 가상 메모리 용량을 측정하게 됩니다. RAM내의 모든 프로세스들이 실제적으로 사용하는 가상 메모리에 대해 얼만큼의 RAM 필요한지를 보여주게 됩니다. 여기서는 항상 4,096이 곱해져서 나타내는데, 그 이유는 Windows 상에서 페이지 크기로 그 만큼의 크기를 사용하고 있기 때문입니다.가상 메모리가 사용 가능한 RAM 용량을 넘어서서 의존하게 되면, 운영체제 에서는 사용가능한 RAM과 최소 페이징 이용에 대해 최적화하는 Working Set 에 맞추어 프로세스의 가상 메모리의 양을 조절하게 됩니다.

Paging File, %pagefile in use
- 여기서는 페이지 파일이 실제적으로 사용되는 양을 측정하게 됩니다. 페이지 파일이 적절한 크기 인 경우가 언제 인지 측정하기 위해 사용되는 카운터 입니다. 만일 이 카운터가 100을 가지게 되면, 페이지 파일이 완전히 꽉 찼다는 의미가 되며, 몇몇은 작업을 중지하게 될 것입니다. 작업량의 변화에 따라 충분히 큰 페이지 파일이 필요할지 모르지만, 보통 50~70% 이하로 사용되게 됩니다. 만일 사용된 페이지 파일 수가 적다면, 다른 물리 디스크 상에 하나 또는 그 이상을 가질 수 있게 되며, 성능이 증가되게 됩니다.

Memory, Pages/Sec
- 여기서는 대부분은 잘못 인식된 값의 측정되는 내용 중 하나 입니다. 이 카운터의 최고값이 성능이 RAM 부족으로 인해 병목 현상이 발생된 것이라고 정확하게 의미하는 것은 아닙니다. 운영체제에서는 명시된 메모리에 제공될 스왑 페이지와는 다른 목적으로 페이징 시스템이 이용됩니다.

Memory, Pages Output/Sec
- 여기서는 매 초마다 다른 목적으로 RAM 페이지 프레임이 해제되기 위해 가상 메모리 페이지가 페이지 파일로 얼마나 많이 쓰여 졌는지를 보여줍니다. 이 기능은, 페이징이 성능의 병목현상을 일으키고 있는지 여부를 예측할 때 감시 할 때 사용되는 최적의 카운터 입니다.

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

처음하는 프로그래밍 [1] - 머릿말

기술자료/.NET 2006. 10. 2. 14:55
지금 부터 동생님을 위해 자그만한 글타래를 펼쳐보려 합니다.
사실 프로그래밍의 프자도 모르는 사람에게, C#이라는 도구를 던져주고
프로그래머 같은 생각을 하며, 프로그래밍을 짜라고 하면 상당히 막막한
입장에 빠집니다.
게다가, 제대로 기능을 활용 못하는 도구를 실행 시켜 맨 도화지 같은 상태에서 프로그래밍을 시작하기란 정말이지 힘든일이 아닐 수 없습니다.
어제 문득 동생님의 프로그래밍을 돕다가 "왜 프로그래밍을 못짤까?" 라는 화두를 나에게 스스로 던져 보았습니다. 물론 프로그래밍을 모른다는 것도 있을 것이며, 제가 잘못 알려준 것도 있으며, 더욱이 제가 C#을 제대로 모르는 것도 있을 수 있습니다.
그러나 그보다 더 근원적인 무언가가 있을 것이라 생각이 되었고, 담배를 입에 물면서 고민을 했습니다.
난 언제 부터 프로그래밍적인 사고를 갖게 된 것일까요? 그래서 지금의 위치에 있는 것일까요? 물론 무척 잘하거나 많이 아는 것은 아니지만, 최소한 이런 저런 기술책을 보면서도 그다지 난해하다고 생각되지 않다고 생각된 내용이 왜 내 동생에게는 난해하다고 생각하는 것 일까요?  내가 나름대로 쉽게 가르친다고 생각도 했고, 나중에 겪을 수 있는 혼란을 미리 예방한다는 생각에 알려주었습니다. 그러나 내 동생은 그렇게 받지 못하고, 도리어 혼란속에 허우적 대고 있다는 것입니다.

결론은 "개구리, 올챙이적 생각을 못한다" 였습니다.

그래서 내 시작이 어떤 것이였는지, 그리고 내가 가진 철학은 무엇인지를 알려주고, 혼란을 최소화 하기 위한 문제/답 스타일의 이야기를 펼쳐 알려줘야 겠다는 생각이 듭니다.

1. 프로그래밍 시작.
내가 프로그래밍을 시작하게된 계기는 무엇일까...라는 생각을 했습니다.
사실 굉장히 개인적인 부분이고, 그 시작이 될 수 있는 부분은 인연과 같은 우연적인 요소가 강하기 때문에, 사실 단언해서 이것이 정답이며 이렇게 걸어야 한다! 라고 말하긴 힘듭니다.

하지만, 제가 만난 사람들과 이야기를 나누면서 프로그래밍을 시작한 계기들을 정리하자면 다음과 같습니다.
  - 개인적인 흥미로 시작했습니다.
  어릴 때, 게임을 보거나, 자신이 만든 프로그램 결과물이 즐겁거나, 아니면 성취감에 대한
  정신적 만족감을 느껴 본 것입니다. 보통은 큰 규모의 프로그래밍 보다는 작은 규모의
  프로그래밍, 특히 정답이라는 형태가 잡혀 있는 문제와 답 형식 간단한 구현을 통해 책을
  통해 다양한 시도를 하면서 독학을 하게 되었을 것입니다.
- 일을 하다가 시작했어요.
  프로그래밍 하는 것을 선배 혹은 사수(자신의 직속 상관)을 통해서 신입사원때 배운 것
  입니다. 위를 통해 전수 받는 것이기 때문에, 그 형태는 다양하게 나오게 되는데, 보통
  많이 갈구는 스타일한테 배운 사람이 많이 늘더군요. 역시 매를 맞아가면서 배워야
  빨리 는다는 아주 원초적인 교육적 원리인 것 같습니다.
- 학원(학교)에서 배웠습니다.
   더 이상 시도해볼 것도 없거나, 자신의 실력이 없거나, 돈을 많이 벌 수 있다는 등의
  다양한 계기로 인해 학원에서 부터 출발할 수 있습니다. 또는 학교에서 정규 과정을 통해
서 출발 할 수 있습니다. 여기서는 대부분은 정규적인 과정이 있으며 그 중간 중간,
  간단한 문제와 답을 함으로써 기초적인 지식을 쌓게 합니다. 물론 Bit 전산원 같이 무척
  까탈시러운 과정을 통해 통과할 수 있습니다.
- 기타.
  그 외에는 다양한 계기들과 다양한 조건들이 있을 것입니다.

어느 부분 부터 시작된 것인지는 알 길은 없지만, 분명 저 중에 한가지 이거나 2~3가지가 복합적일 것입니다. 이것도 저것도 아니라더라도 기타에 다 걸릴 것입니다(笑). 무엇이 중요하고 잘 판단한 것인지는 개개인 마다 틀린 기준이기 때문에, 어디서 부터 출발하는 것이 좋은지는 알 수 없습니다. 단지, 자신이 어디에 처한지 정도 알 수 있겠죠?

2. 프로그래밍을 위한 자세
사실 프로그래밍을 하기 위한 자세란 딱히 없습니다. 대충 대충 짜든, 설계를 해서 짜든 결과만 제대로 나오기만 해도 반은 먹고 들어갑니다. 하지만, 프로그램 = 일 이라는 공식에 빠진 사람들은 대부분 이 4D(4-Danger)업종에서 발전없이 고생만 하다 나오는 것이 대부분의 패턴입니다. 크게 다르진 않죠. 그래도 곰같이 우직하게 일하시는 분들도 있지만...

여기서 제가 말하고 싶은 것은 2가지 입니다. 물론 이 내용들은  프로그래밍뿐 만 아니라 일 자체를 임할때 필요한 자세입니다.
첫번째는, 어느 방법으로 출발을 했던 일단 프로그래밍에 대해 재미있게 그리고 즐기면서 해야 합니다. 든 일은 재미있고 즐겁게 해야 그 결과가 완벽하거나 두세배의 결과치를 얻을 수 있습니다. 일 자체의 결과물 뿐만 아니라, 스스로의 능력도 배가 되는 것을 알 수 있습니다.
두번째는, 목표를 정확히 하는 것입니다. 내가 무엇을 할 것인지, 무엇이 될 것인지를 알아야 합니다. 내가 프로그래밍으로 무엇을 만들 것인지를 알아야 그 내용을 구현할 수 있을 것입니다. 또한 어떻게 배워야 하는지, 무엇을 더 공부해야 할지를 알 수 있을 것입니다. 거기에 내가 어떤 위치에 도달해야 하는지를 명확하게 하면 보다 더 정확한 목표의식을 가지게 됩니다.
이런 목표의식과 즐겁게 일을 할 수 있는 마음을 가질 수 있거나 그와 유사한 형태까지 갔다면 제가 이제 부터 풀어나갈 이야기들을 쉽게 수용하고 빠르게 배울 수 있을 것입니다.
아니라고 해도, 진행이 조금 늦을 뿐 배우기는 할 수 있을 것입니다.

3. 이야기를 하기 위한 Agenda
이 처음하는 프로그래밍을 위한 특별한 교육 순서는 없습니다. 그렇다고 많은 교재들이 택하고 있는 함수는 어쩌내, 클래스는 어쩌내, 상속은 어쩌내 하는 방법을 택하기엔 지겨울 듯 싶구요. 그래서 프로그래밍에 대한 나만이 가진 생각들을 말씀 드리고, 이 후에 문제와 답을 통해 간단한 프로그래밍을 실제로 구현해도록 합니다.
하다가 더 필요하다 싶으면 더 많은 내용을 이야기 할 것입니다.
다음은 이 이야기를 위한 순서 입니다.

  0. 머릿말
  1. 프로그래밍이란?
  2. 문제와 해결방법
  3. C#과 .NET Framework
  4. 고객 관리 프로그램
  5. 그래픽 프로그램.
  6. 정리



 

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

SMS 2003에서 SQL 2005를 지원하는가?

기술자료/개발도구 2006. 9. 25. 18:18

네, 단 SMS 2003 with SP2에서만 SQL 2005를 지원합니다. SMS 2003 with SP2 이전 버전에서는 SQL 2005를 지원하지 않습니다. 만일 이전 버전에 대한 설치 후 업그레이드를 하려면 다음과 같은 업그레이드 순서를 거쳐 진행하셔야 합니다.

업그레이드 순서

1.

SQL 2000 SP3 또는 4를 설치합니다.

2.

SMS 2003 with SP1을 설치합니다.

3.

SMS 2003 사이트 서버를 SP2로 업그레이드 합니다.

4.

SQL 2000 서버를 SQL 2005 서버로 업그레이드 합니다.

지원되는 플랫폼과 시스템 요구사항과 같은 자세한 정보는 Microsoft Download center 에 있는 Supported Configurations Guide SMS 2003 SP2  라는 문서의 "Server Software Requirement"를 보시기 바랍니다.

From : http://www.microsoft.com/technet/prodtechnol/sms/sms2003/techfaq/tfaq02.mspx

728x90
블로그 이미지

하인도1

[하인드/하인도/인도짱 의 홈페이지] 저만의 공간입니다. 다양한 소재들을 나열하는 아주 단순 무식한 홈페이지 입니다. 다양한 문서 자료도 있겠지만, 저의 푸념들도 있답니다.

  • «
  • 1
  • ···
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • ···
  • 44
  • »
250x250

블로그 내에 소스 코드 삽입 이사온 기념 스킨도... RSS 전문 기능 비활성화 관련. 스킨 바꾸어 보았습니다. 서버 파일 정리 좀 했습니다.

«   2025/05   »
일 월 화 수 목 금 토
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

Google Apps Engine java WSS SharePoint Azure windows e-book 비스킷 협업 개발환경 좀 친구 인터파크 매뉴얼 me2dayzm Buscuit Visual Studio 오류 moss 수 me2sms me2photo twi2me 블로그 Tutorial 지름신 2010 MOSS 2007 것 불만

  • Total :
  • Today :
  • Yesterday :

Copyright © 2015-2025 Socialdev. All Rights Reserved.

Copyright © 2015-2025 Socialdev. All Rights Reserved.

티스토리툴바