보통 ASP.NET 기반의 Web Application을 개발하다 보면, DLL들을 많이 이용하게 되는데,
만일 그 DLL의 일부 코드 수정을 반영 하려면 IIS 서비스를 다시 시작해야 한다.
그래서 보통 IISRESET.EXE 라는 명령어를 이용해 아예 서비스를 내렸다가,
다시 시작하곤 한다.

그러나 단순 DLL의 로직 몇가지 변경 때문에, IISRESET을 하기에는 비용이 비쌀 수 있다.
Web Publishing에 관련 된 대부분의 서비스를 내렸다가 다시 올리는 작업이기 때문에,
Reset 하는 시간도 많이 걸리는데다, IIS를 통해 데이터를 끌어 올리는 비용도 만만치 않다.

이에 IIS 6.0 대 부터는 Application Pool 이라는 것이 있어, 그 Application Pool 만
정리해 주면 새로운 DLL로 올려줄 수 있도록 제공하게 된다.

보통은 INETMGR을 띄워 해당하는 Application Pool 에서 오른쪽 버튼을 클릭해서 재생(혹은 Recycle)을 선택하면 되는데, UI 도구를 사용하는 것이라, 조작이 좀 귀찮긴 하다.


이 작업을 명령줄로 실행하는 방법을 사용하게 되면, 시작 -> 실행 -> cmd 해서 나오는 도스창(명령 실행창)에서 실행되게 만들거나 Batch 파일로 만들면 더욱 편하게 작업할 수 있다.

Recycle 할 때 사용하는 명령 줄은 아래와 같다.

IIS 6.0 : cscript //nologo C:\Windows\system32\iisapp.vbs /a "<웹응용프로그램이름>" /r
     예) cscript //nologo C:\Windows\system32\iisapp.vbs /a "SharePoint - 80" /r

IIS 7.0 : C:\Windows\System32\inetsrv\appcmd recycle apppool /apppool.name:"<웹응용프로그램이름>"
     예) C:\Windows\System32\inetsrv\appcmd recycle apppool /apppool.name:"SharePoint - 80"

728x90

List 템플릿 추가 중에 아래와 같은 오류가 끊임없이 발생하여,

추가 List 템플릿으로 web.Lists.Add(".....", "......", listTemplate) 메소드로 SPList를 추가할 수 없는 경우가 있습니다.

System.Data.SqlClient.SqlException:

테이블 'WSS_Content.dbo.EventReceivers', 'Name' NULL 값을 삽입할 수 없습니다. 열에는 NULL을 사용할 수 없습니다.

INSERT() 실패했습니다.  문이 종료되었습니다.    

 

위치: System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) 
위치: System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj)

위치: System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler,
 SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj)
위치: System.Data.SqlClient.SqlCommand.RunExecuteNonQueryTds(String methodName, Boolean async)
위치: System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result,
 String methodName, Boolean sendToPipe)    

위치: System.Data.SqlClient.SqlCommand.ExecuteNonQuery()    

위치: Microsoft.SharePoint.Utilities.SqlSession.ExecuteNonQuery(SqlCommand command)

 

이 내용을 확인해 본 결과 List Template 안의 Event Add 하는 부분에서 아래와 같은 부분을 확인 할 수 있었습니다.

List Template Element.xml 을 살펴본 결과 아래와 같습니다.

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <!-- 리스트 템플릿 정의부분 -->

  <ListTemplate

        Name="FreeTalk_Board"

        Type="8000"

        BaseType="0"

        OnQuickLaunch="TRUE"

        SecurityBits="12"

        Sequence="392"

        DisplayName="FreeTalk_Board"

        Description="FreeTalk_Board"

        Image="/_layouts/images/itann.gif"       

        />

  <!-- 이벤트 리시버 정의부분 -->

  <Receivers ListTemplateId="8000">

    <Receiver>

      <Name>CollectBoardEventReceivers</Name>

      <Type>ItemAdded</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>

    <Receiver>

      <Name>CollectBoardEventReceivers</Name>

      <Type>ItemDeleting</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>  

  </Receivers>

</Elements>

 

일단  <Receivers> .... </Receivers> 부분에 있는 내용을 모두 삭제해 보고 리스트를 추가해 본 결과,

위의 오류가 발생하지 않았습니다.

이번에 다시 추가해서 적용해 본 결과 오류가 재발하였습니다.

