• 구성 요소
    1. WSS 3.0 / MOSS Server
    2. SPTimer Service
    3. SMTP Service
    4. Active Directory management service
    5. AD의 특정 OU에 대해서 충분한 권한이 있는 사용자 계정(최소:읽기 권한 이상)

 

  • 받는 전자 메일에 대한 소개
    1. List와 Library에 E-mail 메시지와 첨부 파일을 저장할 수 있다.
    2. 사용자의 SharePoint Document Library에 문서를 업로드 할 수 있다.
    3. List와 Library에 특정 E-mail 주소를 가질 수 있다.

 

  • SMTP 구성

    서버구성

    1. 비록 우리는 Exchange Server가 있지만, SharePoint Farm의 Web Front End Server에 SMTP 서비스를 설치해야 한다. SMTP 구성 요소를 SharePoint Server에 설치하였다면, SharePoint Timer Service에서 E-mail과 첨부파일을 가져올 것이다.
    2. SharePoint Server에 SMTP 서비스를 설치했을 때, SMTP 서비스 가상 서버에서 새로운 도메인이 생성될 것이다. 수동으로 구성할 필요는 없지만, 진행에 앞서, 몇 가지 검사 할 게 있다.
    3. 실행 > inetmgr(인터넷 정보 관리자) 명령어를 입력 > 기본 SMTP 가상 서버 > 도메인 > 도메인명(이후 가정하에 진행:MOSS.com) > 속성창을 연다. SharePoint Timer Service에서 가져갈 E-mail이 저장되어 있는 C:\Inetpub\mailroot\Drop(기본 위치) 폴더 위치로 지정 되어 있는지, 드롭 디렉토리를 확인한다. SharePoint Timer Service에서 해당 폴더를 매일 5분(기본) 체크할 것이다. 그리고 C:\Inetpub\mailroot\Drop 폴더에 보안 수준을 체크하며, WSS_ADMIN_WPG 로컬 그룹에 모든 권한이 부여한다.

    1. SMTP 가상 서버 등록 정보 설정
  • 속성 페이지에 액세스 탭을 선택한 후, 액세스와 릴레이에 대해 IP를 추가한다.
     
  • SMTP 서버 IP 와 Exchange 서버 IP 주소에 대해 허가됨을 추가한다.

클라이언트 구성

  1. E-mail 클라이언트와 클라이언트 컴퓨터는 모든 Windows 운영 체제 중인 MS Outlook 또는 Outlook Express으로 SharePoint 목록에 E-mail 보낼 있다.
  2. Outlook Express 실행 > 계정 추가

    표시 이름 입력

    전자 메일 주소 입력

    받는 메일 서버 유형 POP3 선택

    받는 메일 서버와 보내는 메일 서버 입력 (예: MOSS.com)

    계정 이름 및 암호 입력

    NOTE

    POP3 서버 접속 실패할 수 있는데, Sharepoint Server에 POP3 서비스가 아닌 유일한 SMTP 서버를 구성하였기에, 이를 무시해도 좋다. 받는 전자 메일 SMTP 서버 구성에는 충분하다.

     

테스트

Outlook Express를 열어 메일을 작성한 후 보내면 드롭 디렉토리에 .eml파일이 저장되는 것을 볼 수 있다.

  • 받는 전자 메일 사용 : 예
  • 설정 모드 : 자동
  • 디렉토리 관리 서비스 : 아니오
  • 받는 전자 메일 서버 표시 주소 : Moss.com
  • 안전한 전자 메일 서버 : 모든 전자 메일 서버에서 오는 메일 수락

 

리스트 설정

  1. Sharepoint 사이트에 리스트(공지사항으로 진행)를 생성한다.
  • 라이브러리 형태에 따라 설정 부분이 조금씩 달라진다.
  1. 리스트 설정에 받는 전자 메일 설정을 한다.
  • 받는 전자 메일 사용 : 예
  • E-mail 주소 입력
  • 전자 메일 첨부 파일 저장 여부 : 예
  • 원본 전자 메일 저장 여부 : 예
  • 전자 메일로 모임 초대 여부 : 예
  • 전자 메일 보안 정책 : 모든 보낸 사람의 전자 메일 메시지 수락

