ASP.NET 에서 가장(Impersonate) 기능 사용하기

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (10/19/2011 1:01:25 PM) Viewing : 3759

프로젝트 진행중에 네트워크 드라이브에 엑셀파일을 업로드를 하고 그 파일을 열어서 Formula 를 읽어서 수식 계산 후에 클라이언트로 내려 주는 기능이 필요 하게 되었습니다.

먼저 네트워크 드라이브는 연결을 하게 되면 기본적으로 아이디 패스워드만 맞춰 주면 업로드 다운로드는 가능 하더군요..

그러나 파일을 오픈 하게 되면 엑세스 오류를 던집니다.

이런 경우 웹계정을 윈도우즈 계정으로 가장 하여 실행을 할 수 있습니다.

쉽게 말해 서버 운영체제에 있는 계정으로 로그인을 하여 그 권한을 획득 하는 것이죠..

기본적인 사항은  MSDN문서를 참고 하시면 되겠습니다.

위 문서중에 모든 연결에 대하여 가장을 하는 경우 

즉 web.config에서 라고 설정을 하면..특정 어셈블리를 로드 하지 못한다는 런타임 오류를 던지더군요...ㅡ.ㅠ;;

이거 아마도 추측 하기에 웹계정이 윈도우계정으로 가장되어서 윈도우계정이 웹권한이 없기 때문이 아닐까....생각해 봅니다..ㅡ.ㅡ;;

가장을 사용하기 위해서는...

서버에 계정과 비밀번호를 할당 합니다.

이 계정에는 기본적으로 제일 적은 권한인 Guests Role을 주고 나머지 Role은 제거 하는게 좋을 듯 싶습니다.

네트워크 서버에는 이 계정과 비밀번호가 같은 계정을 생성하여 공유하고자 하는 폴더를 공유 합니다.

이 절차가 끝나면 서버에서 윈도우즈 탐색기를 통해 위 계정으로 네트워크 서버에 접속이 가능하여야 합니다.

어쨋든..저는 코드에서 구현 하는 것으로 사용 하였습니다.

public const int LOGON32_LOGON_INTERACTIVE = 2;
public const int LOGON32_PROVIDER_DEFAULT = 0;

WindowsImpersonationContext impersonationContext; 

[DllImport("advapi32.dll")]
public static extern int LogonUserA(String lpszUserName, 
	String lpszDomain,
	String lpszPassword,
	int dwLogonType, 
	int dwLogonProvider,
	ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern int DuplicateToken(IntPtr hToken, 
	int impersonationLevel,  
	ref IntPtr hNewToken);
                          
[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]
public static extern bool RevertToSelf();

[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
public static extern  bool CloseHandle(IntPtr handle);

public void Page_Load(Object s, EventArgs e)
{
	if(impersonateValidUser("username", "domain", "password"))
	{
		//Insert your code that runs under the security context of a specific user here.
		undoImpersonation();
	}
	else
	{
		//Your impersonation failed. Therefore, include a fail-safe mechanism here.
	}
}

private bool impersonateValidUser(String userName, String domain, String password)
{
	WindowsIdentity tempWindowsIdentity;
	IntPtr token = IntPtr.Zero;
	IntPtr tokenDuplicate = IntPtr.Zero;

	if(RevertToSelf())
	{
		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 
			LOGON32_PROVIDER_DEFAULT, ref token) != 0)
		{
			if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) 
			{
				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
				impersonationContext = tempWindowsIdentity.Impersonate();
				if (impersonationContext != null)
				{
					CloseHandle(token);
					CloseHandle(tokenDuplicate);
					return true;
				}
			}
		} 
	}
	if(token!= IntPtr.Zero)
		CloseHandle(token);
	if(tokenDuplicate!=IntPtr.Zero)
		CloseHandle(tokenDuplicate);
	return false;
}

private void undoImpersonation()
{
	impersonationContext.Undo();
}

참고로 AD가 구현 되어 있지 않았다면 domain은 빈값을 넣어 주면 되겠습니다.

그러나..서버에 배포시 문제가 생겼습니다.

로컬 및 테스트 서버에서는 잘 작동 하였는데..서버에 배포를 하니..로그인 실패가 뜨는 것입니다.

LogonUserA 메서드가 false를 던지는 것이죠.

일반적으로 운영 서버의 경우 보안의 제약 사항이 많기 때문에 많은 제약 사항 중에 해당 되는 것을 찾아야 했습니다.

음.

