InstallSheild로 여러가지 형태의 Installer를 만들지만, 대부분은 MSI 기반의 인스톨러로 만들게 됩니다.

이 MSI 형식으로 만들게 되면, .NET Framework 역시 지원하며, .NET Framework를 통해 설치용 Custom Action을 만들어 추가할 수 있습니다. 하지만, Custom Action을 이해하려면, MSI 설치 순서와 그 사이 사이의 특성을 어느정도 파악해야 합니다.

만일 단순히 파일을 삭제하거나, 검사하는 간단한 로직을 넣을 정도의 요량이라면, 굳이 Custom Action을 사용해 만들 필요는 없다고 생각합니다.

InstallSheild에서는 특정 DLL에 포함된 특정 기능을 도출해서 쓸 수 있습니다. .NET이든, Native ( VC++ 등을 사용한 ..)든 어떠한 형태든, 표준 DLL 규칙을 가지고 있다면 어떤 형태가 되었든 사용 가능합니다. 물론 이 기능에도 수많은 기능들이 있고, 다양한 조건으로 다양한 상태에서 사용할 수 있지만, InstallSheild의 특성을 무시해서라도, 일단 설치나 제대로 되게 끔 하려하고 있다면, 필자처럼 하면 될 것입니다.

1. 일단 DLL 만든다.

일단 DLL 부터 만듭니다.  C#의 프로젝트 추가를 하시고, 프로젝트 종류를 Class Library로 하면 됩니다.

image

만일 설치될 PC에 .NET Framework의 버전도 꼭 설정해주시기 바랍니다. Visual Studio 2010을 사용한다면, 기본적으로 .NET Framework 4.0으로 되게 되는데, 대상 PC에 .NET Framework 4.0이 설치될 가능성이 없는 경우 2.0 정도로 맞춰주시면 최신 Windows Update를 받는다면 거의 다 동작할 것입니다.

만들어진 DLL 프로젝트에서 그냥 public class에 public method를 만들기만 하면 됩니다. 적당히 이름을 붙이시기 바랍니다. 물론 InstallSheild와 쌍방 통신(InstallSheild 내의 데이터를 사용하거나, 실행 결과물을 InstallSheild에게 전달해야 되는 경우)가 필요하다면, 약간은 다르게 구성해야 겠지만, 만일 그럴 필요가 없다면, 그냥 class와 method를 public으로 만들기만 합니다.

여기 예제에서는 ClearOldProducts 라는 클래스의 CleanOldProductInfo 라는 함수를 만들었습니다.

적당히 안에 로직을 짜고, 컴파일 합니다. 만들어진 DLL을 이제 ISM 파일 수정에 들어가 추가해줍니다.

일단 적용할 ISM 파일을 엽니다.
그리고 트리 메뉴에서 Custom Actions and Sequence를 엽니다.

1

UI 혹은 CustomAction들이 보이는데, 그 중 Root Tree Item에서 오른쪽 버튼을 클릭합니다.
무척 많은 메뉴 내용이 보이는데, 그 중 "New Managed Code -> Stored in Binary table"을 선택합니다.
이미지 대상 PC에 설치되어 있거나, 이미 존재하는 파일을 가지고 하는 거면, 다른 옵션들을 활용할 수 있지만, 새롭게 설치하는 PC를 기준으로 본다면, MSI 인스톨러 안에 해당 DLL을 담고 있어야 하므로, "Store in Binary table"을 선택하는 것입니다.

2

그러면 새로운 Custom Action이 생기는데, 그 위치에서 오른쪽 버튼을 클릭 한 뒤, "Custom Action Wizard..."를 띄웁니다.

3

Wizard가 뜨면 맨 처음 최초의 창은 넘어가시고...

4

Custom Action의 설명을 추가할 것이 있으면 쓰지만, 그냥 넘어가도 됩니다.

5

Custom Action을 호출하는 방법인데, 그대로 두면 됩니다.

6

이제 그 대상이 되는 DLL을 찾아서 선택하면 된다. Browse 버튼을 클릭해서 특정 DLL을 선택해주면 됩니다.7

8

DLL 선택이 되었으면, 이제 그 DLL 안에 있는 특정 함수를 선택 합니다.직접 입력해도 되지만, Browse를 클릭해서 해당 하는 클래스와 메소드를 선택하면 됩니다.

9

10

동작 방식인데, 비동기식으로 하면 인스톨 단계가 그대로 진행되면서 동작하므로, 가급적 Synchronous를 선택합니다. 그리고 exit code를 별도 제공할 예정이면 exit code를 선택하지만, 만일 없다면 Ignores exit code를 꼭 선택해야 합니다. 안그러면 종료 오류로 더 이상 처리 안되는 경우도 있습니다.

11

실행 조건인데, 그대로 두시면 됩니다. 즉시 실행이므로, 특정 조건이 되면 바로 실행되게 끔하는 것입니다.

12

마지막으로 이 스크립트가 실행되는 시점입니다. UI 가 있는 MSI면 Install UI Sequence에서, 없으면 Install Execute Sequence를 선택하여, 이벤트를 고릅니다. 그리고 Condition에 1이라고 넣습니다.

C++ 처럼 TRUE면 1, FALSE 면 0 입니다. 만일 특정 조건(Windows 2000 이상일때 라든가, x86 CPU라든가, 별도 조건이 있는 경우)가 있다면 만들어서 넣어도 되지만, 조건에 상관없이 무조건 실행되는 거라면, 1이라고 넣어주시면 됩니다.

13

요약 창이 뜨고 종료됩니다.

이제 빌드 하고 동작시켜 보시면 됩니다.

Posted by 하인도
예전에 BDD 했을 때 사용한 VB Script 인데, 혹시 몰라 올려 놓습니다.
지금은 대세가 Windows 7인지라...


'
' WMI Script - ChangeVLKey.vbs
'
' This script changes the product key on the computer
'
'***************************************************************************

ON ERROR RESUME NEXT


if Wscript.arguments.count<1 then
   Wscript.echo "Script can't run without VolumeProductKey argument"
   Wscript.echo "Correct usage: Cscript ChangeVLKey.vbs ABCDE-FGHIJ-KLMNO-PRSTU-WYQZX"
   Wscript.quit
end if

Dim VOL_PROD_KEY
VOL_PROD_KEY = Wscript.arguments.Item(0)
VOL_PROD_KEY = Replace(VOL_PROD_KEY,"-","") 'remove hyphens if any

for each Obj in GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf ("win32_WindowsProductActivation")

   result = Obj.SetProductKey (VOL_PROD_KEY)

   if err <> 0 then
      WScript.Echo Err.Description, "0x" & Hex(Err.Number)
      Err.Clear
   end if

Next
Wscript.echo "Windows XP의 제품 키 변경이 완료되었습니다."

 원리는 간단합니다 WMI을 돌면서 win32_WindowsProductActivation 에 대한 인터페이스를 가져온 뒤, 그 안에 입력받은 볼륨키를 넣어주는 기능입니다.
사용방법은 위의 Script를 실행할 때, 파라미터로 볼륨키를 넣어주시면 됩니다.  

       Cscript ChangeVLKey.vbs  ABCDE-FGHIJ-KLMNO-PRSTU-WYQZX

그 중 이텔릭체로 된 부분은 위의 스크립트를 저장한 파일이름인데, 그 파일이름으로 하시면 됩니다.
저작자 표시
Posted by 하인도

자동 빌드를 적용 중에 자주 설정을 바꾸게 되는데, 이상하게 다음과 같은 문제가 자주 발생된다.

Summary
Other Errors and Warnings
1 error(s), 0 warning(s)
      -> The path D:\BuildPlace\BuildProcessTemplates is already mapped in workspace 18_23_builder-PC.

특정 소스 위치가 이미 연결된 상태라며 문제가 발생하는 것 같다. 그래서 더 이상 빌드가 안된다. 이 문제는 아마도 빌드 전에 모든 Source를 Get Lasted Version을 하게 되는데, 그 연결이 남아 있는 상태로 다시 받으려니 문제가 발생되는 문제이다.

안그래도 이 내용을 구글을 통해서 찾아 보니까, 아래와 같은 URL을 찾을 수 있었다.

http://stackoverflow.com/questions/226288/team-build-error-the-path-is-already-mapped-to-workspace

TF.EXE 라는 Team Explorer 에서 제공하는 유틸리티를 이용해서 처리할 수 있다는 것이다.

처리 방법은 아래와 같다.

  1. 먼저 Visual Studio 에서 제공하는 CMD창을 띄운다.
  2. 다음은 다음 명령어를 넣는다. 그러면 현재 MAP 된 정보를 모두 보여준다.
    c:\>tf workspaces /owner:*

    image
    맨 앞부분이 Workspace 이름이고, 그 다음이 Workspace를 생성한 계정. 그리고 그 다음이 Workspace가 생성된 PC 이름이다.
  3. 위의 정보를 가지고 하나씩 삭제 한다. 삭제하는 방법은 CMD 창에 아래와 같이 입력한다.
    C:\>tf workspace /delete workspace_name
    만일 5_15_builder_pc 라는 Workspace를 삭제하려면 아래와 같이 입력하면 된다.
    C:\>tf workspace /delete 5_15_builder_pc
    혹시 현재 로그인 한 계정이 다르다면 아래와 같이 추가적으로 입력한다.
    C:\>tf workspace /delete 5_15_builder_pc /login:tfsadmin

    암호 입력은 별도로 띄우게 되는 NTLM 창이 뜨는데, 그 곳에다 넣으면 된다.
Posted by 하인도

2. Visual Studio 2010 Deployment Project

Visual Studio 안에 배포 프로젝트를 만들 때 사용하는 도구가 있다. Visual Studio 2002 때 부터 이미 존재는 했었고, Windows Installer의 버전과 .NET 내 지원 여부에 따라 몇번의 개정은 있었지만, 2005 때 부터의 기능적인 변화는 크게 없다. 그래서 생각보다 제작하기는 쉽다.

문제는 커스터마이징 부분이 많다. 현재로는 이 커스터마이징에 대한 벽에 부딪혀 더 이상의 진행은 잘 안되고 있다. 지금까지 파악된 내용을 정리하도록 하겠다.
여기서는 현재 개발도구가 Visual Studio 2010이여서 Visual Studio 2010을 기준으로 설명할 예정이다.
그리고 영문판이다 - -;;;

1. 프로젝트 생성 및 배포 대상 구성.

프로젝트를 생성하는 방법은 간단한다.

메뉴에서 File -> New -> Project를 선택한다.