테스트

  1. 첨부 파일과 함께 이메일 발송(예:test@moss.com)한다.
  2. 드롭 디렉토리에 .eml 파일이 생성된 것을 확인한다.
  3. Sharepoint 타이머 서비스에서 .eml를 가져가며, 리스트에 저장한다.
  • Exchange Server 구성
    1. Exchange 관리 콘솔 > 조직 구성 > 허브 전송
    2. SMTP에 대한 송신 커넥터를 추가한다.
  • 송신 커넥터명 입력, 송신 커넥터에 저장할 용도 선택

  • 주소 공간 입력(SMTP 주소입력 => 예:moss.com)
  • 모든 하위 도메인 포함 체크

  • 네크워크 설정

    다음 스마트 호스트를 통해 메일 라우팅 선택

    스마트 호스트 추가한다.(MOSS 서버 IP주소:SMTP)

  • 스마트 호스트 인증 설정 구성 (없음 선택)

  • 원본 선택 후, 새 커넥터를 생성한다.

  1. 고급 SharePoint 구성
    1. 소개
  • Active Directory 및 Sharepoint 서비스 계정에 대한 권한을 위임 제어 옵션을 이용하여 새로운 조직 구성 단위를 만들어 관리한다.
  1. AD에 새로운 OU를 만든다.
  2. 중앙 관리 사이트 > 작업 > 받는 전자 메일 설정

    (http://ServerName:Port/Admin/IncomingEmail.aspx)

  3. 테스트는 기존 위 방식과 같으나, 체크할 항목이 하나 있다.
  • AD에서 OU를 체크하는데, 받는 전자 메일에 설정한 메일 주소가 연락처에 추가된 것을 볼 수 있다.

 

 

원본 http://blogs.msdn.com/selvagan/archive/2008/01/26/incoming-email-configuration-moss.aspx


CAML Query로 Date 및 Time 를 쿼리할 때가 있다.
U2U CAML tool 이용할 경우, 지원이 되지 않아,
쿼리문에 IncludeTimeValue=\"TRUE\" 를 추가하면 된다.

 System.Text.StringBuilder QueryBuilder = new System.Text.StringBuilder();
QueryBuilder.Append(""); 
QueryBuilder.Append("  "); 
QueryBuilder.Append("    "); 
QueryBuilder.Append("    " + SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now.AddDays(10)) + ""); 
QueryBuilder.Append("  "); 
QueryBuilder.Append("");


특수문자 (Special Characters)
 
예약문자 | 그리스문자 | 기호 & 부호 | 화학기호 | 수학기호

--------------------------------------------------------------------------------

 
XML 예약문자
<, >, &는 XML tag 표시와 entity를 표시하는 XML 예약문자로, XML 문서에 그대로 사용할 수 없다.
 
< (less-than sign) &lt;
> (greater-than sign) &gt;
& (ampersand) &amp;


그리스문자
그리스 문자는 풀어서 사용한다.
 
α alpha
β beta
γ gamma
δ,Δ delta
ε epsilon
ζ zeta
η eta
θ theta
ι iota
κ kappa
λ lambda
μ micron
ν nu
ξ xi
ο omicron
π pi
ρ rho
σ, Σ sigma
τ tau
υ upsilon
φ phi
χ chi
ψ psi
ω, Ω omega


기호 & 부호
≤ &lt; or =
≥ &gt; or =
± +/-
˚ degrees
℃ degrees C
→ --&gt;
㎍, μG microgram
㎕, μL microliter
㎛, μM micrometer
® (R)
™ (TM)
χ2 chi─square


화학기호
화학기호는 윗첨자나 아랫첨자를 지정하지 않고 그대로 입력한다.
 
K+ K+
Cl- Cl-
Mg2+ Mg2+
CO2 CO2
H2O H2O


수학기호
수학기호는 윗첨자나 아랫첨자를 괄호 "( )" 안에 넣어서 입력한다.
 
102 10(2)
10-2 10(-2)
height2.239 height(2.239)


로또 복권의 역대 최다 1등 당첨 번호는 '1'과 '37'인 것으로 7일 분석됐다.

기획재정부 복권위원회는 로또 1회부터 342회차까지 당첨 번호를 분석한 결과 1등에 '1' 또는 '37'이 포함된 경우가 67번에 달했다고 밝혔다.

즉 '1'과 '37'은 평균 5번에 1번 정도가 1등 당첨 번호에 들어간 셈이다.