결론은 로컬보안정책 > 사용자 권한 할당 > 로컬 로그온 허용 에 해당 계정을 넣어주면 되었습니다.

완전..개고생 했네요..

 

PS . 네트워크 서버의 경로는 코드 상에 UNC 경로로 입력 하여야 합니다.


마지막 업데이트 : (10/19/2011 1:03:55 PM)

TAG : 가장 



Trackback 보기 (0)
댓글 보기 (2)
kevin님의 글 (10/19/2011 1:41:26 PM)
한가지 궁금한 것이 생겼는데요. ^^

LogonUser 에 LOGON32_LOGON_INTERACTIVE 옵션을 준 경우라서 아마 그런 제약이 걸린 것이 아닐까 싶습니다. 그거 말고, LOGON32_LOGON_NETWORK_CLEARTEXT 를 주었다면... 아마 괜찮지 않았을까 싶은데요. (참고로, 해보지 않고 던지는 의문입니다. ^^)



방실이님의 글 (10/24/2011 11:15:16 AM)
성태씨 글 보고..일단 MSDN을 뒤져 보았습니다.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx
요런 링크에 해당 메서드에 대한 설명이 있네요..
logontype 부분의 설명을 보면 성태씨 의견 처럼 LOGON32_LOGON_NETWORK_CLEARTEXT가 맞을 것 같아요..
그래서 일단 적용을 해보았습니다.
다른 것은 건들지 않고 LOGONTYPE 파라메터의 값만 LOGON32_LOGON_NETWORK_CLEARTEXT으로 바꾸어 보았는데..
false가 떨어지네요..
참고로 저 값의 int 형 값은 8 입니다.
http://pinvoke.net/default.aspx/advapi32.LogonUser
위 링크를 참고 하면 되고요..
일단 테스트 결과는 그렇게 되었네요..
이거.... 참.....



댓글 쓰기

ckeditor에 syntax highlighter 세팅하기

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (9/2/2010 5:30:40 PM) Viewing : 7999

ckeitor 설정에 대한 글은

http://www.bangsil.net/MyArticles?postId=a7f36b53-6f9d-474b-a669-2b983cb17015

를 참고 하시면 되겠네요..

syntax highlighter 라는 것은 번역을 하자면 구문 강조 쯤 되겠네요.

이것은 html 페이지에 코드 블럭을 설정해 주는 것입니다.

물론 현재 이 사이트에도 적용 되어 있구요 이 아티클에도 사용되고 있지욤..

처음에 syntax highlighter 만 적용 했을 경우 ckeditor와 궁합이 안맞아서 태그가 깨지는 현상이 발생됩니다..

대략 난감 하죠..

어느 분이 이런 저같은 사람을 어여삐 여겨 플러그인을 만들어 놓으셨군요..클클...

이제 적용법을 알아 보도록 하겠습니다.

먼저 syntax highlighter 설치를 해야 겠지요?

http://alexgorbatchev.com/SyntaxHighlighter/

이것을 만드신 분의 사이트입니다..개략적으로 읽어 보도록 하십시요.

오늘 날짜(2010-09-02) 기준으로 3.0.83 버전을 다운 받을 수 있군요.

압축을 풀면 테스트 해 볼수 있도록 잘 만들어져 있고요..뭐 각자 해보시기 바래요.

scripts 폴더를 열어 보면 엄청나게 많은 스크립트들이 있군요.

이중에서 필요한 것만 추려 봅니다.

필수 스크립트는 shCore.js 와 shLegacy.js 가 되겠습니다.

이 외에는 필요한 Brush파일만 설치 하세요..필요한 것이란..하이라이팅을 하고자 하는 언어를 의미합니다.

저의 경우는 csharp, css, javascript, xml, sql 정도 설치 했습니다.

이제 css 를 설치 해보지요.

styles 라는 폴더를 보시고 shCore.css 파일과 맘에 드는 테마 저는 그냥 Default로 했네요.(shThemeDefault.css) 를 설치 합니다.

자 이제 설치한 경로를 해당 페이지에 각각 링크를 걸어 주시고요..

SyntaxHighlighter.config.bloogerMode = true;
SyntaxHighlighter.config.tagName = 'pre';
SyntaxHighlighter.config.strings.help = '?';
SyntaxHighlighter.all();

페이지의 상단에 위와 같이 스크립트 코드를 작성해 주시면 끝....

아주 간단하지요???