그래서 이번에는 각 Event의 이름을 다르게 적용해 보았습니다.

 

   ....

  <Receivers ListTemplateId="8000">

    <Receiver>

      <Name>FTEventItemAdded</Name>

      <Type>ItemAdded</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>

    <Receiver>

      <Name>FTEventItemUpdated</Name>

      <Type>ItemDeleting</Type>

      <SequenceNumber>50000</SequenceNumber>

      <Assembly>SKT.TSquare.SPS.FreeTalk, Version=1.0.0.0, Culture=neutral, PublicKeyToken=388b774ba96c947e</Assembly>

      <Class>SKT.TSquare.SPS.FreeTalk.CollectBoardEventReceivers</Class>

      <Data />

      <Filter />

    </Receiver>  

  </Receivers>

   ....

 

확인해 본 결과 위와 같이 변경하니, 그 이상의 오류는 발생하지 않았습니다.

그 이후에는 이름이 동일해도 오류가 발생하지 않았습니다.

초기에 리스트 템플릿 상에서 동일한 이름으로 등록할 때 발생되는 오류로 생각됩니다.

728x90
MOSS로 구성한 사이트에, IIS 내 가상 디렉토리로 추가 구성을 한 경우,
간혹 Output Cache가 정상적으로 동작하지 않는 경우가 있다.
그런 경우 아래와 같은 이벤트가 계속 쌓이게 된다.
이벤트 형식: 오류
이벤트 원본: Office SharePoint Server
이벤트 범주: 게시 캐시
이벤트 ID: 5785
날짜:  2007-10-01
시간:  오전 8:36:03
사용자:  N/A
컴퓨터: PORTAL
설명:
출력 캐싱에 대한 게시 사용자 지정 문자열 처리기에 연결할 수 없습니다. IIS 인스턴스 ID는 '677781685'이고 URL은 'http://portal/TestSite/ServiceFrom.aspx'입니다.
자세한 정보는 http://go.microsoft.com/fwlink/events.asp에 있는 도움말 및 지원 센터를 참조하십시오.

정확히 확인하진 않았지만, 위와 같은 현상이 발생되는 가상 디렉토리는 보통 SPS 쪽이 NTLM이고, 가상 디렉토리 부분이 Anonymous 형태로, 인증 자체가 아예 틀린 경우다.
그런 경우 SPS 쪽의 Output Cache 프로필 중에 Anonymous 대응용 프로필이 없어 발생하는 것으로 생각된다.

이 경우 처리 방법은 해당 가상 디렉토리 내에 web.config를 별도로 생성해서 아래와 같이 처리해 주면 된다. [ 굵은 색 부분을 추가해 주면 된다. ] 
<connectionStrings/>
 <system.web>
    <httpModules>
      <remove name="OutputCache"/>
      <remove name="PublishingHttpModule"/>
    </httpModules>
   
  <!--
            컴파일된 페이지에 디버깅 기호를 삽입하려면
            compilation debug="true"로 설정하십시오. 이렇게 하면
            성능에 영향을 주므로 개발하는 동안에만 이 값을
            true로 설정하십시오.
        -->
  <compilation debug="false">



물론 정확하게는 anonymous에 대응되는 Cache 프로필을 만드는 것이 더욱 좋긴 하지만, 설정 처리 방법을 잘 모르니....
후에 Cache에 대해서 더 자세히 알게 되면 추가하도록 하겠다.

728x90

다양한 형태의 요구 사항에 모두 걸맞는 형태는 아니지만, 최소한
내 머릿속 기억을 남기기 위한 AJAX 관련 기술들의 나열을 하기위해 적는다.
이 작업은 사용자 Client가 IE여야 한다.

먼저 업데이트 할 데이터에 대한 Read를 위한 작업.
이 내용은 MSXML SDK에 있는 DOM Reference 부분을 참고하도록 한다.

먼저 MS XML 개체를 만든다.

var xmlDom = new ActiveXObject('Microsoft.XMLDOM');


그리고 난 뒤, 원하는 Node를 가져온다.

var nodes = xmlDom.selectNodes('rows/row');

여기서 'rows/row'는 XPath의 문형이 들어가면 되므로,
그에 걸맞는 형태로 구성하면 된다.
만일 단일 node를 가져오기 위해서는 selectSingleNode를 사용한다.

var node = xmlDom.selectSingleNode('rows/row[@id="update"]')

위의 예제에 있는 XPath 내용은 id Attribute 값이 update 인 노드를 가져오게 된다.

그리고 XML 안의 값을 가져오기 위해서는, value라는 Property를 사용하면 된다.

var value = node.value;

만일 데이터가 CDATA 형식으로 저장된 경우에는 firstChild의 value를 해서 가져온다.

var value = node.firstChild.value;