'17'이 1등 당첨 번호에 들어 있는 경우가 64번에 달했고 '4', '19', '39'가 61번, '2'가 60번, '3', '34'가 59번, '27', '33', '36', '43'이 58번이었다.

이어 '35', '42'가 57번, '14', '45'가 56번, '18'이 55번, '7', '8', '20'이 54번 순이었다.

'5', '21, '25'는 53번, '6' '11', '13, '16', '26', '31', '40'은 52번, '10','32', '38'은 50번, '30'은 49번, '15', '24', '44'는 48번이었다.

올해 상반기 최다 1등 당첨액은 320회차의 55억1천300만원이었다.

한편 복권위는 거액이 당첨될 경우 시간을 가지고 손익과 우선 순위를 생각하라고 당부했다.

복권위는 복권 당첨 행동수칙을 통해 최소 3개월 동안 당첨금에 손을 대지 말고자산 관리 계획을 충분히 세우고 나서 회계사, 자산관리사, 투자전문가, 재산관련 변호사에게 자문을 구할 것을 주문했다.

'Misc' 카테고리의 다른 글

Music Program  (0) 2009.11.13
Cannon 7D 공식 발표!!  (0) 2009.09.02
소녀 시대 사진  (2) 2009.07.14
에비앙의 "롤러스케이트 타는 아기들"  (0) 2009.07.12
SBS 수목드라마 "태양을 삼켜라"  (2) 2009.07.07

몇일전에 워크플로 진행 상태에 따른 아이템에 대한 권한 변경을 이벤트리시버를 통해
변경되도록 개발 진행한적이 있다.

이와 같이 MOSS를 개발하게 되면, 권한 변경을 프로그램상으로 개발해야 하는 경우가 많을 것이다.
그래서 이번 기회에 리스트 아이템에 대한 권한 변경 모듈을 정리해 보려 한다.

아래 소스는 작성자에게는 기본 참가 그룹이 아닌 사용 수준 정의를 추가한 참가 그룹(특정 권한 뺌)을,
특정 관리자 그룹에게는 모든 권한을 부여하는 소스이다.
            SPPrincipal spPrincipal = null;
            SPRoleAssignment spRoleAssignment = null;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite spSite = new SPSite(properties.WebUrl))
                using (SPWeb spWeb = spSite.OpenWeb())
                {
                    spWeb.AllowUnsafeUpdates = true;

                    SPList spList = spWeb.Lists[properties.ListId];
                    SPListItem spListItem = spList.Items.GetItemById(properties.ListItemId);

                    try
                    {
                        // 사용 권한 수준 정의 (관리자, 참가 권한)
                        SPRoleDefinition spAdminRoleDef = spListItem.Web.RoleDefinitions.GetByType(SPRoleType.Administrator);
                        SPRoleDefinition spConRoleDef = spListItem.Web.RoleDefinitions[strContributorRoleDefName];

                        // #1. 권한 상속 여부 체크
                        if (!spListItem.HasUniqueRoleAssignments)
                        {
                            // 권한 상속을 푼다.
                            spListItem.BreakRoleInheritance(false);
                        }

                        // #2. 작성자 권한 부여
                        int authorSiteID = int.Parse(spListItem[SPBuiltInFieldId.Author].ToString().Split(new string[] { ";#" }, StringSplitOptions.RemoveEmptyEntries)[0]);
                        SPUser spAuthorUser = spListItem.Web.AllUsers.GetByID(authorSiteID);

                        spPrincipal = spAuthorUser as SPPrincipal;
                        spRoleAssignment = new SPRoleAssignment(spPrincipal);
                        spRoleAssignment.RoleDefinitionBindings.Add(spConRoleDef);
                        spListItem.RoleAssignments.Add(spRoleAssignment);


                        // #3. 관리자 그룹 권한 부여

                        // 관리자 그룹에 대해 관리 권한을 정의한다.
                        SPGroup spAdminGroup = spListItem.Web.Groups[strManageGroupName];
                        spPrincipal = spAdminGroup as SPPrincipal;

                        try
                        {
                            // 해당 SPPrincipal 에 대해 만족하는 RoleAssignment이 없을 경우, 바로 Exception 발생
                            spRoleAssignment = spListItem.RoleAssignments.GetAssignmentByPrincipal(spPrincipal);
                        }
                        catch { spRoleAssignment = null; }

                        // 관리 그룹에 대해 관리 권한이 부여되어 있지 않거나, 그룹추가가 안되어 있을 경우
                        if (spRoleAssignment == null || (spRoleAssignment != null && !spRoleAssignment.RoleDefinitionBindings.Contains(spAdminRoleDef)))
                        {
                            spRoleAssignment = new SPRoleAssignment(spPrincipal);
                            spRoleAssignment.RoleDefinitionBindings.Add(spAdminRoleDef);
                            spListItem.RoleAssignments.Add(spRoleAssignment);
                        }
                    }
                    catch (Exception ex)
                    {
                        this.LogWrite("UpdateAuthorRole의 ItemAdded 이벤트 실행중 오류가 발생하였습니다.", ex.Message);
                        spListItem.ResetRoleInheritance();
                    }

                    spListItem.SystemUpdate(false);

                    spWeb.Update();
                    spWeb.AllowUnsafeUpdates = false;
                }
            });