그런데 ckeditor에서 이렇게 사용하면 문제가 발생합니다..ㅎㅎㅎ


그래서 플러그인을 설정해 봅니다...

http://code.google.com/p/ckeditor-syntaxhighlight/

위 링크에 가서 플러그인을 받아 봅니다.

다운 받아 압축을 풀고 syntaxhighlight 라는 폴더를 통채로

사이트/ckeditor/plugins/에 복사 합니다.

마지막으로

사이트/ckeditor/config.js 파일을 열어서 아래와 같이 고칩니다.

CKEDITOR.editorConfig = function(config) {
    config.extraPlugins = 'syntaxhighlight';        //Add the plugin   
    config.toolbar_Full.push(['Code']);  //add the plugin button to the full toolbar
};

이렇게 세팅을 하면 끝...은 아니고요..

이렇게 세팅하면 에디터의 맨 마지막에 코드라는 아이콘이 생성됩니다.

그러나 열어 보면 아시겠지만..엄청나게 많은 언어들을 지원하지요..

그러냐 여기서 세팅한 언어는 딸랑 5개뿐..(shBrush 파일)

그러므로 이부분을 제거해 주어야 합니다.

사이트/ckeditor/plugins/syntaxhighlight/dialogs/syntaxhighlight.js 파일을 엽니다.

코드 최소화가 되어 있는 상태입니다. 스크롤바를 오른쪽으로 쭈욱 당기면서...코드의 나열을 찾아 봅니다.

귀찮으신 분들은..C# 으로 찾아 보시길..^^;

대략 아래와 같은 구조로 되었네요.

[["C#", "csharp"], ["CSS", "css"], ["Javascript", "jscript"], ["SQL", "sql"], ["XML/XHTML", "xml"]]

자 불필요한 것을 지워 버리면 끝..

즐겁게 사용하시길...


마지막 업데이트 : (9/15/2010 2:40:00 PM)




Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

ckeidtor 및 ckfinder 세팅하기

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (7/30/2010 4:21:58 PM) Viewing : 5484

이전 사이트에서는 FCKEDITOR를 사용하였지만.
이번에 리뉴얼 하면서 CKEDITOR로 변경하였습니다.
이름을 보면 금방 알아 차리겠지만..동일제품입니다..ㅋ~ 버전업이 된것이지요..
시대의 트랜드에 맞게 jquery 로 무장하였구요..뭐 기존 버전보다 딱 보기에도 좋아 보이네요..ㅡ.ㅡ;;;

네이년에서 검색해 보아도 CKEDITOR 세팅법은 쫌 나오는 군요..
물론 원 배포 사이트에서 보아도 설명이 잘되어 있지만..(영어의 압박을 빼면말이죠..^^;)
ckeditor는 글을 쓰기 위한 에디터이구요 ckfinder는 업로드된 파일(이미지나 플래시 등등)을 관리하는 툴이 되겠습니다.
먼저 설치 하기 위해서는 CKEDITOR와 CKFINDER가 필요합니다.
 
 
위 링크에서 모두 구하실수 있습니다..물론 닷넷 버전을 받아야 겠지요..
음.. 또 버전없이 되었군요..제 사이트에서 설치된 버전이 3.2 (2010년 07월 30일 기준)입니다만..현재 3.3.1버전이 나왔군요..
뭐 불편한 점 없기에 그냥 쓸랍니다..3.4에 대한 내용도 얼핏 보입니다만..그때가서 생각하도록 하지욥.
어쨋든 다운로드를 받았으면 세팅을 해야 겠지요..
루트경로 바로 아래에 ckeditor 폴더와 ckfinder 폴더를 위치 시킵니다..규칙입니다..^^;;
이제 js파일을 프로젝트에 참조 시켜야 겠지요...
 
<script type="text/javascript" src='<%=this.Url.Content("~/ckeditor/ckeditor.js")%>'></script>

<script type="text/javascript" src='<%=this.Url.Content("~/ckfinder/ckfinder.js")%>'></script>

<script type="text/javascript" src='<%=this.Url.Content("~/ckeditor/adapters/jquery.js")%>'></script>
위 코드는 MVC 프레임워크로 개발했기 때문에..this.Url.Content 라는 메서드가 있는 겁니다..착오 없으시길..
이제 게시물을 쓰는 페이지(이 사이트의 경우에는 /Views/Article/Add.aspx - MVC로 개발했기 때문에 URL이 다릅니다 착오 없으시길..)에 textarea 컨트롤에 에디터를 세팅해줍니다.
 