selectNodes를 통해 여러개의 Node를 가져왔다면, 보통 for 문을 사용해서 처리하면 된다.

for(i=0;i<nodes.length;i++)
{
       var curNode = nodes[i];
       .......
}
728x90

이 작업은 Windows Share Point 관리자가 Administrators 권한을 가지지 않을 때 발생되는
문제입니다. 단순하게 Administrators에 포함 시켰을 때는 큰 문제는 없습니다.
(그러나 테스트가 아닌 현업에서는 보안적으로 큰 구멍이됩니다.)

만일 Administrators가 아닌 일반 사용자 권한 또는 그 이하의 권한으로 WSS 3.0이 동작 중이라면 이벤트로그에 다음과 같은 로그가 쌓이는 것을 볼 수 있습니다.

이벤트 형식: 오류
이벤트 원본: DCOM
이벤트 범주: 없음
이벤트 ID: 10016
날짜:  2007-02-XX
시간:  오전 2:28:XX
사용자:  LOE\spsadmin
컴퓨터: S---SA
설명:
응용 프로그램별 권한 설정에서 CLSID가
{61738644-F196-11D0-9953-00C04FD919C1}
인 COM 서버 응용 프로그램에 대한 로컬 활성화 사용 권한을 사용자 XXXX\spsadmin SID(S-1-5-XX-XXXXXXXX-XXXXXXX-XXXXXXXX-XXXX)에게 부여하지 않았습니다. 구성 요소 서비스 관리 도구를 사용하여 이 보안 권한을 수정할 수 있습니다.

자세한 정보는 http://go.microsoft.com/fwlink/events.asp에 있는 도움말 및 지원 센터를 참조하십시오.

이 경우는 해당 계정이 DCOM 중 IIS WAMREG admin Service에 필요한 권한 중 시작과 활성화 권한이 없기 때문에 발생되는 문제입니다.
이 경우 해결하는 방법은
관리도구 -> 구성요소 서비스 창을 띄운 후
콘솔 루트 -> 구성 요소 서비스 -> 컴퓨터 -> 내 컴퓨터 -> DCOM 구성으로 들어가 IIS WAMREG admin Service 항목의 속성에 들어갑니다.
그 중 보안 탭을 눌러 시작 및 활성화 권한에서 "사용자 지정"을 선택한 후 편집에 들어가
자신의 계정을 추가해주면 됩니다.


728x90
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
보통 HTML 문서 상에서 되어 있는 문서 중에,
강제적으로 Redirect 를 하고 싶은 경우, JAVASCRIPT 나 PHP/ASP를 이용한 문서
Redirect 방법을 사용한다.

하지만 단순한 Redirect 인 경우 굳이 위와 같은 방법을 사용할 필요는 없다.
방법은 간단하다.

<head> </head> 안에 아래의 문구중 한 줄만 집어 넣어 주면 된다.
<meta http-equiv="REFRESH" content="1; URL=문서 위치/이름">

문서 위치/이름 에다 리다이렉트할 문서를 넣어주면 된다.

< 참고 문서 >
http://www.pa.msu.edu/services/computing/faq/auto-redirect.html
728x90
기존에 공개로 나돌아다니는 소스는 대부분 WMP6 를 기반으로 만들어진 소스가 많다.
그래서 실제로 그 소스를 사용하게 되면, 대부분의 명령어가 제대로 먹어들어가지 않아,
애를 먹곤한다.

실제 이쪽 인터페이스의 변경은 WMP7에서 이루워졌지만..자바스크립트로 핸들링하는 것이
늘 한계가 있다는 것을 많은 사람들이 알고 있기 때문에, 쉬이 지나치곤 한다.

몇가지 문제점들이 있는 부분들을 지적하고 기록하는 것이 이 문서의 목적이다.

* 기본 Play, Pause, Stop 문제.
기존에는 Player 객체안에 저 위의 Method들이 전부 존재를 했었는데, WMP7이후로 변경이 되었다.
Player 객체안에다 다시 Controls라는 객체를 안에다 넣어 위의 기본 명령어를 묶었다.
그러므로 기존에 .Play()... 등으로 적은 것들을 .Controls.Play() 등으로 변경해 주어야 한다.

* Mute, Voluem 문제.
이 부분은 위와 같이 Setting 이라는 객체로 묶어서 존재한다. 그러므로 기존에, .Mute 라고 처리했던 부분이
전부 .settings.Mute로 변경 조치를 취해주어야 한다.
그리고 기존에는 Volume 부분이 0~-10,000 범위로 설정되어 있었으나, 이번에는 0~100 으로 범위가 재설정되었다.