After Service Pack 1 and the inherent security improvements that had been implemented you may find yourself having issues with SharePoint Designer workflows kicking off automatically.  One way that we have found around that issue is setting workflows in a list / library that you know will have that issue to manual start only and register a custom event handler on that list for ItemAdded or ItemUpdated to manually kick off the workflow through code.

 

That in itself is a nice workaround, but what if you wanted to kick off a workflow using another users context, but you don’t want to store credentials or any other pesky security information in your code?

 

In this specific scenario we created a workflow service account that we wanted to use to kick the workflow off on a form library where items were being submitted through InfoPath Forms Services (and because these workflows were creating, updating, and looking inside other lists that we needed to set security we only needed to do it for this one service account).  Here is a bunch of code:

 

//Set variables from web.configstring _workflowUser = ConfigurationSettings.AppSettings["WorkflowUser"]; //Example:DOMAIN\Administratorstring _workflowName = ConfigurationSettings.AppSettings["WorkflowName"]; //Example:Master Workflowstring _formsLibrary = ConfigurationSettings.AppSettings["FormsLibrary"]; //Example:Request LibrarySPSecurity.RunWithElevatedPrivileges(delegate(){     //Setting variables to use under workflow service account     string userName = properties.UserLoginName;     int itemID = properties.ListItemId;     SPWeb parentWeb = properties.OpenWeb();     SPList parentList = parentWeb.Lists[_formsLibrary];     string targetUrl = parentWeb.Url;     SPUser workflowUser = parentWeb.AllUsers[_workflowUser];     //Open site as workflow service account     SPSite site = new SPSite(targetUrl, workflowUser.UserToken);     site.AllowUnsafeUpdates = true;     //Open web as workflow service account     SPWeb web = site.OpenWeb();     web.AllowUnsafeUpdates = true;     //Get Item object as workflow service account     SPList formsLibrary = web.Lists[_formsLibrary];     SPListItem item = formsLibrary.GetItemById(itemID);     //Getting workflow information     SPWorkflowAssociation workflowTemplate = formsLibrary.WorkflowAssociations.GetAssociationByName(_workflowName, System.Globalization.CultureInfo.CurrentCulture);     //Getting workflow Manager to start workflow     SPWorkflowManager mgr = site.WorkflowManager;     //Starting workflow as service account     mgr.StartWorkflow(item, workflowTemplate, workflowTemplate.AssociationData);     web.Dispose();     site.Dispose();     parentWeb.Dispose();});

 

First off I’m getting my variables from my web.config appSettings, you could just as easily set these in a property bag on an SPSite or SPWeb object.  After that, I start running the next few lines in the context of the application pool so that I know I have access for everything I need to populate other variables I will need down the road.  The fun part comes when I open the SPSite site object using the workflowUser.UserToken object.  After that all items that I use the parent site object to obtain is opened up as that workflowUser

Best Practices
다음 과 같이 소스는 메모리를 많이 사용한다고 한다.
그리고 IIS 에서의 리사이클 주기를 짧게 하여 성능 상의 문제를 일으킨다고 한다.
public void GetNavigationInfo()
{
   SPWeb oSPWeb = SPContext.Web;

   // .. Get information oSPWeb for navigation .. 
   foreach(SPWeb oSubWeb in oSPWeb.GetSubWebsForCurrentUser())
   {
      // .. Add subweb information for navigation .. 
    }
}