<%= this.Html.TextAreaFor(m => m.Content) %>

<script type="text/javascript">
    var editor = CKEDITOR.replace('Content');
    CKFinder.SetupCKEditor(editor, '/ckfinder');
</script>
위 코드에서 textarea 컨트롤의 이름은 Content 입니다. MVC가 아닌 것으로 개발하게 되면 ClientID를 입력하여야 겠지요?
여기까지 하면 일단 게시물작성 페이지에서 에디터를 볼수가 있습니다.
이제 ckfinder/bin 폴더의 ckfinder.dll을 /bin 에 복사 합니다. ckfinder/bin은 지우셔도 됩니다. 그리고 프로젝트에서 참조추가 하십시오.
기본적으로 업로드파일의 경로는  /ckfinder/userfiles/ folder 로 되어 있지만..아무도 그렇게 사용하지는 않겠지요??
이 사이트의 경우에는 /Upload 입니다.
/Upload 아래에 _thumbs, files, flash, images 폴더를 생성합니다. 그런데..저는 files는 에디터에서 사용하지 않습니다..
바로 아래에 파일첨부 항목에서 첨부 하면 그쪽으로 들어 가도록 세팅되었습니다..뭐 이건 중요한게 아니고..ㅡ.ㅡ;
이제 중요한 권한 설정(fckeditor에서는 이부분이 취약하였습니다만..ckeditor는 만족스럽습니다.)
/ckfinder/config.ascx 파일이 손을 봐야 하는 가장 중요한 파일입니다..권한을 담당하지요..
 
public override void SetConfig()
{
    LicenseName = "http://www.Bangsil.net";
    LicenseKey = "http://www.Bangsil.net";

    BaseUrl = "/upload/";

    BaseDir = "";

    Thumbnails.Url = BaseUrl + "_thumbs/";
    Thumbnails.Dir = BaseDir + "";
    Thumbnails.Enabled = true;
    Thumbnails.DirectAccess = true;
    Thumbnails.MaxWidth = 100;
    Thumbnails.MaxHeight = 100;
    Thumbnails.Quality = 80;

    Images.MaxWidth = 1600;
    Images.MaxHeight = 1200;
    Images.Quality = 80;

    CheckSizeAfterScaling = true;

    ForceSingleExtension = true;

    HtmlExtensions = new string[] { "html", "htm", "xml", "js" };

    HideFolders = new string[] { ".svn", "CVS" };

    HideFiles = new string[] { ".*" };

    SecureImageUploads = true;

    RoleSessionVar = "CKFinder_UserRole";

    AccessControl acl = AccessControl.Add();
    acl.Role = "*";
    acl.ResourceType = "*";
    acl.Folder = "/";
    acl.FolderView = true;

    acl = AccessControl.Add();
    acl.Role = "*";
    acl.ResourceType = "Images";
    acl.Folder = "/public/";
    acl.FileView = true;
    acl.FileUpload = true;

    acl = AccessControl.Add();
    acl.Role = "*";
    acl.ResourceType = "Flash";
    acl.Folder = "/public/";
    acl.FileView = true;
    acl.FileUpload = true;

    acl = AccessControl.Add();
    acl.Role = "Admin";
    acl.ResourceType = "*";
    acl.Folder = "/";
    acl.FolderView = true;
    acl.FolderCreate = true;
    acl.FolderRename = true;
    acl.FolderDelete = true;
    acl.FileView = true;
    acl.FileUpload = true;
    acl.FileRename = true;
    acl.FileDelete = true;

    DefaultResourceTypes = "";

    ResourceType type;

    type = ResourceType.Add("Images");
    type.Url = BaseUrl + "images/";
    type.Dir = BaseDir == "" ? "" : BaseDir + "images/";
    type.MaxSize = 3000000;
    type.AllowedExtensions = new string[] { "bmp", "gif", "jpeg", "jpg", "png" };
    type.DeniedExtensions = new string[] { };

    type = ResourceType.Add("Flash");
    type.Url = BaseUrl + "flash/";
    type.Dir = BaseDir == "" ? "" : BaseDir + "flash/";
    type.MaxSize = 3000000;
    type.AllowedExtensions = new string[] { "swf", "flv" };
    type.DeniedExtensions = new string[] { };
}
먼저 6행의 BaseUrl 속성에 업로드 경로를 입력합니다. 앞서 말했듯이 이 사이트의 경로는 /Upload가 되겠습니다. 코드를 보면 알겠지만 그 다음부분은 섬네일의 설정입니다. 34행은 역할에 사용할 세션변수의 이름을 설정하는 부분입니다.. 위 코드의 값은 기본값입니다..저는 그냥 기본값 사용합니다.
이제 주목해야 할 부분은  36행의 AccessControl 입니다.
이게 바로 권한의 설정 부분이 되겠습니다.
권한 설정은 역할에 따라 설정하게끔 되어 있습니다.
이 사이트의 역할은 Admin, User, Anonymous 및...등등 을 사용하고 있습니다만..여기서는 이 세가지만 다룹니다..^^;;
모든 역할은 모든 리소스타입(파일형식이 되겠습니다.)에 대해 뷰 권한이 있습니다.
모든 역할은 이미지형식에 대해 /public/ 경로(실제 경로는 /Upload/Images/public/ 이 됩니다..중요..)에 대해 파일 조회 권한과 업로드 권한을 가집니다.
모든 역할은 플래시형식에 대해 /public/ 경로(실제 경로는 /Upload/Images/public/ 이 됩니다..중요..)에 대해 파일 조회 권한과 업로드 권한을 가집니다.
관리자 역할은 모든 리소스타입에 대해 폴더조회, 폴더 생성, 폴더리네임,폴더 삭제, 파일조회, 파일업로드,파일리네임,파일삭제의 권한을 가집니다.
이해 되십니까????
이제 73행 부터 마지막으로 리소스의 형식에 대해서 정의 합니다.
AccessControl에서 설정하였던 Images 라는 이름을 가진 리소스는 바로 여기서 정의 됩니다.
이제 인증 여부 및 역할에 대해서 설정해야 합니다..
같은 페이지의 CheckAuthentication 메서드를 보겠습니다.
 