그러면 새로운 프로젝트의 유형을 묻는 창이 뜨는데, 왼편의 Tree 에서 Other Project Type -> Setup and Deployment -> Visual Studio Installer 를 선택한다.(만일 Install Sheild가 없다면 Setup and Deployment 에서 바로 보인다.

selectproject

프로젝트 종류 중에 Setup Project를 선택한다. 그리고 .NET Framework 종류를 2.0을 선택하도록 한다.
요즘 최소한 .NET Framework 2.0 정도는 설치되어 있으니 2.0으로 선택하는 것이 좋을 것이다. (4.0 같은 것을 설치하면 나중에 배포 할 때 .NET 4.0 배포 처리를 해야 한다.

그리고 프로젝트이름을 적절히 정하고, 프로젝트가 위치할 곳도 정하도록 한다. 그리고 OK를 누르도록 한다.

최초 생성되면 신규 솔루션 파일안에 이 배포 프로젝트만 달랑 있는데, 실제 배포할 프로그램이 있는 프로젝트를 연결하도록 한다. 여기서는 예제로 필자가 기존에 재미삼아 만든 프로젝트를 포함해보도록 한다.

solutiontree 
배포할 것은 바로 GetLottoNum 에서 만들어진 Exe 파일을 올리는 것으로 판단하면 될 것이다.

2. 배포될 파일 구성.

먼저 배포 프로젝트에서 오른쪽 버튼을 클릭한다.
그러면 나오는 컨텍스트 메뉴에서 View -> File System을 선택한다.
selectview_filesystem

그러면 중앙 화면에 배포 파일 위치들이 나오게 된다.
filesystem_view

팬이 두개가 나오는데 그 중 왼편이 일종의 Tree 같은 것이고, 오른편이 왼쪽에서 선택한 폴더의 내용을 보여주는 부분이다. 최초 기본값으로 만들어진 내용은 총 3가지의 폴더의 형태를 가지고 있다.
Application Folder에는 배포할 때 배포 위치에 저장될 파일목록을 기록하는 내용이다.
두번째의 User's Desktop은 바탕화면을 의미한다.
마지막의 User's Programs Menu는 시작을 눌러서 나오는 프로그램 메뉴를 의미한다.

즉 두번째와 세번째에 위치한 User's Desktop과 User's Program Menu에는 일종의 아이콘들을 넣는 곳이라고 보면 되고, 첫번째에 위치한 Application Folder가 바로 실제 응용 프로그램들이 담기는 위치를 의미한다.

일단 왼편 트리에서 Application Folder를 선택한다. 그리고 오른쪽 빈공간에서 오른쪽 버튼을 클릭하여,
Add -> Project Output.. 을 선택한다.
addproject001

그러면 다음화면과 같은 Project 내 추가할 그룹들을 선택하게 된다.

selectprojectgroups

먼저 Project 에서 추가시킬 프로젝트를 선택한다.

그리고 난 뒤 하단에 위치한 종류를 원하는 대로 선택한다.

  • Primary output : 프로젝트를 빌드하면 출력되는 최종 결과물. 보통 Exe 나 Dll 이된다.
  • Localized resource : 언어별로 만들어진 Resource Dll 들이 된다.
  • Debug Symbol : 만일 빌드하는 형태가 Debug인 경우 pdb 같은 디버그 관련 정보 파일들이 된다.
  • Content Files : 프로젝트내에서 프로젝트 파일들을 Source가 아닌 Content로 선택한 내용들을 복사해온다.
  • Soruce Files : 프로젝트에서 빌드하기 위해서 있는 Source 들을 복사해온다.
  • Documentation Files : 프로젝트 내에서 문서로 분류해놓은 파일들을 복사해온다.
  • XML Serialization Assembles : XML 시리얼라이즈로 구성된 XML 파일들을 복사해온다.

보통은 Primary output을 하지만, 간혹 content 나 Localized resource를 포함하는 경우가 있다. 또 기본값 설정을 위해 XML Serialize 구성이 되어 있다면 XML Serialize Assemblies를 포함해야 한다. 원하면 여러개를 선택하여 한꺼번에 넣을 수 있다. Ctrl 키를 눌러 다중 선택이 가능하다.

그리고 Debug/Release 별로 나누고 싶을 때는 Configuration 부분을 적절히 선택하면 된다.

여기서는 Primary output을 선택하도록 한다.

3. 바탕화면, 시작메뉴에 프로그램 바로가기 만들기.

아이콘으로 된 바로가기를 만드는 작업을 한다.

왼편 트리에서 User's Desktop 을 선택하고, 오른편에서 오른쪽 버튼을 클릭하여, Create New Shortcut을 선택한다.
그러면 아래와 같은 선택 창이 나오는데, 앞서 설정한 Application Folder 안에 있는 Primary output을 선택하도록 한다.
select_newshortcut

OK를 누르면 알아서 자동으로 바로가기가 추가된다.적당한 이름으로 변경해준다.

이번에는 User's Programs Menu 이다.

바탕화면은 바로 만들었지만, 시작 메뉴는 하위에 폴더를 먼저 만들도록 한다. 시작메뉴 바깥에 그냥 만드는 경우도 있지만, 대개의 경우에는 폴더를 구성해서 그 폴더 안에 바로가기가 들어 있다. 그러므로 가급적이면 다른 프로그램 처럼 구성하는 것이 좋다.

startmenu_examples

앞서 바탕화면에서 했던 작업과는 별도로 한가지 더 작업이 있는 것이다. 폴더를 만드는 것.
여기서는 Get Lotto Number 이라는 폴더를 만들고 그 안에 바로가기를 만든다. 폴더를 만드는 방법은 해당 위치에서 오른쪽 버튼을 눌러 Add -> Folder를 선택하면 된다.
새로 만들어진 폴더를 클릭하고 앞서 만든 바로가기 처럼 추가하면 된다.

createshortcutforstartmenu

그냥 이렇게 만들어진 바로가기는 이쁘지 않으니, 해당 바로가기를 선택한 뒤, Properties 창에서 Icon 부분을 클릭해 새로운 아이콘을 넣도록 한다. 넣는 방법은 Properties 중에서 Icon 부분을 클릭하면 드랍다운 창이 드는데 그 중 (Browse..) 를 선택한다 그러면 선택창이 나오는데, Application Folder를 선택하고, Add File을 선택한다.
그리고 적당한 ico 파일을 선택하면 자동으로 Application Folder로 들어간다. 새롭게 Application Folder에 들어간 icon 파일을 선택하고 OK를 클릭한다.

selectnewicon

4. Build

오른편에 위치한 솔루션 트리에서 Deployment 프로젝트를 선택하고 오른쪽 버튼을 클릭해 Build 혹은 Rebuild를 선택한다. 그러면 자동으로 빌드를 하고 해당 프로젝트 하위에 각 프로젝트 형태(Debug/Release) 형태로 폴더를 만들어 결과물을 만들어 낸다.

5. 선결 설치 내용 정의하기.

개발 환경에는 개발을 위해서 다양한 선결 조건이 먼저 구축되어 있다. 최소한 .NET 프로그램을 만들기 때문에, 당연히 이에 필요한 .NET Framework가 버젼별로 구성되어 있다. 하지만, 이 프로그램을 설치할 PC에서는 해당되는 구성요소가 없을 수 있다. 이를 위한 설정을 해야 한다.

이를 위해서는 Deployment Project에서 오른쪽 버튼을 클릭하여 Property에 들어간다.
deploymentproejctproperty

속성창 하단에 위치한 Prerequisites 버튼을 클릭하도록 한다.
그러면 각종 선결작업으로 사용될 패키지들이 보인다. 만일 원한하는 패키지가 없다면 MS 사이트에서 업데이트 받으면 된다. ( 중간에 보이는 Check Microsoft Update for more redistributable component 를 클릭해도 된다. )
prerequisite

만일 이 프로그램을 설치하는 사람들이 인터넷을 사용할 수 없다면 맨 아래쪽에 선택하는 것들 중에 중간을 선택하도록 한다. 그러면 배포 패키지 안에 설치본이 자동으로 들어간다. 예를 들면, .NET Framework 3.0 같은 경우 인터넷에서 다운받아서 설치하게 끔 되어 있은데, 2번째를 선택하면 이미 전체를 다운 받은 버전을 설치본에 넣어줘서 인터넷 접속없이도 설치가 가능하게 된다. (가급적 2번째를 선택하는게 설치 작업을 빠르게 끝낼 수 있다.)

위에 나열된 내용은 Microsoft SDK 라는 곳에 있는 버젼별 SDK 안에 Bootstrapper 의 Package 안의 내용을 보여준다. (아래 캡쳐 화면에 있는 주소줄 위치로 보시면 된다. )

bootstrappers

각 폴더 안에는 설치본들이 담겨 있으며, 자동으로 설치되는 설정이나, 버젼 체크 방법을 위한 도구들이 같이 담겨 있다. 이 패키지를 만드는 방법은 다음 사이트를 참고하도록 한다.

http://msdn.microsoft.com/en-us/library/ms165429.aspx (Creating Bootstrapper Packages )
http://msdn.microsoft.com/ko-kr/library/ms165429.aspx

6. 인스톨러 추가 기능 만들기.

사실 Visual Studio 안에서 이 설치 프로젝트를 수정하는 방법이 애매하다.
그래서 추가적인 기능을 덪붙이기는 쉽지는 않다.
대신 방법은 Exe 나 Dll 을 통해 처리하도록 할 수 있다.

여기서는 간단하게 DLL 프로젝트로 만들도록 한다.
현재 Deployment Project가 있는 솔루션에 Class Library 프로젝트를 하나 만든다.
installeraddon

References(참조)에서 .NET 중, System.Configuration.Install 을 추가하도록 한다.

그리고 현재 Main Class 에 System.Configuration.Install.Installer 클래스를 상속 받게 한다.

classinheritance

안에 다음과 같은 함수들을 추가한다. "override" 라는 키워드를 치면 인텔리센스를 통해 자동으로 대부분 나오게 된다.

  • Install
  • Uninstall
  • Commit
  • Rollback

꼭 만들필요는 없지만, 원하는 이벤트의 형태에 따라 만들면 된다.

  • OnBeforeInstall
  • OnAfterInstall
  • OnBeforeUninstall
  • OnAfterUninstall
  • OnBeforeCommit
  • OnAfterCommit
  • OnBeforeRollback
  • OnAfterRollback

각 실행지점에 대한 설명을 하고 싶지만, 애석하게도 명확히 구분이 안되서 필자역시 여기가 한계다.

일단 이런 DLL이 만들어지면, 다음에는 Deployment Project로 돌아가도록 한다.

이제 Application Folder에 위의 프로젝트의 결과물을 넣도록 한다.
View -> File System을 선택한 뒤, 위의 프로젝트의 Primary Outputs를 넣도록 한다.

이 예제대로면 아래와 같이 2개의 Primary output이 들어가 있을 것이다.

primaryouts2

그리고 View -> Custom Actions를 클릭하여 Custom Actions 창을 띄우도록 한다.
창이 떴으면 원하는 단계에서 오른쪽 버튼을 클릭하여 Add Custom Action.. 을 클릭한다.
(만일 모든 단계에 포함하고 싶으면 트리의 최상단에 있는 Custom Actions에서 하면 된다).

addcustomactions

그러면 선택화면이 뜨는데, 그 중 Application Folder 안에 있는 Primary output 중에 앞서 만든 Installer 를 선택한다.

selectinstallerprimaryoutput

등록이 성공하면 Install 아래에 한가지의 Action이 추가되었을 것이다. 이 Actions을 선택하고 속성창을 열도록 한다.

actionproperties 

여기서 반드시 확인해야 하는것이 바로 InstallerClass 부분이다. 반드시 이 부분이 True로 되어 있어야 한다.

그리고 이 사용자 정의 Installer에 정보를 별도로 제공하려면, CustomActionData를 사용해야 한다.
마치 파라미터를 통해 데이터를 주듯 주면 된다.
예를 들어 설치 폴더의 정보를 주려면,

/DestDir="[TARGETDIR]\"

이라는 값을 CustomActionData 속성으로 넣어야 한다.

만일 그 외의 값들을 추가적으로 주려면, 한칸 띄고 그 옆에 / 하여 계속 붙여서 보내주면 된다.

/내부이름=값

위의 형식을 기억하면 간단한 것이다. 여러개인 경우 /내부이름1=값  /내부이름2=값  /내부이름3=값 … 이런식으로 넣는다. 또 값안에 공백이 있는 경우에는 반드시 " " 를 통해 막아서 보내도록 한다.

위의 예제에서 보면 /DestDir="[TARGETDIR]\" 라고 했는데, 값 부분에서 맨 끝에 \ 가 들어가 있다.
정확히는 왜 이런지는 모르겠는데 안들어가면 오류가 난다. 아마도 내부 변수 ([TARGETDIR] 같은 것들)를 사용하면
오류가 발생하는 것 같다.

이렇게 전달되는 값을 프로그램안에서 쓰려면 아래와 같이 하면 된다.

destdir_paramtest

this.Context.Parameter 를 통해 값을 전달 받는 것이다.

이를 통해 인스톨러 내에서 사용되는 각종 값을 수신하는 것이다.(상태값, 입력값 등등)

7. Launch Condition.

각 구성요소의 실행 조건을 미리 만들어 놓는 곳이다.

View -> Launch Conditions 를 선택하면 나온다.

왼편 폴더가 보이는데 그 중 Search Target Machine이 바로 IF문을 만드는 부분이다.
종류는 총 세가지가 있다.

  • File Search
  • Registry Search
  • Windows Installer Search

각각 파일이 존재여부로, 레지스트리의 특정값이 존재여부로, 마지막으로 Windows Installer로 설치된 ID로 있는지 없는지를 판단하여 true/false로 결정되는 사항이다.

하위에 있는 Lauch condition인데, 여기서는 외부에서 실행될 내용을 연결할 때 사용되는 부분이다.

앞서 만든 Custom Action들 중에 특정 조건에 해당할 때만 실행되도록 만들려면, 먼저 Search Target Machine에서 해당 조건을 만들고, 이를 가지고 Lanch Condition을 만든다. 이를 Custom Acition 의 속성안에 설정한다.

 

 

사실 이 프로젝트를 이용하여 좀더 커스터마이징을 가해서 원하는 형태로 뽑아내고 싶었다.
이 Deployment Project는 Visual Studio로 만드는 모든 프로젝트 결과물을 가장 효율적으로 묶을 수 있기 때문에, 사용성은 우수하다. 하지만, 정말 원하는 기능을 추가하기 위해서는 제약점이 너무크다. 그나마 커스터마이즈 율이 제일 큰게 외부 모듈을 이용해 Action을 정의할 수 있는 부분인데, 그 마저도 애석하게도 한계점이 자주 보인다.

(아직 조사가 끝난 것은 아니지만, UI를 제어할 방법이 있는지를 명확히 모르겠다.)

시간이 허락되면 나중에 이 Installer에 대한 자세한 파악이 병행될 필요는 있어보인다.

Posted by 하인도

기존 Application이나 Patch등은 별다른 조건 없이 설치 진행이 되었기 때문에, 설치 프로그램의 기본값만으로도 충분하게 패키지화 했다. 하지만, 이번에는 본격적으로 End-User를 향한 제품을 패키지 하는 작업이기 때문에, 그렇게 단순하고 쉽게 패키징을 할 수 없었다.

물론 아래의 처리 방법들은 현재까지 패키징을 하면서 받았던 각종 정보와 설정 값들일 뿐, 원하는 형태로 성공적인 패키지 한 것은 아니다.

단순하게나마 패키지를 할 때 도움이 될 것 같아 기록에 남긴다.

1. NSIS ( Nullsoft Scriptable Install System )

Nullsoft에서 제작한 Installer System 프로그램. 100%에 가깝게 스크립트기반이며, 스크립트로 처리가 불가능한 경우 DLL 등을 이용하여 외부 모듈을 통해 플러그인의 개념처럼  추가할 수 있다. 하지만, 아직 그 부분까지는 접근조차 하지 못했으며, 특히 매 버전마다 변경점 마다 스크립트 수정 작업의 부하가 너무 커서 제작 중 도중에 포기하였다.하지만, 단순하고 직관적으로 패키지를 말때는 상당히 도움이 될 것 같다.

준비물.

  1. NSIS( Nullsoft Scriptable Install System) 컴파일러.
    제일 중요한 부분. 이 제품은 Open Source 라이센스를 따르며 무료로 배포되고 있다.
    http://nsis.sourceforge.net/Main_Page
    에서 Download 부분을 통해 다운 받을 수 있다.
  2. HM NIS Edit
    NSIS의 동작은 모두 Script를 컴파일 한 뒤, 나온 결과물로 동작한다. 즉 Script 파일과 실제 배포할 파일들만 있으면 간단하게 만들 수 있다. 진짜 “메모장” 하나 열고 그 안에서 Text 파일로 된 Script 파일을 구성한 뒤, 컴파일 하면 된다. 하지만, 이제 처음 NSIS를 돌려보시거나, NSIS 개념을 막 잡아가는 초보(필자도 포함)에게는 버겁기 그지 없다. 이를 그나마 많이 편하게 제공하는 UI가 바로 HM NIS Edit 프로그램.
    이 역시 무료이며, 불편함이 없지않아 있지만, 그 작은 불편을 뛰어 넘는 다양한 기능들이 NSIS를 조금은 더 쉽게 다가게 해준다.
    해당하는 프로그램은
    http://hmne.sourceforge.net/
    에서 볼 수 있으며, 다운로드 받아 설치하면 된다.

 

개념을 익히기 좋은 사이트들.

사실 NSIS 는 개념익히는데 상당히 어렵다. 물론 MSI 작성 방법보다는 조금은 더 직관적이고 단순하다. 그러나 작은 개념조차 익히기 어려운 건 사실이며, 대부분의 설명 사이트들은 영어로 되어 있다. 그래도 국내에서 NSIS로 삽질하시던 많은 프로그래머들이 있고 그들의 흔적을 잘만 찾아 댕겨도 의외의 많은 정보들을 얻을 수 있다.

  1. Kipple 사이트
    꿀뷰(HoneyView)라는 이미지 뷰어 프로그램으로 유명세를 타고 있던 분. 이 분이 만든 제품들의 패키지를 NSIS로 했으며, 그에 따라 다양한 기능등를 자체적으로 구성했다. 그래서 그 속에서 묻어 나오는 각종 팁들이나 예제들을 제공한다. 특히 예제로 담은 nsissample.zip 파일은 받드시 받고 그 안의 스크립트 내용을 잘 확인해보록 한다.
    http://www.kippler.com/doc/nsis/
  2. 게으른 엔지니어가 사는법 ~~~~ 사이트.
    NSIS 에는 몇가지 UI가 있는데, 과거 Winamp 시절에 사용한 classic 방법 부터 현재는 MUI2 라는 방식까지 여러가지가 존재한다. 필자의 경우 Windows Installer 3.1 UI랑 비슷하게 나오게 하는 MUI2를 주로 사용하는데 간혹 관련 예제들을 Google에서 찾으면 classic 시절에 짰던 방법으로 많이 나온다. 그래서 이래저래 방황을 많이 했는데, 아래의 사이트에서 많은 도움을 얻었다.
    http://www.cipher.pe.kr/tt/cipher/154?category=6
  3. 그 외..
    http://innara.springnote.com/pages/3828755
    http://jgh0721.tistory.com/category/프로그래밍/NSIS

 

구성 순서.

1. 기본 도구 설치 준비.

제일 먼저 NSIS 컴파일러와 HS NIS Edit를 설치한다.
이 두가지는 반드시 설치해서 진행하도록 한다.

2. 작업 폴더 준비.

인스톨러를 준비하기 위한 적절한 폴더를 하나 마련한다.
보통 이 폴더에 배포하기 위해 필요한 내용도 적절하게 보관하여 정리하도록 한다.
실행에 필요한 각종 내용들 (.NET 기준으로 bin\Debug 혹은 bin\Release 같은 폴더)을 담은 폴더와,
기타 부가적으로 필요한 내용들 ( 인스톨러 커스터마이징을 위한 이미지나 아이콘 등)을 담은 폴더,
그리고 별도로 복사할 때 사용되는 잡스러운 내용을 담은 폴더를 나누어 정리한다.

folderlists

3. 설정 파일 생성 혹은 템플릿 이용.

HM NIS Edit에서 새로 만들기를 하면, 마법사를 이용하여 기본적인 NSIS용 설정파일을 하나 만들어준다. 하지만, 이 방법으로 만들게 되면 결과물이 거의 완전 영어판으로 나오기 때문에,영어 알레르기가 있으신 분은 무척 애매해지는 경우가 발생할 수 있다.
이 경우에는 앞서 언급한 Kipple 님의 홈페이지에서 NSIS 예제를 다운로드 받는 것이다.
그 파일을 그대로 활용해도 된다.  물론 바로 받아와서 사용하려고 하면 컴파일할 때 오류가 발생하는데,
NSIS를 Kipple님이 수정한 버전으로 교체하거나, 아니면 설정 파일에서 오류나는 부분을 주석 처리해도 된다.
여기서는 Kipple님의 설정파일을 기준으로 설명한다.

4. 설치 파일 설정하기.

My_CopyFile 라는 함수를 찾는다. Ctrl + F를 눌러 저 Text로 찾으면 된다.
다른 부분은 그대로 두면 되고, SeachOutPath와 File 이라는 명령어가 있는 부분을 대거 수정한다.

filelist1

설치 결과물를 잘 고민하도록 하자. 만일 아래와 같은 형태로 구성하고 싶은 경우라고 가정을 하자.
filelist2

Program Files 밑에 Easy Connect 라면, 일단 그 부분은 그대로 두고,
그 폴더 안에 복사될 파일들을 File 이라는 명령을 사용해 넣도록 하자.
지금 설치될 파일은 모두 Binaries 폴더에 있으니 그 경로의 파일들을 나열하면 된다.

File ".\Binary\bin\Debug\\DevExpress.XtraTreeList.v10.1.xml"
File ".\Binary\bin\Debug\\DevExpress.XtraTreeList.v10.1.dll"
File ".\Binary\bin\Debug\DevExpress.XtraRichEdit.v10.1.xml"
File ".\Binary\bin\Debug\DevExpress.XtraRichEdit.v10.1.dll"
File ".\Binary\bin\Debug\DevExpress.XtraPivotGrid.v10.1.xml"
…………

자 다음은 Cur 부분. 일단 File 이 쭉 나열된 목록들 맨 끝에 다음과 같은 줄을 넣는다.

SetOutPath "$INSTDIR\Cur"

그리고 Cur 폴더에 들어갈 파일들을 위의 FILE 처럼 쭉 아래로 나열한다.

원리는 간단하다 SetOutPath 라는 것을 이용해 폴더를 구축한다. 여기서 시작점이 바로 "$INSTDIR"이 된다.
그 하위에는 당연히 \ 가 붙고 그 하위에 폴더를 만들면 된다.

5. 조건 별로 설치되어야 할 파일 설정.

지금 배포할 응용 프로그램은 .NET Framework 2.0 을 기반으로 구성되어 있다.
그러므로 반드시 미리 .NET Framework 2.0이 설치되어 있어야 하는데, 이를 체크한 뒤에 해당하는 프로그램이 설치되어 있지 않으면 설치해야 할 것이다.
아래의 코드로직을 설명하기 전에, 찾는 방법을 간단하게 설명하면 아래와 같다.

  1. 레지스트리에서 HKey_Local_Machine\SOFTWARE\Microsoft\.NETFramework 부분의 키를 따라들어간다.
  2. 키 안에 값들 중 InstallRoot 라는 항목을 열어 본다.
  3. 그 안의 값에 맨 뒤에 .NET 버전을 붙여본다.
    보통 .NET 2.0 이 설치되어 있다면 "C:\Windows\Microsoft.NET\Framework\2.0.50727" 라는 폴더가 있고, 그 안에 파일들이 있다.
  4. 위의 경로에 파일이 있는지 확인한다.

위의 단계에서 1 부분에서 오류가 있다면, 즉 레지스트리에 값이 없다면 .NET Framework가 설치되어 있지 않다는 의미. 그러므로 .NET Framework 2.0 을 그냥 설치하면 된다. 만일 이 부분이 있다면 .NET Framework 가 설치된 폴더에 파일들이 있는지 확인한다. ( Windows 설치 폴더가 생뚱 맞은데일 수도 있다. - E:\Windows 등등 ). 만일 파일들이 없다면 다른 .NET Framework 는 설치되어 있지만, 2.0은 설치되어 있지 않다는 것이다.

이런 로직으로 찾아보도록 한다.

제일 먼저 .NET Framework 가 설치되어 있는지 아닌지 여부를 저장하기 위한 전역 변수를 하나 설정한다.

Var IsHadNetFramework20

이 변수에 "t"가 들어 있으면 설치되어 있는것이고, 비어 있으면 설치되지 않은 것으로 정한다.

그리고 난 뒤, 체크하는 로직을 위한 Function을 만든다.

Function CheckAlreayInstalledSolutions

    ; .NET Framework 2.0 설치 여부 체크
   ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\.NETFramework" "InstallRoot"
   StrCpy $IsHadNetFramework20 ""
   StrCmp $R0 "" notFound foundIt

   foundIt:
           IfFileExists "$R0\v2.0.50727\*.*" VersionFound notFound
   VersionFound :
           StrCpy $IsHadNetFramework20 "t"
   notFound:


FunctionEnd

함수는 Function {이름} 으로 시작해서 FunctionEnd 로 끝난다.
그 안에 필요한 로직을 넣으면 된다.

일단 한 줄 씩 끄집어 보도록 하자. 

함수의 맨처음 줄은 ";" 가 맨 앞에 붙어 있는데, 주석이다. "#" 을 써도 된다.

ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\.NETFramework" "InstallRoot"

ReadRegStr은 특정 레지스트리 에서 값을 가져오는 것이다.
HKLM은 HKey Local Manchine을 기준으로 "SOFTWARE\Microsoft\.NETFramework" 에서 "InstallRoot" 라는 곳에서 문자열을 읽어온다. 이렇게 읽어온 문자열은 $R0 이라는 임시변수에 저장한다는 것이다.

StrCpy $IsHadNetFramework20 ""

별다른 의미는 없고 전역 변수로 설정한 변수를 초기화 하는 것이다. 그를 위해서 StrCpy라는 명령을 썼는데, 다른게 아니고 바로 문자열 복사같은 것이다. "" 를 복사했으니 완전 빈 변수가 되었다고 보면 된다.

StrCmp $R0 "" notFound foundIt

이 부분 부터 암호화의 느낌을 받은 문장. 다른 의미는 아니고 $R0 과 "" 를 비교한다는 것이다.
그 결과에 따라서 만일 같으면 notFound로 같지 않으면 foundIt 으로 이동한다는 의미.
굳이 Basic 스타일로 번역하면..

if $R0 == "" 
Then 
  Goto notFound
Else
  Goto foundIt

이 NSIS의 스크립트에는 IF라는 개념이 없는데 그와 유사한 로직으로 사용하는 것이 바로 이 StrCmp.
이 것을 활용하는 것으로 보면 된다.

foundIt:

암호화에 일조하는 부분인데, 바로 라벨이다. 즉 goto 해서 이동할 라벨을 의미하는 것.

   IfFileExists "$R0\v2.0.50727\*.*" VersionFound notFound

왠지 IF 스러운 내용인데, 이 If 는 여러가지로 활용가능한 If 가 아니라, 오로지 파일이 있는지 여부를 확인하기 위한 로직이다. .NET 2.0 파일들이 있는지 확인한다. 만일 파일들이 있다면 VerisonFound로 goto 하고 없다면 notFound 로 goto 한다.

위의 로직에서는 Check 하는 것이므로, 이젠 설치하는 로직을 만들도록 하자.

Function InstallNETFramework20

; .NET Framework 2.0이 설치되어 있지 않으면 설치
   StrCmp $IsHadNetFramework20 "t" DoInstllDotNet PassInstall
   DoInstllDotNet:
       DetailPrint "Install .NET Framework 2.0"
       ExecWait '".\AddonPackage\installdotnet.cmd"' $1
       SetRebootFlag true
       Sleep 20000
    PassInstall:

FunctionEnd

위에서 언급안된 부분을 설명하도록 한다.
DoInstallDotNet 이라는 라벨이 있는 부분을 보도록 한다.

DetailPrint "Install .NET Framework 2.0"

다른 의미는 없고 인스톨 설명 줄에 "Install .NET Framework 2.0"를 출력하는 것 뿐이다. 설치 화면 중에 지금 무엇이 설치되고 있는지 설명을 출력되는 창에 보이는 문구라고 보면 된다.

ExecWait '".\AddonPackage\installdotnet.cmd"' $1

이 부분이 중요한데, '".\AddonPackage\installdotnet.cmd"' 라는 문자을 Shell을 써서 실행한다는 의미이다. 단 실행은 하는데, 단지 실행이 완전히 종료될 때까지 대기를 하겠다는 의미이다. 그리고 최종적으로 실행 결과를 $1에 출력하겠다는 것이다. 기다릴 필요가 없는 경우에는 Exec 를 쓰면 된다.

SetRebootFlag true

일종의 옵션인데, 설치 후 맨 마지막에 Reboot 하겠다는 의미이다. 종종 설치 프로그램에서도 특정 프로그램을 설치한 뒤 자동으로 재시작하는 경우를 많이 보는데, 바로 그럴 때 사용하는 옵션이다. 만일 .NET을 설치하지 않는 경우에는 Reboot를 할 필요가 없으니, 설치할 때만 이 옵션을 true로 설정하는 것이다.

Sleep 20000

설치 중에 다른 프로그램을 설치하게 되면 HDD의 Access Time이라는 것이 있어서, 약간의 대기가 필요할 수 있다.
여기서는 20초 정도로 설정했다. 1/1000 초이므로 1000이 1초. 즉 20초 대기라는 의미.

 

일단 설치되어 있는지 여부를 체크하는 함수와 그 체크한 결과 값을 기준으로 설치하는 로직을 담은 함수를 제작했다.
이제 이 함수를 호출하는 로직을 넣어보도록 한다.

먼저 체크.

설치하기 전에 맨 처음 부분에서 실행한다.
윈도우의 EventHandler 같은 기능들을 제공하는데, 그 중 인스톨러 시작할 때 걸리는 함수는 이것이다.

Function .onInit
     ………
FunctionEnd

저 함수 안에 다음과 같음 문장을 넣는다.

Call CheckAlreayInstalledSolutions

 

이제 마지막으로 남은 것은 설치하는 함수.
설치할 때 넣어주거나, 아예 시작할 때 넣어도 된다. 여기서는 설치할 때 넣을 수 있도록,
앞서 보여준 My_CopyFile  라는 함수 안에다가 다음과 같은 문장을 넣는다.

Call InstallNETFramework20

 

6.사용자 정의 화면 넣기.

사용자 정의 페이지를 넣으려면 MUI2 에서 제공하는 페이지 적용하는 방법부터 확인해야 한다.

pages

대략 보면 알겠지만, "!insertmacro" 라는 키워드를 이용해 MUI_PAGE_ 로 시작하는 페이지들을 나열한다.
바로 원하는 페이지를 넣는 방법이다. 이 방법은 MUI2 에서 만들어진 화면을 끼워넣는 것으로써,
저 넣는 순서를 바꾸면 실제 나오는 화면이 순서도 바뀌게 된다. 그리고 뒤쪽에 MUI_UPAGE는 언인스톨 할 때 보여주는 페이지들이다.

사용자 정의 화면을 만드는 방법은 다음과 같다.

  1. UI를 표시하는 ini 파일을 생성한다.
    물론 텍스트 파일 편집기로 ini 파일을 만들어도 되지만, HM NIS Edit 도구를 써서 만들도록 한다.
    만드는 방법은 파일(F) -> 인스톨 옵션 파일 만들기 를 선택한다. 그러면 다음과 같은 UI 도구가 나오는데,
    원하는 형태의 UI를 구성한다.
    custompage1
    적당한 UI를 넣고 설정을 한 뒤, 저장하면 ini 파일이 만들어진다.
  2. 만들어진 ini 파일을  스크립트 파일 내에서 등록해줘야 한다.
    먼저 스크립트 소스의 상단에 다음과 같은 줄을 포함한다.

    ReserveFile ".\qlmscr.ini"

  3. .onInit 함수 - 초기화 함수 - 에 다음과 같은 줄을 넣는다.

    !insertmacro INSTALLOPTIONS_EXTRACT_AS ".\qlmscr.ini" "qlmscr.ini"

    ini 파일의 내용을 미리 분석해서 이름을 정해 놓는 것이다. 즉 .\qlmscr.ini 라는 의미는 스크립트가 담긴 폴더위치의 qlmscr.ini를 분석한 뒤 이제 이름을 "qlmscr.ini" 로 하겠다는 것이다. 이제 이 화면에 대한 아이디는 바로 "qlmscr.ini" 가 되는 것이다.

    사실 ini 파일은 NSIS 가 설치된 폴더 아래에 있는 Plugin에 복사해서 사용하는게 일반적인 것 같다.
    하지만, ini 파일을 영구히 다른데서 쓸 예정이 아니라면, 스크립트 파일이 있는 위치에 ini 파일을 위치시켜 놓고, 위와 같은 줄을 포함해 놓으면 좋다.
  4. 위 쪽에 페이지 순서를 넣는 부분 처럼 Page custom 부분을 만들어 넣는다.
    여기서 Page custom을 만들 때 뒷부분에 다음과 같은 항목들이 들어가야 된다.
    Page custom {페이지생성용 함수} {페이지내 입력값 확인용 함수}

    예를 들면 이렇게 넣는다.

    Page custom CreateCheckUserInfo ValidateCheckUserInfo

    위와 같이 만들었으면 CreateCheckUserInfo 라는 함수와 ValidateCheckUserInfo 라는 함수도 덩달아 만든다.
  5. 생성용 함수로 들어가 다음과 같은 줄을 포함시킨다.

    !insertmacro MUI_HEADER_TEXT 'User Information' 'Input your information and serial key for authorizing this application'
    !insertmacro INSTALLOPTIONS_DISPLAY "qlmscr.ini"

    MUI_HEADER_TEXT 라는 것을 !insertmacro 해서 넣었는데, 이 부분이 현재 사용자 정의로 만든 창의 제목줄과 설명 줄 내용을 넣는 부분이다. 적당한 제목과 설명을 넣으면 된다.

    다음에 있는 INSTALLOPTIONS_DISPLY "qlmscr.ini" 부분은 qlmscr.ini 라고 정의된 사용자 정의 화면을 띄우는 작업이다. qlmscr.ini 는 앞서 .onInit 함수 안에서 설정한 그 이름이다. 즉 화면 아이디 같은 것. 즉 저 화면을 띄우겠다는 의미가 되는 것이다.

    만일 화면 안의 특정 요소들에서 값을 빼와야 되는 경우가 있다. 예를 들어 문자열을 입력받을 때 사용되는 텍스트 박스 같은 것이 있다면, 그 ID와 변수를 연결한다. 이 때 사용되는 문구가 다음과 같은 것이다.

    !insertmacro INSTALLOPTIONS_WRITE "qlmscr.ini" "Field 1" "State" "$UserName"

    번역하자면, "qlmscr.ini" 화면에 있는 "Field 1" 라는 컨트롤에서 속성 값 중, "State" 부분의 속성값을 $UserName 이라는 변수에 넣는다는 것이다. 이 때 주의할 점은 모든 값들 정보에 " " 가 들어간다.

    예를 들면 아래와 같은 모습이 되는 것이다.
    !insertmacro INSTALLOPTIONS_WRITE "qlmscr.ini" "Field 1" "State" "$UserName"
    !insertmacro INSTALLOPTIONS_WRITE "qlmscr.ini" "Field 2" "State" "$UserCompany"

 

일단 NSIS 로 인스톨러를 구성하면서 막혔던 부분에 대한 설명을 모두 담은 것 같다.
아직은 이 NSIS 라는 도구에 대한 학습이 부족하고, 더욱이 버젼별로 나누어 만드는 방법을 자동화 하는 방법을 아직 못찾고 있어서 현재로는 더 이상의 파악은 어려운 상태이다.

나중에 시간적인 여유가 되면 이 NSIS 라는 부분을 체크하고 인스톨러 답게 만들려고 한다.

여기까지 정리.

Posted by 하인도

MS Test 연동하기
요즘 TDD 학습에 피치를 올리고 있기 때문에, MS Visual Studio 안의 Test Unit을 사용중이다.

(NUnit이 .NET을 위한 Unit 테스트 프레임으로 다양한 기능을 제공한다고 한다. 또한 이 CCNet 안에서도 자체 지원되며 결정적으로 CCNet Config에서 간단하게 추가할 수 있다..

그러나 아직 NUnit을 한번도 사용해 본적이 없다. )

 

그런데 CCNet 에서는 MS Test를 적용하는 방법이 직접적으로 설정 할 수 없었다. (최소한 1.4.4 버전에선....)

대신 MS Test를 일종의 작업으로 돌려, 그 결과 값을 Report에 적용해줄 수 있었다.

그 중 googling을 통해 얻은 자료 중 하나가 바로 이것이다. (CCNet 에서 MS Test 결과를 적용하는 방법이 담긴 링크)

 

시작하기 전에

이 작업을 하려면 먼저 MS Test를 실행하는 방법을 어느정도 이해해야 한다.

IDE 도구에서야 Test의 Test 실행 버튼 한번이면 되지만, 여기서 작업이라는 형태로 만들려면, 외부에서 프로그램을 어떻게 띄워야 하는지 등을 알아야 한다.

  • 솔루션 전체를 한번 빌드 한다
  • 이전에 Test 결과 값이 있는 경우 삭제하는 배치 파일을 만든다. 그리고 그 배치를 실행할 수 있게 한다.
  • MSTest를 동작시키는 프로그램을 실행하며 동작시킨다.
  • 테스트 결과물을 CCNet에 연동한다.

이제 이런 방법으로 차근 차근 하나씩 적용하도록 한다.

 

준비 작업

맨 먼저 준비해야 될 작업은 작업의 기준이 되는 CCNet 설정파일이다.

이 설정 파일을 기준으로 하나씩 추가해야 하며 각 단계를 아래에서 계속 설명할 것이다.

이전 단계에서 설명한 내용을 기반으로 CCNetConfig를 이용해 구성했다면 다음과 같은 .config 파일을 열어볼 수 있다.

(.config 파일은 C:\Program Files\CruiseControl.NET\server\ccnet.config 를 의미한다. )

<!--<ccnetconfig><configurationVersion>1.4</configurationVersion></ccnetconfig>-->
<cruisecontrol>
  <project name="CQWorkflowViewer">
    <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
    <artifactDirectory>E:\Builds\CQWorkflowViewer</artifactDirectory>
    <sourcecontrol type="svn">
      <trunkUrl>file:///D:/Works/000.MySVN/CQWorkflowViewer</trunkUrl>
      <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
      <executable>C:\Program Files\VisualSVN\bin\svn.exe</executable>
    </sourcecontrol>
    <triggers />
  </project>
</cruisecontrol>

 

 

솔루션 전체 빌드하기.

맨처음에 난 이 내용을 이해하지 못했다. 그냥 MS Test를 동작시키면 되지 않을까 했다.

하지만, MS Test가 동작하려면, 테스트 코드가 컴파일되어 있는 DLL이 필요했는데, 이 DLL은 결국 솔루션 전체 Build가 되어야 생성될 수 있다.
(Unit 테스트 자체가 이곳 저곳의 클래스와 컴포넌트들을 거의 직접 연결하므로 어쩔 수 없는 것 같다.)

이 빌드 방법은 솔루션 파일(*.sln)을 직접 컴파일 해야 되기 때문에, Visual Studio의 힘을 빌릴 수 밖에 없다.

그래서 이 Task를 하나씩 조립해서 하나의 Task로 만들면 다음과 같다.

<devenv>
                <solutionfile>"E:\Builds\CQWorkflowViewer\Works\CQWorkflowViewer.sln"</solutionfile>
                <configuration>Debug</configuration>
                <buildtype>Build</buildtype>
                <executable>"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com"</executable>
                <buildTimeoutSeconds>90</buildTimeoutSeconds>
 </devenv>

뭔가 낯선 이상한 XML 엘리멘트들이 튀어 나왔다.

이 작업 devenv라는 컴파일 구성요소를 설정하는 내용으로 위의 내용은 특정 솔루션을 전체 빌드하기 위한 내용이다. 

각 부품들을 하나씩 살펴보자.

solutionfile 부분은 이 프로젝트의 솔루션 파일의 위치를 정해준다. 작업 디렉토리를 기준으로 해당 솔루션 파일이 어디 있는지 확인해서 해당 내용을 적용해주면 된다.

configuration 부분은 전체 빌드 형태를 결정해준다. Debug 모드인지 Release 모드인지 등을 결정하는 것이다.

excutable에는 이 빌드 작업을 수행할 프로그램을 선택한다. x64나 기타 다른 위치에 설치 하지 않았다면 위의 경로로 넣으면 된다. 만일 틀리다면 devenv.com이 있는 위치를 찾아

넣어주도록 한다.

나머지는 필자도 잘 모르지만 일단 테스트해 본 결과 저 정도로 마무리 지으면 일단 제정신으로 도는 것 같다.

 

위의 XML 부품을 구성하고 이해했다면, 이제 ccnet.config 안에 끼워 넣도록 한다.

이 부품은 다음의 경로에 추가해주면 된다.

//cruisecontrol/project/tasks

경로라고 말한 부분은 바로 엘리멘트 트리 순서이다.

XML로 표현하면 다음과 같은 구성이 되어줘야 한다는 것이다.

     <cruisecontrol>

        <project ...>

           <tasks>(여기를 의미하는 것)</tasks>

        </project>

     </cruisecontrol>

우리 원본 ccnet.config에 보면 tasks 라는 엘리멘트를 볼 수 없는데, 이 부분은 추가해줘야 한다.

자, 이렇게 해서 조립하면 다음과 같은 ccnet.config가 된다.

 

<!--<ccnetconfig><configurationVersion>1.4</configurationVersion></ccnetconfig>-->
<cruisecontrol>
  <project name="CQWorkflowViewer">
    <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
    <artifactDirectory>E:\Builds\CQWorkflowViewer</artifactDirectory>

    <tasks>

<devenv>
                <solutionfile>"E:\Builds\CQWorkflowViewer\Works\CQWorkflowViewer.sln"</solutionfile>
                <configuration>Debug</configuration>
                <buildtype>Build</buildtype>
                <executable>"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com"</executable>
                <buildTimeoutSeconds>90</buildTimeoutSeconds>
 </devenv>

    </tasks>
    <sourcecontrol type="svn">
      <trunkUrl>file:///D:/Works/000.MySVN/CQWorkflowViewer</trunkUrl>
      <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
      <executable>C:\Program Files\VisualSVN\bin\svn.exe</executable>
    </sourcecontrol>
    <triggers />

  </project>

</cruisecontrol>

 

테스트 결과 파일 삭제하기.

MS Test를 돌리게 되면 그 결과물을 XML 형태로 만들어 주게 되는데, 이 파일이 위치해 있으면 MS Test가 무조건 실패하게 된다.

그래서 MS Test를 동작 시키기 전에 반드시 해당 파일이 있으면 낼름 지워주는 기능을 하는 배치 파일(.Bat 또는 .Cmd)을 만들어 주도록 한다.

실제 이 결과물이 어디에 저장되는지는 다음에 정의할 MS Test 관련 설정을 할 때 결정되는데, 여기서는 그 결과물이 테스트 프로젝트가 있는

위치에 저장된다는 가정하에 설정하도록 하겠다.

먼저 적당한 위치에 .Bat 도는 .Cmd를 만든다. 여기서는 E:\Builds\CQWorkflowViwer 폴더에 deleteReport.bat라는 파일을 만들도록 하겠다.

그 내용은 다음과 같다.

IF EXIST E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer\testResults.trx DEL /f E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer\testResults.trx

원리는 간단하다. 파일이 있으면 지우고 없으면 지우지 않는다. 뭐 그정도?

그리고 난 뒤에 위에서 만든 작업 처럼 이번 것도 작업으로 만들어 준다.

이번에는 단순히 실행만 하면 되므로 devenv 엘리멘트가 아닌 exec 엘리멘트를 사용한다.

이 엘리멘트로 구성하면 다음과 같이 만들 수 있다.

<exec executable="deleteReport.bat">
   <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
   <buildArgs></buildArgs>
</exec>

특별한 설명은 필요 없지만, 일단 간단하게 각 엘리멘트 및 속성 값을 설명하면 아래와 같다.

exec는 이 작업이 단순 실행하는 작업을 의미하는 것이다. 실행할 내용은 executable 이라는  속성값에 값을 넣으면 된다.

baseDirectory는 이 실행이 진행되는 위치를 의미한다.

이 내용을 지금까지 만든 설정 파일이 추가해 보자. tasks는 앞서 만들었으니 이제 그 다음에 넣어주면 될 것이다.

<!--<ccnetconfig><configurationVersion>1.4</configurationVersion></ccnetconfig>-->
<cruisecontrol>
  <project name="CQWorkflowViewer">
    <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
    <artifactDirectory>E:\Builds\CQWorkflowViewer</artifactDirectory>

    <tasks>

<devenv>
                <solutionfile>"E:\Builds\CQWorkflowViewer\Works\CQWorkflowViewer.sln"</solutionfile>
                <configuration>Debug</configuration>
                <buildtype>Build</buildtype>
                <executable>"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com"</executable>
                <buildTimeoutSeconds>90</buildTimeoutSeconds>
 </devenv>   

      <exec executable="deleteReport.bat">
         <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
         <buildArgs></buildArgs>
      </exec>

</tasks>   

<sourcecontrol type="svn">
      <trunkUrl>file:///D:/Works/000.MySVN/CQWorkflowViewer</trunkUrl>
      <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
      <executable>C:\Program Files\VisualSVN\bin\svn.exe</executable>
</sourcecontrol>

      <triggers />

  </project>

</cruisecontrol>

 

MS Test 동작시키기.

모든 준비작업은 끝났다. 이제 실제적으로 동작해야하는 작업을 수행한다.

이번에는 MSTest를 동작시킨다. 이를 위해서 하는 방법은 위의 방법과 거의 동일하다.

단지, 몇가지 MSTest를 동작시키기 위한 파라미터 값만 조정하면 된다.

<exec executable="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\mstest.exe">
   <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
   <buildArgs>/testcontainer:bin\debug\TestProjectCQWorkflowViewer.dll  /resultsfile:testResults.trx</buildArgs>
   <buildTimeoutSeconds>90</buildTimeoutSeconds>
</exec>  

 

앞서 테스트 결과 삭제 목록의 내용 중에서 특이 점은 buildArgs 부분에 파라미터 값들이 정의된다는 사실이다.

테스트를 동작시키기 위한 DLL 정보와 테스트 결과를 저장하기 위한 그 리포트 출력용 파일 이름 정도이다.

실행할 주체가 mstest.exe 인 C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\mstest.exe 정도 뿐이다.

여기서 경로등을 주의해서 넣어주면 된다.

만일 mstest의 특별한 기능들이 더 필요한 경우 http://msdn.microsoft.com/en-us/library/ms182489%28VS.80%29.aspx 를 참고해서

파라미터 값들을 조정해주면 된다.

이를 추가하면 아래와 같이 된다.

<!--<ccnetconfig><configurationVersion>1.4</configurationVersion></ccnetconfig>-->
<cruisecontrol>
  <project name="CQWorkflowViewer">
    <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
    <artifactDirectory>E:\Builds\CQWorkflowViewer</artifactDirectory>

    <tasks>

<devenv>
                <solutionfile>"E:\Builds\CQWorkflowViewer\Works\CQWorkflowViewer.sln"</solutionfile>
                <configuration>Debug</configuration>
                <buildtype>Build</buildtype>
                <executable>"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com"</executable>
                <buildTimeoutSeconds>90</buildTimeoutSeconds>
 </devenv>   

      <exec executable="deleteReport.bat">
         <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
         <buildArgs></buildArgs>
      </exec>

<exec executable="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\mstest.exe">
   <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
   <buildArgs>/testcontainer:bin\debug\TestProjectCQWorkflowViewer.dll  /resultsfile:testResults.trx</buildArgs>
   <buildTimeoutSeconds>90</buildTimeoutSeconds>
</exec>

</tasks>   

<sourcecontrol type="svn">
      <trunkUrl>file:///D:/Works/000.MySVN/CQWorkflowViewer</trunkUrl>
      <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
      <executable>C:\Program Files\VisualSVN\bin\svn.exe</executable>
</sourcecontrol>

      <triggers />

  </project>

</cruisecontrol>

 

 

리포트 결과를 CCNet에 보고하기.

이제 마지막 부분이다. 위의 내용 까지는 최종 테스트 결과물을 만드는 과정이다. 이제 그 테스트 결과물을 빌드 결과물로써 나타내게 해주면 된다.

지금까지는 tasks 안에 들어갔지만, 이번에는 tasks 밖에서 publishers 라는 엘리멘트 안에 작업을 해주어야 한다.

기본적인 작업들이 들어가는데, 그 중 추가적인 작업 결과물은 여기서 처리해주어야 한다.

결론적으로 해당 처리를 위한 XML은 아래와 같다.

<publishers>
   <merge>
      <files>
         <file>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer\testResults.trx</file>
       </files>
   </merge>
   <xmllogger />

</publishers>

 

publishers 나, merge, files은 XML 형식에 맞추기 위해 필요한 내용이고, xmllogger는 다른 기능을 위해 준비된 내용이다.

우리가 집중할 부분은 file 부분으로 이 안에 xml 형식으로 된 리포트 파일만 걸어주면 된다. 앞에서 예제로 설정한 내용을 기준으로 본다면,

테스트 작업 후, E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer\testResults.trx 라는 파일이 생기게 된다.

 

자 이것을 추가하면 아래와 같이 정리된다.

<!--<ccnetconfig><configurationVersion>1.4</configurationVersion></ccnetconfig>-->
<cruisecontrol>
  <project name="CQWorkflowViewer">
    <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
    <artifactDirectory>E:\Builds\CQWorkflowViewer</artifactDirectory>

    <tasks>

<devenv>
                <solutionfile>"E:\Builds\CQWorkflowViewer\Works\CQWorkflowViewer.sln"</solutionfile>
                <configuration>Debug</configuration>
                <buildtype>Build</buildtype>
                <executable>"C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\devenv.com"</executable>
                <buildTimeoutSeconds>90</buildTimeoutSeconds>
 </devenv>   

      <exec executable="deleteReport.bat">
         <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
         <buildArgs></buildArgs>
      </exec>

<exec executable="C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\mstest.exe">
   <baseDirectory>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer</baseDirectory>
   <buildArgs>/testcontainer:bin\debug\TestProjectCQWorkflowViewer.dll  /resultsfile:testResults.trx</buildArgs>
   <buildTimeoutSeconds>90</buildTimeoutSeconds>
</exec>

</tasks>   

<sourcecontrol type="svn">
      <trunkUrl>file:///D:/Works/000.MySVN/CQWorkflowViewer</trunkUrl>
      <workingDirectory>E:\Builds\CQWorkflowViewer\Works</workingDirectory>
      <executable>C:\Program Files\VisualSVN\bin\svn.exe</executable>
</sourcecontrol>

      <triggers />

<publishers>
   <merge>
      <files>
         <file>E:\Builds\CQWorkflowViewer\Works\TestProjectCQWorkflowViewer\testResults.trx</file>
       </files>
   </merge>
   <xmllogger />

</publishers>

 

  </project>

</cruisecontrol>

 

이제 실제로 서버를 실행해 보면, MSTest까지 수행하고 그 결과 값에 따라 Build 성공 실패가 보이기 시작할 것이다.

 

PS. 웹에서 이 결과 리포트를 보고 싶을때.

굳이 필요한 기능은 아니지만, 빌드 결과물을 보여주는 웹화면에서 이 Test 결과 내용도 보고 싶다면 추가적인 작업을 해야 한다.

CCNet의 웹을 띄우기 위해서는 http://<<서버이름>>/ccnet 이라고 치면 된다.(설치 중 Web Url을 변경하거나 조작한 경우 다른 이름이 될 수 있다.)

그래서 화면이 뜨면 각종 리포트를 위한 웹 화면을 볼 수 있는데, 그 중 이 Test 결과도 볼 수 있다.

그러나 MS Test는 기본 값이 아니기 때문에, 이 리포트용 웹사이트에 한가지 작업을 더 수행해주어야 한다.

 

작업을 하려면, 맨 먼저 해당 웹사이트가 있는 폴더로 이동한다.

CCNet이 설치된 폴더에서 webdashboard 라는 폴더이며, 그 안에 있는 dashboard.config 파일을 열도록 한다.

 

그리고 <xslReportBuildPlugin description="....... > .... </xslReportBuildPlugin> 항목들이 쭉 늘어선 곳에다 다음 줄을 추가한다.

    <xslReportBuildPlugin description="MSTest Report" actionName="MSTESTReport" xslFileName="xsl\MsTestSummary.xsl"/>

SNAG-0050.png

 

이제 다시 웹을 띄운 후 프로젝트를 클릭해서 들어간다.

SNAG-0053.png

오른편쪽에 항목들 중 자신이 실패한 빌드 번호를 클릭한다.

SNAG-0054.png

이번엔 왼편에 Report나 Log 목록들이 있는데 그 중 MsTest Report를 클릭한다.

SNAG-0055.png

 

오른편에 해당 오류가 발생한 내용이 표시된다.

SNAG-0056.png

 

이 글은 스프링노트에서 작성되었습니다.

Posted by 하인도

설치 및 구성하기.

설치 쪽은 최재훈 님께서 마이크로스프트웨어에 기고했던 글을 참고하면 된다.

http://kaistizen.net/EE/index.php/imaso/continuousintegration_2008_04/

 

일단 기본적으로 설치하면 각 사용할 파일들은 C:\Program Files 위치에 저장된다.(x64에서는 다른 위치에 저장될 수 있지만, 아직 테스트 해보지 않았음)

맨처음 CCNet 서버를 설치하면 설치 완료 후 별다른 반응을 보이지 않는다.

시작 -> 모든 프로그램 -> CruiseControl.NET -> CruiseControl.NET 을 실행하면 도스 창에 무언가 버글 버글 뜨고, 화면이 멈춰 있는 것을 볼 수 있다.

SNAG-0030.png
이게 콘솔 화면으로 띄우는 CCNet 인데, 설정 디버그나 결과들을 확인하고 싶을 때 이렇게 해서 확인하면 된다.

만일 설정 파일이나 설정 정보가 안정적으로 동작한다고 생각된다면, 이런 식의 도스 창 같은 것을 띄우지 않고 서비스로 동작하게 할 수 있다.

시작 -> 제어판 -> 관리 도구 -> 서비스 에 들어가서 CruiseControl.NET Server 서비스를 시작해 주면 된다.

SNAG-0031.png

만일 서버 리붓후에도 계속 켜지게 하고 싶은 경우에는 시작 유형을 수동에서 자동으로 변경해주면 된다.

 

주의 : 만일 서비스 상태로 띄우다가, 도스창(디버그용)을 띄우면 안된다. 만일 도스창용으로 띄우고 싶으면, 반드시 서비스로 동작 중인 CCNet을 죽이고수행해야 한다.

 

설정 파일 구성하기

CCNet 의 설정파일은 C:\Program Files\CruiseControl.NET\server 폴더 안에 있다. 파일 이름은 ccnet.config 라는 이름으로 되어 있으며, 이 안의 값을 어떻게 정의하냐에 따라, 빌드 서버가 어떻게 동작하는지를 결정하게 된다. 모든 내용은 XML 기반으로 구성되어 있어, 가독성에서 꿀리는 부분은 없다.

그.러.나. 이 안의 각 Element 들이 어떻게 들어가는지 값들이 어떻게 들어가는 지에 대한 설명은 모두 영어로 된 도움말의 도움을 받아야 한다.

http://confluence.public.thoughtworks.org/display/CCNET/Configuring+the+Server 를 보게 되면, 설정 파일 내에 설정할 수 있는 다양한 내용들이 있다.

간단하게 테스트 하는 수준이였다면, 내가 찾아들어간 방식대로 한번 시도 해보자.

 

  1. CCNetConfig 프로그램 실행하기.

    앞서 언급한 프로그램 중 하나이다. 설정 파일인 XML 파일을 설정하는데 Visual Studio의 속성값 편집하듯이 편하게 구성되어 있다.
    물론 전체적인 내용이 딱 한눈에 안들어오긴 하지만, 이 정도의 가이드가 있다면 큰 도움이 될 것이다.

    실행하면 아래와 같은 화면이 떨렁 나올 것이다.
    SNAG-0032.png
    당황하지 말고 File -> Open을 해서 C:\Program Files\CruiseControl.NET\server 폴더 안의 ccnet.config 파일을 선택한다.

    Open 할때, OpenFileDialog 에서 아래쪽에 있는 Version을 꼭 선택해주시기 바란다. 현재 CCNet이 설치된 버전을 확인해서,
    1.1인지, 1.2 인지..아니면 1.4 인지를 꼭 체크해서 그에 맞는 버전을 선택한다.
    SNAG-0033.png

    열리면 아래와 같이 왼쪽에 트리 형태의 내용이 뜨게 된다.
    SNAG-0034.png

  2. 새로운 프로젝트를 추가하기.
    자 이제 실제 Build 작업을 수행할 프로젝트를 선택한다. File 이라는 메뉴 아래에 있는 아이콘을 선택하거나 CruiseControl 이라는 항목에서 오른쪽 버튼을 눌러 컨텍스트 메뉴에서 프로젝트 추가를 하던 어떤 식이든 Add Project를 하도록 한다.
    SNAG-0035.png
    프로젝트 이름을 입력하는 창에 이번에 Build 할 솔루션 이름을 넣는다. (달라도 되는지는 테스트 해본적이 없어서 -_-;;)
    SNAG-0036.png
  3. 프로젝트 기본 속성값 넣기.
    이제 프로젝트에 대한 기본 속성값을 넣도록 한다. 왼쪽 트리에서 입력한 프로젝트 명을 클릭하면 오른쪽에 속성 창이 뜬다.
    SNAG-0038.png  
    언어적 장벽이 큰 문제가 없다면 아래쪽 간단한 설명을 도움받아 값을 넣어주면 된다. 
    이 중 최소 컴파일이 되기 위한 내용들을 채워보자면 다음과 같다.
    여러가지 내용들이 들어갈 수 있지만 최소 다음 내용 정도를 채우면 된다.

    • (Name) : 이름. 제일 중요하기도 하지만, 프로젝트 만들때 결정되니까 가급적 손대지 말았으면 좋겠다.
    • ArtifactDirectory : 프로젝트에 대한 산출물 디렉토리. 상대 경로로 설정되어 있다면 CruiseControl.NET 서버가 설치되어 있는 디렉토리에 프로젝트 이름을 기준으로 구성된다. 산출물 디렉토리는 빌드 로그, 배포물 등등 빌드의 결과물로 저장될 내용들이 저장되는 장소이다. 가급적 이 폴더는 프로젝트 별로 틀리게 설정해주어야 빌드에 대한 각종 결과물들이 정상적으로 보이게 된다. 단 경로를 입력할 때 중간에 공백이 들어가 있더라도 쌍따옴표 표시(")는 필요없다.
    • SourceControl : 소스 버전 관리 도구에 대한 설정을 한다. 이 CCNet에서 자동으로 최신버전을 받아서 빌드를 수행할 때 소스를 받게되는 위치를 의미한다.
    • WorkingDirectory : 프로젝트에 대한 작업 디렉토리. The Working Directory for the project (this is used by other blocks). 상대 경로로 설정되어 있다면 CruiseControl.NET 서버가 설치되어 있는 디렉토리에 프로젝트 이름을 기준으로 구성된다. 작업 디렉토리는 통합 수행을 하는 프로젝트에서 체크아웃된 버전을 포함한다. 이 경로는 프로젝트 별로 틀리게 설정해주어야 빌드시 오류가 발생되지 않는다.  단 경로를 입력할 때 중간에 공백이 들어가 있더라도 쌍따옴표 표시(")는 필요없다.    
  4. 채운 내용을 예제로 캡처한 내용이 다음과 같다.
    (각 값은 필자 프로젝트를 기준으로 맞춘 내용이므로 적절히 자신의 환경에 맞게 구성해 주어야 한다. )
    프로젝트 명 : CQWorkflowViewer

    산출물 디렉토리 : E:\Builds\CQWorkflowViewer
    작업 디렉토리 : E:\Builds\CQWorkflowViewer\Works
    소스버전관리 : SubVersion,
        - 서브 버전 프로그램 위치(소스버전관리 형태에 따라 다름) : C:\Program Files\VisualSVN\bn\svn.exe
        - 서브버전 URL : file:///D:/Workfs/000.MySVN/CQWorkflowViewer
        - 소스 처리 경로 : E:\Builds\CQWorkflowViewer\Works
    SNAG-0039.png

  5. 저장 버튼을 눌러 저장한다.

 

동작 확인

구성이 완료되었으면 이 빌드가 정상적으로 동작하는지 꼭 확인하도록 한다.

서버를 무작정 동작시키진 말고, 콘솔 모드로 동작하게 끔 한다.

    시작 -> 모든 프로그램 -> CruiseControl.NET -> CruiseControl.NET

을 클릭해서 실행한다. 

일단 서버는 레디상태. 자 이제 실제 빌드를 강제 동작시켜 본다.

 

이 때 간단하게 시도해 볼 수 있게 해주는 도구가 바로 CCTray 이다.

CCTray를 일단 설치해 놓고 무조건 실행해보자. 그러면 화면 오른쪽 아래에 CC 라는 아이콘이 보인다.

SNAG-0040.png

거기서 오른쪽 버튼을 클릭해서 열어 보면 메뉴가 나오는데 그 중 Settings에 들어간다.

SNAG-0041.png

설정 화면이 뜨면 거기서 Add 버튼을 클릭해서 들어간다.

SNAG-0042.png

 

빌드 서버가 몇개든, 프로젝트가 몇개든, 여기서 Add를 통해 계속 추가해주면 된다.

이제 설정 화면이 뜨는데, 그 안에 서버를 추가해주면 된다. Add Server 버튼을 클릭한다.

SNAG-0043.png

Add Server 버튼을 클릭하면 총 3가지 유형의 서버를 선택할 수 있다. 원격에서 CCNet 서버를 접근하는 방법을 넣는 방법들인데,

IIS를 이용하여 접속하여 CCNet에서 제공하는 Dashboard 사이트를 통해서 접근하는 방법.

.NET Remote 기법을 이용하여 직접 연결하는 방법(이 때는 포트를 21234를 사용한다.)

CCNet 이 아닌 CC for Java 같은 솔루션  접근을 위해 HTTP GET 메소드를 사용하는 특별한 페이지들을 이용하여 접근하는 방법이 있다.

대개의 경우는 2번째 방법을 통해 접근하는게 좋다. (첫번째 방법으로 해보지는 못했다.)

SNAG-0045.png

자 그럼 서버 목록에 서버가 하나 추가되었고, 그 서버에서 Build 처리가 가능한 프로젝트가 하나 뜨게 된다.

즉 CCTrary에서 제어할 프로젝트(빌드 서버내에 다양한 프로젝트를 넣을 수 있으므로)를 선택적으로 적용할 수 있게 된다.

SNAG-0046.png

자 OK 해서 일단 설정 창을 닫고 다시 CCTray 아이콘을 더블 클릭하거나 메뉴에서 Show Status Window를 클릭하도록 한다.

그러면 아래와 같은 창이 뜨면서 아까 선택한 서버의 프로젝트가 트리형식으로 나타난다.

SNAG-0047.png

자 이제 추가한 프로젝트를 선택한 후 Force Build를 클릭하도록 한다.

만일 실패하면 CC 아이콘이 빨개 지고, 성공하면 녹색으로 나오게 된다.

 

도스 창을 보게 되면 처음에 대기화면에서 무언가 화면 가득 쌓여 있다. 아이콘이 빨갛게 된 경우에는 반드시 그 오류 내용을 도스창을 통해 찾아보도록 한다.

SNAG-0048.png

 

주의!

여기서는 설정 오류 뿐만 아니라, 빌드 하다가 발생되는 오류나, 기타 등등 다양한 사유에서 발생되는 모든 형태의 오류로 인해 아이콘이 빨개진다.

반드시 정상적으로 빌드 되는 소스를 가지고 테스트를 진행하도록 한다.

그래야 설정이 정상적이라는 것을 믿고 진행할 수 있는 것이다.

하다 못해 윈도우 창만 떨렁 띄우는 프로젝트라도 미리 컴파일 해서 아무 이상이 없는지 꼭 확인해주도록 한다.

 

성공하면 아래화면 처럼, 맨 믿줄에 Integration complete: Success로 뜨고 아이콘도 녹색으로 바뀐다.

SNAG-0049.png

이 글은 스프링노트에서 작성되었습니다.

Posted by 하인도

애자일 방법론들을 가만히 보면 몇가지 공통 사항이 있다.

가장 특징적인 하나는 TDD(Test Driven Developing)이고 다른 하나는 CI(Continuous Inegration)이다.

전자는 일단 범위도 넓고, 중요도도 무척 높지만, 여기까지 언급하기에는 범위외이기 건너간다.

 

CI란  지속적인 통합 빌드로 주기적으로 계속 통합하여 빌드를 유지하는 것이다.

이게 중요한데, 개인이 만드는 소프트웨어에 자신의 IDE 도구들을 사용하여 필요할 때마다 빌드를 하고 테스트를 하겠지만,

팀 단위의 개별 개발을 할 때는 전혀 다른 문제다. 대부분 CI를 하지 않는 곳에서는  BingBang 빌드라고 하여,

특정시점(중간 통합 단계)에 다른 이들의 코드를 한꺼번에 싣는 작업을 수행하곤 한다. 운좋으면 짧은 시간에 완성할 수 있겠지만,

대부분은 컴파일 부터 오류가 발생되어 모두 나자빠지고 그 부분의 수정에 온 힘을 기울이게 된다.

(특히 의존성이 높은 클래스나 컴포넌트의 수정으로 인해 발생되는 오류들이 무척 많은 편이다.)

그렇다고, 매번 누군가가 최신버전을 다운 받은 후 매일 매일 빌드하는 짓도 곤혹스럽다. 바로 이런 작업을 수행하는 도구를 필요로 했다.

 

맨 처음에는 이 도구를 개발할까 생각했다.

혼자 이런 저런 기능을 파악하고, Visual Studio의 프로젝트 파일을 열어 이런 저런 조사를 하면 뭔가 나오지 않을까 했다.

하지만, 생각보다 내용도 많고, 범위도 컸다. 최소한의 기능만으로 만든다고 해도, SCRUM - 30d 기준으로 2~3 sprint(약 3달)정도의

개발 공정이 필요했다. 게다가 당장 확장을 하려면 이 또한 큰 작업이 될 공산이 컸다.

이 때 우연히 찾은 도구가 있는데, 바로 CruiseControl.NET 이였다.

 

링크 따라가기

아무 생각 없이 찾았던 도구인데, 링크에 링크를 따라가다 찾게 되었다.

맨 처음에는 SCRUM 관련 자료를 찾는 도중 애자인 인 여의도라는 블로그에서 허드슨(CS Server Hudson) 이라는 도구를 보여주었다.

이건 뭐야 하는 마음에 허드슨 관련 자료를 찾다가 이번엔 Toby's Epril 이라는 블로그를 통해  Atlassian 이라는 회사를 알게 되었다.

이건 또 뭐야 하면서 무슨 솔루션 이름인 줄 알았는데 알고 보았더니 각종 제품 및 도구를 만드는 회사였다.
게다가 이번에 읽고 있는 Scrum and XP from the Trenches에 보면 각 Sprint와 Task 정보를 Jira 라는 도구로 일부 저장 관리 한다고 했다.

Jira라는 도구를 만든 회사가 바로 이 Atlassian 이라는 회사였다.  이번에는 이 회사에서 만든 CI 도구가 있는데,

애석하게도 라이센스가 있었다. 가격을 지불해야 했고, 몇가지 조정적인 작업이 필요했다.

지금 있는 회사에서도 범용적으로 빌드 관리할 때 사용되는 Build Forge라는 제품을 판매하고 있다. - 즉 굳이 이런 도구 찾을 필요는 없었을 것이다. -

 

하지만, 애석하게도 그 놈의 Build Forge가 다양한 플랫폼에 다양한 형태의 Build를 제공해야 하기 때문에, 조작이 감이 딱 오지 않았다.

더 결정적인 것인 그 놈의 툴의 가격이 예술을 넘어 사치품에 가깝게 만들어 버렸다. 많아봐야 나 혼자쓰는데 이건 좀 너무 하다 싶었다.

 

결국 Atlassian에서 만든 CI나 Build Forge나 일단, 가볍게 동작하며 라이센스에 연연하지 않아도 될법한 제품을 찾아야 됬다.

어차피 개인 내지 많아봐야 1~2명만 쓸 예정이기에 굳이 다양한 기능 보다는 어느 정도 통합빌드를 지속적으로만 할 수 있으면 되겠다는 생각에 찾기 시작했다.

검색어를 Continuous Integration .NET 으로 찾아보았고,

그 결과 찾은 것이  CruiseControl.NET 이였다.

 

특징.

일단 Open Source License 정책을 가지고 있다. 그래서 배포나 구성에 있어 제약이 없었다. 그리고 .NET 기반의 프로젝트를 간단하게 빌드 할 수 있고,

설치 프로그램도 의외로 작았다. 다양한 버전 관리 도구들과 연결 되어 Build 전 최신 버전, Base Line의 Source를 알아서 가져와, 필요할 때 원하는 만큼

Build를 수행할 수 있다. 다양한 외부도구들을 지원해 가장 마음에 드는게 바로 Tray Icon으로 나오는 CCTray라는 프로그램이였다.

필요시 원격에서 강제로 Build를 할 수도 있고, 현재 맨 마지막 Build 결과도 바로 확인할 수 있다.

관리자들이 참 좋아하는 빌드 깨트린 자가 누구인지도 명확히 찾을 수 있다. ㅋ

 

다운 받는 곳.

CCNet은 SourceForge 중 CCNet 프로젝트에서 다운 받는다.

    http://confluence.public.thoughtworks.org/display/CCNET/Welcome+to+CruiseControl.NET

각 버전 별로 나열되어 있는데, 특정 버전을 선택하면 아래 쪽에 관련 프로그램 별로 다운 받을 수 있는 링크들이 나온다.

CruiseControl.NET-1.X.X-Setup.exe 라고 적힌 파일이 바로 이 CCNet 서버의 내용으로 이 파일은 반드시 다운 받도록 한다.

CruiseControl.NET-CCTray-1.X.X-Setup.exe라고 적힌 파일도 다운 받는데, 이 파일이 원격에서 CCNet 서버의 정보를 확인하거나 강제 빌드 시킬 수 있도록 하는 실시간 원격 확인 도구이다.

 

일단 위의 파일들이 준비되었으면 이번에는 CCNet 설정을 쉽게 도와주는 도구인 CCNet Config라는 도구를 다운받는다.

  http://ccnetconfig.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=17322#DownloadId=43769

CCNet 서버 설정은 모두 XML 형식으로 정의하게 끔 되어 있는데, 처음부터 이 XML 형식의 내용을 넣기에는 메뉴얼 보면서 넣기가 영 귀찮고 힘들다.
(어느정도 익숙해지면 쉽다고는 하는데, 그닥... 감은 안온다.) 그래서 위의 도구를 다운 받아 설치하도록 한다.

 

 

이 글은 스프링노트에서 작성되었습니다.

Posted by 하인도

원문 : http://www.codeproject.com/KB/tips/autovssbackup.aspx

Visual Source Safe의 기능은 최소한 MS Visual Tool을 사용하고 있다면 모두 반 불가항력으로 사용하고 있다. ( 물론 돈 많은 회사에서는 IBM Rational의 Clear Case 같은 도구를 사용할 수 있을지도 모르겠다 ). 그런데 관리도구를 보면, MS의 전형적인 귀차니즘이 묻어 나서 백업 도구의 부실함을 확인할 수 있다. 물론 Release 서버를 별도 구축하여, Release만 담당하는 사람이 있다면, 관리도구를 그 사람이 스스로 일정 시간마다 할 수 있을지 모르겠지만,
조그만한 회사에 조그만한 팀에서 운영한다면, 이런 작업은 또하나의 작업으로 환생하여, 누군지 모를 프로그래머 한명 또는 다수가 묘한 프레샤를 받게 된다. ( 만에 하나 VSS DB가 날라가서 백업을 원복하는데, 백업 과정을 제대로 수행하지 않음이 밝혀지면, 온 지탄의 눈길을 한눈에 받을 지도 모른다. )

그래서 자동으로 백업해줄 만한 솔루션을 찾다가, 코드 프로젝트 쪽에서 백업 기능을 일정 케쥴에 맞추어 수행할 수 있도록 하는 기능을 구성한 분이 있어, 그 내용을 적어보도록 한다.
( 해외 사이트의 글이지만, 엄연한 불펌이므로, 이 글을 재가공은 가급적 자제해주시기 바랍니다. -_-;;;;; 원문을 최대한 활용해 주세요.  [ I'm too sorry about capturing the documents by illegally. I'm very very sorry )

1. 백업용 배치 파일 만들기.

다음 텍스트를 .BAT 또는 .CMD 파일로 만든다.

1: @ECHO OFF
2: @TITLE Backing up source safe databases
3: FOR /F "tokens=2-4 delims=/ " %%i IN ('date /t') DO SET DATE=%%i-%%j-%%k e:\source_safe-code\win32\ssarc -d- e:\backups\%DATE% General backup.ssa $/General
4: @ECHO Finished backups

* 위의 항목 중 "숫자:" 부분은 줄 수를 가르키기 위한 부분이다. 실제 코드는 1:, 2:, 3:, 4: 는 빼고 나머지 부분을 넣는다. 각 줄 끝은 ENTER 키를 꼭꼭 넣는다. 일단 위와 같이 만들어 준다.

위와 같은 내용을 .BAT 혹은 .CMD 파일을 만들었으면, 자신의 Source Safe가 설치된 내용에 맞게 수정하는 작업을 한다. 그 핵은 3번째 줄에 있다.

먼저 해당 문장을 살펴보면 아래와 같이 진하게 표시된 부분을 수정해야 한다.

FOR /F "tokens=2-4 delims=/ " %%i IN ('date /t') DO SET DATE=%%i-%%j-%%k e:\source_safe-code\win32\ssarc -d- e:\backups\%DATE% General backup.ssa $/General

진하게 칠해진 부분에 Souce Safe 데이터 베이스가 위치한 경로를 넣어주도록 한다. 보통 ssafe.ini 파일이 있는 위치를 가르키면 된다.

그리고 난 뒤에 아래와 같이 진하게 표시된 부분도 수정한다.

FOR /F "tokens=2-4 delims=/ " %%i IN ('date /t') DO SET DATE=%%i-%%j-%%k e:\source_safe-code\win32\ssarc -d- e:\backups\%DATE% General backup.ssa $/General

진하게 칠해진 부분이 백업 결과물을 저장할 위치를 의미한다. 적당한 경로를 설정해서 수정한다.

2. 스케쥴 만들기.

시작 -> 제어판 -> 예약된 작업 -> 예약 작업 추가 를 한다.

예약 추가 마법사가 시작되면 "다음" 버튼을 클릭한다.

작업을 실행할 프로그램 선택화면에서 "탐색" 버튼을 클릭한다.

탐색 창에서 자신이 만든 .BAT 혹은 .CMD 파일을 선택한다.

일정을 어느 스타일로 할 것인지 결정한다. ( 매일, 매주, 매월 등등 다양한 스타일이 있다. - 예제 화면으로는 "매일" 스케쥴을 선택한 것으로 보여준다. )

세부 스케쥴을 설정한다. 시간이나, 요일 등을 설정하게 된다.

이 프로그램을 실행할 계정을 선택한다. Source Safe 데이터베이스의 모든 파일을 쉽게 접근할 수 있는 계정으로 설정한다. 암호도 올바르게 넣어준다.

완료가 되었으면 "마침"을 클릭하면 자동으로 저장되며 스케쥴 설정대로 실행되게 된다.

Posted by 하인도

참조 추가 대화 상자에 어셈블리를 표시하는 방법

기술 자료 ID : 306149
마지막 검토 : 2006년 9월 1일 금요일
수정 : 4.0

요약

Visual Studio .NET에서 클래스 라이브러리를 개발할 때 라이브러리를 직접 찾지 않고도 .NET 탭의 참조 추가 대화 상자에 자동으로 표시할 수 있습니다.

그러나 GAC(전역 어셈블리 캐시)에 어셈블리를 추가할 경우 참조 추가 대화 상자가 경로를 기반으로 하고 GAC의 구성 요소를 열거하지 않으므로 이렇게 할 수 없습니다.

참조 추가 대화 상자에 어셈블리를 표시하려면 어셈블리 위치를 가리키는 다음과 같은 레지스트리 키를 추가하면 됩니다.
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework\AssemblyFolders\MyAssemblies]@="C:\\MyAssemblies"
여기서 MyAssemblies는 어셈블리가 들어 있는 폴더의 이름입니다.

참고: HKEY_LOCAL_MACHINE 하이브 아래에 이 레지스트리 항목을 만들 수 있습니다. 이렇게 하면 시스템에 있는 모든 사용자에 대한 설정이 변경됩니다. HKEY_CURRENT_USER 아래에 이 레지스트리 항목을 만들면 현재 사용자에 대한 설정만 변경됩니다.

이 키를 추가한 후에는 Visual Studio .NET을 다시 시작하십시오.

추가 정보

시스템에서 실행 중인 다른 응용 프로그램과 어셈블리를 공유하지 않으려면 GAC에 어셈블리를 추가하지 않는 것이 좋습니다. 또한 프로젝트에서 GAC의 어셈블리를 직접 참조할 수도 없습니다. GAC의 어셈블리를 사용하려면 로컬 폴더로 어셈블리를 가져온 다음 이 폴더에서 어셈블리에 대한 참조를 추가해야 합니다. 로컬 시스템에 있는 프로젝트 폴더로 어셈블리를 복사하지 않으려는 경우에는 해당 어셈블리의 로컬 복사 속성을 False로 설정할 수 있습니다. 런타임에 응용 프로그램은 GAC의 어셈블리를 사용합니다.
Posted by 하인도