아래와 같이 Dispose 를 권장한다.
public void GetNavigationInfo()
{
   SPWeb oSPWeb = SPContext.Web;
   foreach(SPWeb oSubWeb in oSPWeb.GetSubWebsForCurrentUser()))
   {
      // .. Add subweb information for navigation ..
      oSubWeb.Dispose();
   }
}
캐쉬 데이타를 사용할 경우에는 Lock 을 하자 아래의 소스 처럼 캐쉬 데이터를 사용할 경우 동 시간대의 접속 자들은 같은 오브젝트에 같은 데이터를 업데이트를 하려고 한다. 이 경우 캐쉬데이타의 깨짐 현상이 일어 날수 있다고 한다.
public void CacheData()
{
   SPListItemCollection oListItems;
   oListItems = (SPListItemCollection)Cache["ListItemCacheName"];
   
   if(oListItems == null)
   {
      oListItems = DoQueryToReturnItems();
      Cache.Add("ListItemCacheName", oListItems, ..);
   }
}
이 현상을 방지 하기 위해서 다음과 같은 locking 처리가 필요하다.
public void CacheData()
{
   DataTable oDataTable;
   SPListItemCollection oListItems;

   lock(this)
   {
      oDataTable = (DataTable)Cache["ListItemCacheName"];
      if(oDataTable == null)
      {
         oListItems = DoQueryToReturnItems();
         oDataTable = oListItems.GetDataTable();
         Cache.Add("ListItemCacheName", oDataTable, ..);
      }
   }
}


워크플로에 대한 구글링을 하다, MS에서 워크플로에 대한 설명을 정리한 문서를 발견하였다.

크게 3분류로

1. WWF(Windows Workflow Foundation)에 대한 설명
2. WSS(Windows SharePoint Service)에 Workflow 접목
3. Office Sharepoint Server 2007에 Workflow 접목

에 대한 설명이 되어 있다.


기사를 보다, 사진이 잘 나온거 같아서
하나 올려본다.ㅋㅋ


SharetPoint 리스트에 워크플로 상태 값을 쿼리 하기 위해,
UI상에 보이는 승인됨, 진행 중 과 같은 값으로 쿼리를 날렸으나,
제대로 값이 나오지 않을 것이다.

워크플로 상태 값을 쿼리 하기 위해서는, 워크플로 상태 코드 값으로 쿼리하면 된다.
아래는 워크플로 상태 코드 값들이다.

진행중(In Progress) : 2
승인됨(Approved) : 16
거절됨(Rejected) : 17
취소됨(Canceled) : 4
에러발생함(Error Occured) : 3


012


요즘 인터넷에서 화제가 되고 있는 에비앙의 광고인 "롤러스케이트 타는 아기들"이다.
기저귀를 찬 아기들이 롤러스케이트를 타며 힙합 묘기를 부리는 모습이 담겨 있다.
이 아기들은 모두 컴퓨터 그래픽으로 창조된 캐릭터라고 한다.
그리고 아기들이 보여주는 묘기 또한 모션 캡처 전문 배우들의 움직임을 컴퓨터 합성하였다고 한다.

 

이 광고는 원래 방송용이였으나, 인터넷에 먼저 공개하기로 결정하여 바이럴 마케팅 전략을 쓰기로 한 것이다.
(소비자들의 주의를 끌어 광고에 자연스럽게 노출되도록 유도하는 최신 기법이라고 한다.)
회사 의도는 적중했고 지난 3일 이후 일주일 동안에 무려 800만 번 이상의 다운로드 회수를 기록할 정도로 폭발적인 인기를 몰고 있다고 한다.

이 동영상 보면 볼수록 너무 웃겨서 자주 보게 된다.

MOSS 권한을 보면 아래와 같은 그림처럼 
모든 권한, 디자인, 계층 구조 관리, 승인, 참가, 읽기 ....등등 
각 사용 권한 수준에 특정 권한이 기본적으로 부여되어 있다.



여기서 필자가 말하려고 하는 것은 특정 권한만이 부여된 사용 권한 수준이 필요 할 경우
그 사용 권한 수준을 어떻게 추가하는지 정리한 항목이다.

우선 관리자(Administrator) 계정으로 로그인하여 사이트 설정에 사용자 및 그룹을 선택하고,
좌측 메뉴의 사이트 사용 권한 항목을 선택한다.
그러면 아래와 같은 화면이 나타날 것이다.