public override bool CheckAuthentication()
{
    if (this.Request.IsAuthenticated)
    {
        if (this.Context.User.IsInRole("Admin"))
        {
            this.Session["CKFinder_UserRole"] = "Admin";
        }
        else
        {
            this.Session["CKFinder_UserRole"] = "User";
        }
    }
    else
    {
        this.Session["CKFinder_UserRole"] = "Anonymous";
    }
   //return this.Context.User.Identity.IsAuthenticated;
    return true;
}
원본에는 18행 처럼 되어 있지만..우리는 역할별 권한을 할당하여야 하기에..위 코드 처럼 변경하여야 겠지요?
따로 설명이 필요 없을듯 합니다.
이제 마지막으로 에디터의 세팅이 남았는데..
저의 경우는 그냥 기본설정을 사용하였습니다..ㅡ.ㅡ;;;
설정을 변경하고픈 분들은 ...http://docs.cksource.com/CKEditor_3.x/Developers_Guide 에서 configuratinon 부분을 참고하여 게시물 작성 페이지에서 직접 설정 코드를 입력하시거나.. /ckeditor/ckeditor.js 파일에서 찾아서 수정하시면 되겠습니다.
간단하니...설명은 생략합니다..

마지막 업데이트 : (9/15/2010 2:30:04 PM)

TAG : editor 



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

SandCastle을 이용하여 주석 도움말을 만들어 보자

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (7/26/2010 3:46:46 PM) Viewing : 3161

이 글을 예전에 썼던 XML 주석의 문서화 (NDOC , SandCastle) 이 글에 추가 된 글로 보면 되겠습니다.
먼저 도움말을 만들기 위해서는 그에 대한 조건이 충족되어야 합니다.

가장 중요한 것이 xml 형태의 주석을 코드 상에 아주 잘..달아야 합니다..^^(당연하겠지만.)
XML 주석을 다는 것은 아래 링크를 참고 하십시오.

이 규칙이 지켜져야 합니다..^^;

 
 
참고로 주석을 도와주는 유명한 툴이 있지요..GhostDoc 이라고.. 이툴은 선택 조건이 되겠습니다.
자 이제 주석을 잘 달았으면 빌드해서 오류가 없어야 겠지요?
빌드 하기 전에 잠깐...^^;
VS에서 빌드 하기 위한 프로젝트를 선택하고 빌드 탭을 선택합니다.
아래쪽에 보면  XML문서 파일 이라고 있습니다.
이것을 활성화 하고 빌드해 봅니다.
이제 output 경로에 xml 파일도 컴파일된 것을 눈으로 확인할 수 있습니다.
이제 소스는 준비가 완료 되었습니다.
이제 이것으로 도움말을 만들어 봅시다.