* DisplaySize
기존에는 DisplaySize를 자체에서 지원해서 큰 문제가 없었다. 형태별로 크기가 Predefine 되어 있어,
25%, 50%, 100%, 200% 등의 크기를 이 속성을 이용하여 처리를 했다.
그러나 WMP7에는 이런 속성이 없어졌고, 더 이상 이런식으로 처리가 불가능하다. 대신, 객체 자체의
크기를 변경해서 처리하면 해결 된다. 미디어객체.width 와 미디어객체.height를 변경해 줌으로써 해결을
하면 된다.

* 진행 시간 및 총 진행 시간
Play Time을 실시간으로 출력해 주어야 하는데, 이 경우 기존에는 총 시간을 초로 받아서 원하는 형태대로
포멧을 만들어 출력했다. 즉 00:20:10 이 상영 시간이라면 1210 이라는 초 시간을 미디어 플레이어에게서 받아
원하는 형태대로 계산하여 문자열로 만들었다.
그러나 WMP7 이후에는 문자열을 자동으로 생성해 준다. 단, 현재 상영시간과 총 상영시간은 역할이 틀려 각기
다른 객체로 구성되어 있다.
현재 상영시간은 .Controls.currentPositionString 를 통해서 얻는다.
총 상영시간은 .currentMedia.durationString 를 통해서 얻는다.
여기서 currentMedia가 핵심인데, 여기서 얻게 되는 총 상영시간은 현재 상영중인 컨텐츠에 한해지는 것이다.
만일 플레이 리스트가 여러가 존재한다면, 그 전체의 시간이 아닌 현재 상영중인 컨텐츠의 시간만 돌려준다.
또한, 위의 시간의 개념은 스스로 해당하는 부분만 표시한다.
만일 시간이 없는 형태 00:20:10 과 같은 형태라면 20:10 만을 돌려준다. 그 점을 유의해서 처리해야 한다.
추가적인 문자열 처리 작업이 필요하다는 의미이다.

* ASX 포멧 활용
기존 WMP6.4 에서는 Filename이라는 Param 을 이용해 ASX 내용을 그대로 건네주면 해결 되었다. 혹은 ASX 내용이 나오는
ASP를 돌려주면 간단하게 해결 되었다. 그러나 WMP7 이상에서는 그 Param이 사라지고 없다.
그래서 적용할 수 있는 방법이 다소 복잡해 졌다.
일단 JavaScript 로 별도의 함수를 만든다. 그리고 body의 OnLoad에 만든 함수를 걸어 준다.
만든 함수 안에서 미디어 객체에 아래와 같은 작업을 해야한다.

var media;
media = document.MediaPlayer.newMedia("ASX 위치 혹은 ASX내용을 돌려주는 ASP/PHP");
document.MediaPlayer.currentMedia = media;

간단하게 설명하자면 객체의 newMedia 라는 메소드를 이용해 일단 media 객체를 생성한다. 즉 media 객체를 생성하는
메소드는 URL 혹은 ASX 내용이 들어가면 생성이 되기 때문이다. (절대 URL 같은 방법으로는 ASX 내용이 들어가지지 않는다.)
그리고 난뒤에, 현재 미디어플레이어 객체에 있는 currentMedia를 현재 새로 생성한 media로 변경해준다.
이렇게 처리하게 되면, 미디어 잡히게 되고 자동으로 실행되게 된다.


* 기묘한 true 값.
간혹 객체들 중에, true/false 값으로 상태를 변경 처리하는 부분이 있다. 이들을 처리하기 위해 종종 0 과 1을 사용하거나
'true','false' 등을 이용한다. 아직 전부다 실험해 본것은 아니지만 종종 1 이라는 값을 넣으면 실행안되는 속성내용이 있다.
대표적인 것으로 fullScreen 이다. 이에다 'true' 와 1 을 넣어 보았으나 실행이 되지 않는 것이다.
그래서 혹시나 하는 마음에 자동으로 HTML을 생성해주는 Tool을 이용해 보니, -1로 값이 들어가 있고, 그 값이 들어가자
실행이 되는 것이다. 이 부분을 잘 고려 해야 한다.


이상의 내용이 WMP6.4 에서 WMP7 이상으로 업그레이드를 하는 경우에 발생하게될 문제들을 대부분 해결할 수 있다.
그러나 JScript는 성능이나, 기능상 한계가 많기 때문에, 가급적 ActiveX 나 COM 등으로 따로 개발해 통짜로 처리하는 것이
좋은 방안이 될 수 있다.
728x90

+ Recent posts

728x90