해당 화면에서 폼 메뉴에 설정이라는 항목을 클릭하면 
아래와 같이 사용 권한 수준이 있으며 선택한다.
 


자, 이제부터는 사용 권한 수준 설정 부분이니 잘 보도록 하자.
위 순서대로 잘 진행했다면 아래와 같은 화면이 나타난다.


사용 권한 수준 추가에 대한 페이지 화면이 나타나며,
이름 및 설명 그리고 사용 권한을 부여한 후, 하단의 만들기 버튼을 클릭하면
사용 권한 수준 추가는 끝이 난다.



특정 사용 권한 수준에 대해 복사하고 싶을 경우
사용 권한 수준 화면(바로 위에 위 이미지)에서 사용 권한 수준 이름을 클릭하면
해당 사용 권한 수준 설정이 나타날 것이며,
맨 하단에 보면 사용 권한 수준 복사라는 항목을 클릭하면 된다.



SPList 또는 SPListItem 개체에서 특정 사용자의 특정 권한을 체크해야 할 때가 있다.
금일 특정 권한 체크를 어떻게 해야 하냐는 질문에 바로 대답이 나오지 않아 난감했었다.

무엇을 묻는지도, 무엇을 대답해야 하는지도 아는데,
"DoesUserHavePermissions" 라는 메소드명이 기억나지 않아.
D로 시작하는 권한 체크하는 메소드 있는데 라고만 대답했을 뿐...ㅋㅋ

MOSS 개발 안한지도 4개월쯤 되가나~ 자주 안하니깐 까먹게 되는거 같다.ㅋㅋ
필자도 사람이기에 자주 사용안하는 건 까먹는다. (냠냠~)
그래서 이번 계기로 복습한다 생각에 정리를 해볼까 한다. (누구나 아는 거겠지만)

SPList
개체에서 특정 사용자의 특정 권한을 체크하고 싶을 때 사용하는 방법이다.

아래 소스는 기존에 사용하였던 방식이다.
//특정 그룹에 사용자가 있는지 체크하여 권한 체크
SPList spList = SPContext.Current.Web.GetList(".....");   //List URL
SPGroup spGroup = SPContext.Current.Web.Groups["....."];   //그룹명
if( spGroup.ContainsCurrentUser == true )
{
       // SPList에 글쓰기가 있으니.. 쓰는 권한에 관련된 처리를 여기에..
       ......
}

위 방식을 사용하기 위해서는 특정 그룹을 찾아야 한다는 문제가 있다. 이에 간단하게 해결되는 방법이 있다.

SPList spList = SPContext.Current.Web.GetList(".....");  //List URL

//리스트에 아이템 추가 권한 즉 쓰기 권한이 있는지 체크
if(spList.DoesUserHavePermissions(SPBasePermissions.AddListItems))
{
      // SPList에 글쓰기가 있으니.. 쓰는 권한에 관련된 처리를 여기에..
      ......
}
만일에 여러 권한을 체크해야 할 경우가 있을 것이다. 그럴 경우에는 DoesUserHavePermissions 메소드 안에 SPBasePermissions 항목을 '|' 구분하여 체크하면 된다.
if(splist.DoesUserHavePermissions(SPBasePermissions.AddListItems |
    SPBasePermissions.EditListItems))
{
      ......
}

Visual Studio에서 프로젝트를 소스세이프에 추가 하려고 할 때
아래와 같이 VSS 웹서비스 형식으로 등록하는 화면으로 나올 경우가 있다.
VSS에 로그인하여 추가 하려고 하는데, 이런 화면이 나타나면 당황스럽다.


웹 서비스 형식으로 하고 싶지 않을 경우 설정을 변경해야 한다.

Visual Studio 상단 메뉴를 보면, 도구라는 메뉴가 있는데, 하위 메뉴의 옵션을 클릭한다.


옵션화면에 왼쪽 트리 메뉴를 보시면 소스 제어라는 항목이 있을 것이다.
아래 화면과 같이 설정을 변경하면, 원하는 화면으로 될 것이다.


결과 화면



SBS 수목 새드라마 "태양을 삼켜라"
올인을 쓴 작가가 하는 드라마라고 한다.
출연진도 빵빵하고, 스케일도 큰 드라마인 거 같아
너무 기대되는 드라마



+ Recent posts