필요한 물건은 망치와 못...이 아니라..ㅡ.ㅡ;
Sandcastle
Sandcastle Help File Builder 라는 놈입니다.
각각 해당 링크에서 다운 받을수 있습니다.
그리고 htmlhelp1로 생성할 경우 (흔히들 알고 있는 .chm 확장자의 도움말 파일을 칭합니다.)
htmlhelp
라는 놈도 다운 받으셔야 합니다.
처음 썼든 아티클이 3년전이니까..참..그기간에 이 툴들도 많이 변했군요..^^;;
성격 급하신분들..일단 다운 받아서 설치부터 해 봅니다.
순서는 sandcastle 만 먼저 설치 하면 나머지는 알아서..하십시오.
이전 아티클에서는 영문 VS만 된다고 하였는데..지금은 한글VS도 되는 군요..완전 사랑해..^^;
그러나 제한도 약간 있습니다..OTL
이에 대해서는 옵션 설명하면서 설명 하도록 하지욥.

자 이제 Sandcastle Help File Builder GUI 응용프로그램을 실행해 봅니다.
화면의 오른쪽 부분에 Project Explorer 라는게 보입니다.
Documentation Sources에서 ContextMenu를 띄워보면 Add Documentation Sources라는 메뉴가 보입니다.
이제 도움말을 생성할 xml 파일만을 선택하십시요..
그럼 자동으로 원본 dll도 포함이 됩니다..
이제 설정을 해봅시다.

왼쪽 화면의 Project Properties 에서 속성들을 설정합니다.
HelpFileFormat 을 HtmlHelp1로 합니다. 다른 것은 직접 해 보시기 바랍니다..^^;
 
Comments 섹션에서 NamespaceSummaries를 주목하세요.
클릭하면 새로운 팝업이 활성화됩니다.
친절하게 설명이 되었네요..
Checked namespaces will appear in the help file. Unchecked namespaces will not.
SHFB(Sandcastle Help File Builder)를 이용해서 몇번 빌드를 해본사람은 알겠지만.
각 클래스 및 멤버에는 주석을 달 수 있지만..네임스페이스에다가는 주석을 달수 없습니다..
이 팝업은 바로 네임스페이스에 주석을 달아주는 기능을 담당합니다.
주석을 추가할 네임스페이스를 선택하고
Edit the summary for the selected namespace. 아래 TextBox에 xml 주석을 입력하면 되겠습니다.
그리고 모두 작성한 후 그냥 Close 하면 됩니다.
 
Help File 섹션에서
Header및 Footer등등을 설정합니다.
Language를 영어(미국)으로 합니다.ㅡ.ㅡ;
한글로 하게 되면...음..직접 빌드 해보시기 바랍니다..^^;;;;;
PresentationStyle은 입맛에 맞게 설정하세요..
참고로 저는 vs2005가 무난하더군요..ㅋ~
 
Paths 섹션에서는 OutputPath..아시죠?? 컴파일완료된 도움말이 위치할 경로입니다.
SandcastlePath 는 Sandcastle이 설치된 경로가 되겠지요.
기본으로 설치 하였다면 C:\Program Files\Sandcastle\ 가 됩니다.
 
Show Missing Tags 섹션은.
xml 주석이 있어야 하는 부분에 존재 하지 않을 경우 Missing 이라는 시뻘건 문자를 보여 줄것인가에 대한 설정입니다.
모두 false로 하면 좋겠지만..그렇게 되면 어디서 누락되었는지 눈에 띄지 않겠지요...?
최종 배포 시에만 false 로 하시면 되겠네요.
 
Visibility 섹션은..도움말에 보여줄 한정자의 설정이 되겠습니다.
기본적으로 private은 보여줄 필요가 없을듯 하고요..
아니면 보여 주어도 되고요..
중요한것은 apiFilter ...이 놈입니다.
이것을 클릭 하게 되면..하나의 팝업이 뜹니다.
왼쪽 화면에서는 모든 참조된 네임스페이스가 보이고 체크박스가 보이지요.
오른쪽 화면에서는 개체형식과 한정자 등등이 섞여서 보여지네요.
이 화면에서는 특정 어셈블리를 활성화 또는 비활성화 할 수 있으며
또한 어셈블리 안에서 각 멤버 활성화 비활성화 설정을 할 수 있습니다.
즉 보여주고 싶은 것만 보여 줄수 있는 게 되겟죠.
웹프로젝트의 경우 웹페이지의 멤버(메서드나 이벤트등등)는 굳이 보여질 필요가 없다고 생각합니다만...^^;
어쨋든 필요한 기본 설정은 완료 되었습니다.
이제 빌드를 해봅시다..^^;
추가된 어셈블리의 수에 따라 천차만별이겠지만..시간이 꽤 걸립니다..^^;
빌드가 실패하였다면 log를 분석해 보시기 바랍니다..
저한테 물어 보지 마세욤..ㅡ.ㅡ;;;;
다음에는 스샷도 좀 첨부 해보도록 하지욤..ㅡ.ㅡ;;;

마지막 업데이트 : (9/15/2010 2:30:56 PM)

TAG : SandCastle 주석 



Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

리소스(resources)를 통합 관리 해보자.

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (8/19/2008 10:43:15 AM) Viewing : 5716

리소스는 참 관리 하기 어려운 존재이다.

기본 적으로 VS 에서는 하나의 어셈블리마다 각각의 리소스를 사용할 수 있으며 파일명을 가지고 culture를 구분하여 동적으로 런타임시에 해당 리소스를 바인딩 하는 형식이 되겠다.

그러나 하나의 솔루션에 속하는 프로젝트가 많아 지다 보면 각각의 프로젝트에 속한 리소스를 관리하기가 여간...만만치않다.

나도 역시 이 문제 때문에 고민을 하다가 약간은 조잡할지 모르나 나름구성을 해보았다.

먼저 사용할 리소스의 형태는 확장자가 resX인 XML 형태와, 확장자가 resources 인 바이너리형태 , 2가지가 있다.
리소스를 작성하기 위해서는 IDE에 내장되어 있는 리소스 편집기를 이용하여도 상관 없으나 따로 Resourcer.NET 이라는 무료 도구를 이용하도록 하겠다.
사용법은 간단하니..pass 하도록 하겠다.

샘플프로젝트구조

샘플 프로젝트의 구조는 다음과 같다.
먼저 리소스를 관리할 BIT.TM.Resources 라는 프로젝트가 있다. 이 프로젝트에는 Proxies 라는 폴더와 Resources 라는 폴더가 있는데 관심있게 살펴 봐야 한다.
이 리소스를 사용할 프로젝트는 Sample 이라는 프로젝트이다. 
일반적으로 리소스는 그것을 사용할 프로젝트에 같이 있어야 하나, 분리를 시켜 독자적으로 관리 하게끔 하였다.
Proxies 라는 폴더와 Resources 라는 폴더에 있는 파일의 네이밍규칙을 살펴 보자.

이 리소스를 사용할 프로젝트의 네임스페이스를 사용하고 있다.
즉  문자열 리소스의 경우 Proxies 클래스의 네이밍룰은 {네임스페이스}.StringProxy.cs 가 되며, 
리소스의 경우 {네임스페이스}.String.{CultureCode(생략가능)}.resources 가 된다.

서두에 언급하였지만 리소스의 형식은 resX가 되었던 resources 가 되었던 상관은 없다.

자.. 이제 코드를 살펴 보자..
먼저 ResourceType 열거형을 살펴 보자.

    ///

    /// 리소스의 타입 열거형 Ver 1.0

    ///

    ///

    /// 2007.12.11 - Prototype - 이방은(http://www.bangsil.net)

    ///

    public enum ResourceType

    {

        ///

        /// 아이콘 타입입니다.

        ///

        Icon,

        ///

        /// 문자열 타입입니다.

        ///

        String,

        ///

        /// 이미지 타입입니다.

        ///

        Image

    }

리소스의 형식을 정의하는 열거형이다.
이제 리소스 파일을 읽어 관리하는 ResourceManager 를 살펴 보자.

   34 public CustomResourceManager(ResourceType resourceType, Type type)

   35 {

   36     bool hasResource = false;

   37     Assembly asm = Assembly.GetCallingAssembly();

   38     string resourceName = this.GetType().Namespace + ".Resources." + type.Namespace + "." + resourceType.ToString();

   39     foreach (string reName in asm.GetManifestResourceNames())

   40     {

   41         if (reName.Substring(0,reName.LastIndexOf('.')) == resourceName)

   42         {

   43             hasResource = true;

   44             break;

   45         }

   46     }

   47     if (!hasResource)

   48     {

   49         throw new MissingManifestResourceException("해당 타입의 리소스를 찾을 수 없습니다.");

   50     }

   51     else

   52     {

   53         rm = new ResourceManager(resourceName, asm);

   54     }

   55 }

생성자를 보게 되면 앞서 정의한 ResourceType열거형과 Type 개체를 받는걸 볼수 있다.
38행을 보게 되면 매개변수로 받은 type 변수로 호출할 어셈블리의 네임스페이스를 알아내고 이를 이용해 리소스 이름을 생성하는 것을 볼 수 있다.

그외 메서드로는

  104 ///

  105 /// 해당 키를 가지고 있는 문자열 타입의 리소스를 반환합니다.

  106 ///

  107 /// 리소스를 호출 할 키입니다.

  108 /// 반환되는 리소스입니다.

  109 internal string GetString(string key)

  110 {

  111     if (key.Length == 0)

  112     {

  113         return null;

  114     }

  115     try

  116     {

  117         return rm.GetString(key);

  118     }

  119     catch

  120     {

  121         return null;

  122     }

  123 }

과 같은 리소스의 값을 반환하는 메서드가 존재한다.

이제 Proxies 개체를 만들어 보도록 하겠다.

    7 namespace Sample

    8 {

    9     ///

   10     /// 문자열 리소스 Proxy 클래스 Ver 1.0

   11     ///

   12     /// 2007.12.11 - Prototype - 이방은(http://www.bangsil.net)

   13     public class StringProxy

   14     {

   15         private static CustomResourceManager rm;

   16

   17         ///

   18         /// 클래스의 정적 생성자입니다.

   19         ///

   20         static StringProxy()

   21         {

   22             rm = new CustomResourceManager(ResourceType.String, typeof(StringProxy));

   23         }

   24

   25         public static string TestString

   26         {

   27             get { return rm.GetString("TestString"); }

   28         }

   29     }

   30 }

주의 할 것은 이 프락시 클래스의 네임스페이스이다.
네임스페이스를 보게 되면 이 클래스가 존재하는 어셈블리의 이름(BIT.TM.Resources)이 아니고 이 클래스를 사용할 어셈블리의 네임스페이스가 등록된다.
그리고 정적 생성자에서 조금 전에 설명했던 CustomResourceManager 개체를 만들고 호출할 리소스의 키를 Property로 제공하기만 하면 된다.

이미지 프락시의 경우는 아래와 같다.

    8 namespace Sample

    9 {

   10     public class ImageProxy

   11     {

   12         private static CustomResourceManager rm;

   13

   14         ///

   15         /// 클래스의 정적 생성자입니다.

   16         ///

   17         static ImageProxy()

   18         {

   19             rm = new CustomResourceManager(ResourceType.Image, typeof(ImageProxy));

   20         }

   21

   22         public static Image TestImage

   23         {

   24             get { return rm.GetImage("TestImage"); }

   25         }

   26     }

   27 }

자 이제 리소스는 모두 정의 되어 있으니 이것을 사용하는 코드만 남았다.

Sample 프로젝트는 비즈니스계층으로 이 리소스를 사용하는 곳이 되겠다.

    8     public class Sample

    9     {

   10         public static string GetString()

   11         {

   12             return StringProxy.TestString;

   13         }

   14

   15         public static Image GetImage()

   16         {

   17             return ImageProxy.TestImage;

   18         }

   19     }

간단하게 위 처럼 정의해 보았다.
이제 이 개체를 Culture를 변경시켜 보여주도록 하기위에 폼단에서 코드를 손을 본다.

   19 private void Form1_Load(object sender, EventArgs e)

   20 {

   21     this.label4.Text = Sample.Sample.GetString();

   22     this.pictureBox1.Image = Sample.Sample.GetImage();

   23

   24     Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");

   25     this.label3.Text = Sample.Sample.GetString();

   26 }

20행과 21행은 한글버전이므로 
Sample.String.resources와 Sample.Image.resources 파을일 읽게 될 것이며
24행의 Culture변환으로 인해
25행의 경우에는 영문버전이 되므로
Sample.String.en.resources를 읽게 된다. 
그 결과는 아래와 같다.

실행결과

나름대로 짱구를 굴려 보았지만..현재까지는 이정도가 한계인듯 하다.
리소스 관리에 대해 더 좋은 의견이 있다면 
언제든 환영........


마지막 업데이트 : (9/15/2010 2:41:56 PM)

TAG : 리소스 resource 



첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기



<< < 1 2 3 > >>