'Useful Solutions'에 해당되는 글 32건

  1. 2014.09.26 구관이 명관 – 어느 위치에서 실행하든 경로를 유지하는 배치 파일 만들기
  2. 2014.06.07 Visual Studio 테스트, 어렵지 않아요
  3. 2013.11.16 Visual Studio 2013에서 ASP.NET 프로젝트가 만들어지지 않는 경우
  4. 2012.12.24 동일 IP 주소를 사용하는 가상 호스트를 로컬에서 테스트하기
  5. 2012.12.09 Live Connect Developer Center의 두 가지 다른 Application에 대한 이해
  6. 2012.10.26 ClickOnce의 문서화되지 않은 비관리 API 활용하기
  7. 2012.10.08 Photoshop 없이 PSD 파일의 레이어 추출하기
  8. 2012.10.05 x64 플랫폼에서의 System32 디렉터리에 대한 트릭
  9. 2012.08.08 무료 Microsoft eBook 컬렉션 (2)
  10. 2012.05.15 라우팅 및 원격 액세스 역할 설치 후 MMC 콘솔에 문제가 있을 때 해결 방법
  11. 2010.10.13 Client App Dev MVP가 엄선한 닷넷 개발 관련 무료 e-Book 7선
  12. 2010.08.14 구관이 명관! Batch File 활용 - Batch File도 반복문을 쓸 수 있다! & 디렉터리 경로 탐색 팁 [수정]
  13. 2010.01.15 구관이 명관! Batch File 활용 - 배치 파일로 프로그램을 작성하는데에 필요한 기본 사항 살펴보기
  14. 2009.08.31 구관이 명관! Batch File 활용 - 문자열과 숫자의 비교 (2)
  15. 2009.03.23 TortoiseSVN에서 제외할 파일/디렉터리 이름 패턴 (Delphi/VC++/.NET IDE)
  16. 2009.01.19 Informix, Oracle, MSSQL을 위한 테이블 구조 확인 SQL문
  17. 2008.12.17 Windows Update를 사용하려고 할 때 0x80072ee2 오류에 대한 대처 방법 (1)
  18. 2008.09.01 Windows 최적화: Icon Cache 크기 조절을 통한 메뉴 표시 속도 향상
  19. 2008.06.17 HwpCtrl ActiveX 컨트롤에 관한 문제점 해결 방안 두 가지
  20. 2008.03.27 Oracle Database 연결 병목 현상 해결
  21. 2007.11.12 Windows Server 2003 SP1 이상에서 Visual Studio 2005 SP1 설치 시 문제 해결 방법
  22. 2007.10.22 Delphi VCL TStatusBar의 Owner Draw 렌더링 문제 해결
  23. 2007.10.15 Windows Live Custom Domains 200% 활용하기
  24. 2007.08.09 외워두면 편리한 환경 변수들
  25. 2007.08.05 삽질 하나: rundll32.exe와 ~RunDLL 시리즈 함수들
  26. 2007.04.10 SysInternals.com의 유용한 Windows NT 관리자 도구 모음집
  27. 2007.02.03 sc.exe로 svnserve.exe를 NT 서비스로 직접 등록하는 방법
  28. 2006.12.25 Install Shield를 대체할 만한 무료 Install Builder (1)
  29. 2006.12.09 DB 연결 문자열 찾으러 멀리가지 마세요!
  30. 2004.11.19 Windows에서 자주 쓰이는 프로그램 하나
Useful Solutions2014. 9. 26. 09:39

오랫만에 구관이 명관 시리즈를 업데이트해봅니다. 이번 아티클은 작지만 확실히 유용한 팁 하나를 소개해볼까 합니다. 배치 파일을 작성하고 배포할 때 가장 큰 문제가 되는 것이, 배치 파일이 의도하지 않은 디렉터리 경로 상에서 실행된다는 점일 것입니다.

 

 

예를 들면 배치 파일을 명령어나 다른 프로그램을 이용하여 실행하면 배치 파일이 있는 경로가 아닌 호출한 프로그램의 현재 디렉터리 경로 위에서 실행되어서 문제가 될 때가 있습니다. 물론 배치 파일의 이런 특성을 활용해야 하는 경우도 있겠습니다만, 보통은 배치 파일을 실행할 때 정확히 해당 경로 상에서 어떤 작업을 하도록 의도한 것이 많으므로 이런 특성은 불편할 수 있습니다.

이 문제를 수정하려면 배치 파일의 경로를 항상 정확하게 알 수 있어야 하는데, 이럴 때 %~dp0 환경 변수를 사용하면 쉽게 문제를 해결할 수 있습니다. 하지만 무작정 cd 명령을 사용하면 배치파일이 끝나고 난 다음에 디렉터리 위치가 원래대로 돌아오지 않는 문제가 남습니다.

이런 문제를 해결하기 위하여, 새로 작성하는 배치 파일의 시작과 끝을 아래의 코드처럼 작성하도록 하면 편리할 것입니다.
@echo off
pushd "%~dp0"

rem 여기에 배치 파일 본문을 작성합니다.

:exit
popd
@echo on


 

내용은 단순합니다. 실행하는 명령줄이 보이지 않게 @echo off로 감추고, pushd 명령을 사용하여 스택에 현재 디렉터리 경로를 push하고 새 위치로 이동한 다음 원하는 일을 하는 것입니다. 그리고 나중에 종료할 때에는 popd 명령을 사용하여 직전에 저장한 디렉터리 경로를 꺼내와 그 위치로 다시 이동하고 @echo on으로 (심미성을 위하여 @echo on이라고 썼습니다.) echo 상태를 복원합니다. 여기서 :exit 라벨은 프로그램 내에서 탈출 조건을 만났을 때 편리하게 활용할 수 있도록 하기 위한 것입니다.

위의 예제를 활용하면 다음과 같이 응용할 수 있습니다.

@echo off
pushd "%~dp0"


if not exist %windir%\system32\runas.exe. (
    echo RUNAS.EXE 프로그램을 찾을 수 없습니다.
    pause
    goto exit
)

for /r "%~dp0" %%v in (test.cmd) do (
    if exist "%%v" (
        echo %%v 진행 중...
        call "%%v"
        rem 다른 배치 파일을 호출하고나면 echo on 상태가 되므로 다시 @echo off로 꺼줍니다.
        @echo off
    )
)

:exit
popd
@echo on


 

위와 같이 활용한다면 배치 파일을 어디서 실행하든 원하는 경로로 들어갔다가 다시 쉽게 원래 위치로 되돌아올 수 있으므로 일반 프로그램처럼 배치 파일을 작성하는 것이 좀 더 쉬워집니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2014. 6. 7. 09:29

Visual Studio에서 제공하는 테스트 도구에 NUNIT을 결합해서 사용할 수 있다면 정말 유용할 것입니다. 이번 웹 캐스트는 Visual Studio에서 제공하는 테스트 도구와 NUNIT 간의 연동을 도와주는 NUNIT Test Adapter의 사용 방법과 함께, Windows Forms 기반 응용프로그램에서 Visual Studio와 NUNIT Test Adapter를 결합하여 테스트를 진행할 수 있는 방법을 소개합니다.

(비디오 콘텐츠로 올렸던 게시물이었으나 아티클로 조만간 복원할 예정입니다.)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2013. 11. 16. 02:00

Visual Studio 2013에서는 One ASP.NET이라는 새로운 형태의 프로젝트 생성 방식을 제공하고 있습니다. 이전에는 ASP.NET MVC, Web Form, Web Page, Web API가 각기 다른 프로젝트로 분리되어있어서 구성하기에 불편한 점이 많았습니다만 2013부터는 한 위치에서 동시에 여러 ASP.NET 웹 스택을 선택하고 조합할 수 있게 되었으며, 인증 시나리오도 Windows Identity Foundation, 기본 인증, 소셜 네트워크 기반 인증 등을 지원할 수 있는 옵션이 추가되었습니다.

그런데 이러한 특성 때문에, 처음부터 NuGet 패키지 관리자에 대한 의존성이 필수가 되었습니다. 그래서 간혹 어떤 컴퓨터에서는 Visual Studio 2013으로 ASP.NET 프로젝트를 생성하려 할 때 다음과 같은 오류 메시지가 나타나기도 합니다.

지정된 파일을 찾을 수 없습니다. (예외가 발생한 HRESULT: 0x80070002) 

오류: 이 템플릿에서 구성 요소 어셈블리 'NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'을(를) 로드하려고 했습니다. 이 문제에 대한 자세한 정보 및 이 템플릿을 활성화하는 방법에 대한 정보는 "프로젝트 템플릿 사용자 지정"의 설명서를 참조하십시오. 

위와 같은 오류 메시지가 나타나는 것은 NuGet Package Manager 애드인이 설치되어있지 않기 때문이며, ASP.NET 프로젝트 생성과 동시에 인터넷 상에서 NuGet Package Manager를 이용하여 프로젝트 구성에 필요한 각종 라이브러리들 (jQuery, ANTLRv3 등)을 내려받으려고 시도하기 때문입니다.

문제를 진단하기 위하여, Visual Studio에 현재 설치된 확장 및 업데이트 내역을 확인합니다. 메뉴에서 아래와 같이 실행하면 해당 항목을 찾을 수 있습니다.

도구(T) - 확장 및 업데이트(U) 클릭 

온라인 - Visual Studio 갤러리 선택 - 검색어에 nuget 입력 후 Enter 키 누름 - "NuGet Package Manager for Visual Studio" 선택 - 다운로드 버튼 클릭 

다운로드 진행 - EULA 동의 - 설치 - 아래와 같이 화면이 나타나면 하단의 "지금 다시 시작(R)" 버튼 클릭

이제 ASP.NET 프로젝트를 다시 생성하면 정상적으로 생성이 완료될 것입니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 12. 24. 18:23

안녕하세요. Windows Azure MVP 남정현입니다.

IIS나 Apache 등의 웹 서버를 사용하여 웹 사이트를 구축하고 운영하다보면 사이트에 발생하는 문제를 진단해야 할 경우가 종종 생깁니다. 규모가 크지 않은 경우 사이트 하나에 한 서버, 한 IP만을 이용할 수도 있지만 편의에 따라 맵핑된 도메인 주소에 따라 다른 웹 사이트를 내보내도록 가상 호스트를 구성한 경우 테스트하기 불편한 점이 있습니다.

이러한 불편함을 쉽게 해소하고 완벽하게 테스트할 수 있는 방법이 있어 소개합니다. 바로 HOSTS 파일을 수정하는 방법인데, 이 파일을 수정하여 가상의 호스트를 정의하고 해당되는 호스트 앞으로 사이트를 연결시키는 방법입니다. 이번 글에서는 IIS를 사용하는 경우를 예로 들어서 설명을 드리겠습니다.

1. %windir%\system32\drivers\etc\hosts 파일 편집하기

Windows + R 키를 이용하여 실행 대화 상자를 띄우거나 기타 여러가지 방법을 이용하여 %windir%\system32\drivers\etc\hosts 파일을 텍스트 편집기로 엽니다.

그러면 아래와 같이 텍스트 편집기 창이 열리는데 그림에서 보는 것과 같이 IP 주소와 가상 호스트 이름을 한 줄씩 입력합니다. 주석으로 표시할 내용은 각 줄 제일 첫 글자를 #으로 시작하면 됩니다.

예를 들어 127.0.0.1 tiger 라고 입력하고 저장한 다음 서버 내의 브라우저나 기타 인터넷 응용프로그램에서 접속을 시도하면 localhost와 마찬가지로 접속이 잘 됩니다. 그러나 IIS나 가상 호스트 개념을 사용하는 네트워크 서비스에서는 다른 호스트로 분리하여 처리할 수 있는 근거가 이 지점부터 유효하게 됩니다.

2. IIS에서 가상 호스트 설정 업데이트하기

IIS 관리자를 실행한 다음 여러 개의 웹 사이트가 있는 것을 확인합니다. 

1단계에서 지정한 가상 호스트와 연결할 웹 사이트 항목을 오른쪽 버튼을 클릭하고, 바인딩 편집 메뉴를 클릭하여 세부 설정으로 이동합니다. 

바인딩 편집에서 호스트 이름에 1단계에서 추가한 가상 호스트 이름을, 포트나 IP 주소 설정은 필요에 따라 변경합니다. 포트 번호나 IP 주소를 따로 변경하지 않아도 호스트 이름으로 구분하기로 하였으므로 로컬에서도 사이트 별로 분리된 상태에서 쉽게 테스트가 가능하게 됩니다. 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 12. 9. 19:54

안녕하세요. Windows Azure MVP 남정현입니다.

오늘은 자세히 살펴보지 않으면 헛갈릴 수도 있는 세밀한 내용을 하나 다루어보려고 합니다. 이번에 Azure Camp @ 서울시립대 강의를 진행하면서 우연히 찾은 내용입니다.

Windows Azure Mobile Service는 Windows Live 이외에 Facebook, Twitter, Google이 제공하는 Client ID와 Client Secret을 내부적으로 보관할 수 있는 기능을 가지고 있고, 이들 아이디를 사용하여 Claim Authentication을 중간에서 릴레이해주는 유용한 기능을 가지고 있습니다. 나중에 App에서는 Windows Azure Mobile Service SDK를 개발하려는 플랫폼에 맞게 내려받아서 적용하기만 하면 손쉽게 소셜 네트워크 서비스들과 맥락을 같이할 수 있는 것이지요.

이전에도 종종 알려지곤 했었는데 dev.live.com이라는 별도의 관리 포털 사이트가 줄곧 있었습니다. 이 사이트에서도 사실 Application을 선언하고 만드는 것이 가능했었는데 최근에 여기에 Application을 등록할 수 있는 다른 대행 사이트가 하나 더 늘어났습니다. 바로 Windows 8 Developer Dashboard (dev.windows.com) 입니다. 여기서 앱의 이름을 예약하는 순간 자동으로 dev.live.com에서도 Application이 동시에 등록됩니다.

여기서 알아두시면 유용한 것이 두 가지가 있습니다.

첫 번째는 기존에 dev.live.com에서 같은 이름으로 선언한 Application 정의가 있다 하더라도 내부 클라이언트 ID와 시그니처값을 비교 대상으로 보는 관계로 Windows Store에서 앱 이름을 예약한 경우 또 다른 Application이 dev.live.com 상에서도 한 번 더 생성이 됩니다. 물론 둘 사이는 전혀 연관 관계가 없습니다.

두 번째는 dev.live.com에서 Application을 선언한 경우 Claim Authentication 목적으로 SDK에서 활용할 수는 있지만, Windows Store App 고유의 기능인 푸시 알림 서비스를 위한 Package SID가 dev.live.com에서 생성한 경우에는 지정되지 않고 수정이 되지 않기 때문에 사용할 수 없습니다. 당연한 이야기이지만 푸시 알림 서비스나 기타 Windows Store App 고유의 기능을 활용하려면 dev.windows.com을 통해서 앱 이름을 정확히 예약해야 합니다.

아래 이미지는 실제로 두 가지 다른 Application의 차이점을 설명하는 그림입니다. 왼쪽이 Store Dashboard에서 예약한 Application으로 Package SID 값이 할당되어있습니다. 반면 오른쪽은 dev.live.com에서 직접 예약한 이름으로 Package SID 표시도 없고 선택지도 없습니다.

이러한 특징이 있으므로 개발하려는 앱이나 웹 서비스가 향후 Windows 8 앱으로의 출시를 목표로 하시는 경우에는 앱의 이름을 사전에 미리 예약하는 작업이 필요합니다. 그리고 달리 말하면, dev.live.com에서 등록한 Application이 Windows Store App의 이름으로 쓰이지는 못한다는 것을 정확히 숙지하시는 것이 필요합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 10. 26. 00:42

안녕하세요. Windows Azure MVP 남정현입니다.

오늘 소개해드리려고 하는 내용은 ClickOnce용 패키지를 만들었을 때 유용하게 활용하실 수 있는 팁입니다. 보통은 같이 만들어지는 setup.exe 프로그램을 통해서 ClickOnce 패키지가 시작되도록 배포하는 것이 일반적이겠지만, 이 setup.exe를 대신하여 여러분만의 고유한 Bootstrapper를 제작할 수 있는 방법이 있습니다. 바로 ClickOnce의 주요 핵심 DLL인 DFSHIM.DLL 파일의 API 2개를 활용하는 것인데요, 지금 소개하려는 API를 보통은 rundll32.exe 프로그램을 이용해서 호출하는 것으로만 구글의 검색 결과에 보통 열거됩니다. 그러나 이 기능을 rundll32.exe 프로그램에 의존하지 않고 직접 프로그래밍 코드에서 호출할 수 있는 방법은 없을까요?

rundll32.exe로 호출하는 API에 대한 특성 이해하기

rundll32.exe 프로그램은 약간의 트릭과 암묵적인 규칙을 기반으로 동작하는 시스템 유틸리티로 다소 게으른(?) 면이 있습니다. 특수한 경우를 제외하고 일반적으로 DLL 파일은 직접 실행할 수 없고 반드시 다른 EXE 파일에 동적이든 정적이든 링크되어 사용되야만 합니다. 프로그램 개발 공수 관점에서 보면 DLL에 중요 컨텐츠를 포함시켜놓았을 경우 번번히 이런 컨텐츠를 위해서 별 의미없는 EXE 파일을 빌드해야 하는 셈인데, 이러한 낭비적 요소를 제거하기 위해서 일반화된 DLL 호스트 및 실행 프로그램을 넣게 됩니다. 그러나 잘 아시겠지만, 사실 이는 잠재적으로 보안 위협이 되는 부분도 있습니다.

다행히도 rundll32.exe는 무분별, 무절제하게 아무렇게나 들어오는 입력을 모두 받아들이는 것이 아닙니다. 이에 대한 상세한 규칙은 Microsoft KB164787 문서 (http://support.microsoft.com/kb/164787) 에 상세하게 기록되어있으며 내용을 요약하면, RUNDLL32.EXE로 호출할 수 있는 함수 시그니처는 대강 아래와 같은 형태로 제약됩니다.

  • void __stdcall <Function>W(HWND hwnd, HINSTANCE hinst, LPCWSTR lpszCmdLine, int nCmdShow);
  • void __stdcall <Function>(HWND hwnd, HINSTANCE hinst, LPCSTR lpszCmdLine, int nCmdShow);
  • void __stdcall <Function>(void);

이 글을 작성하는 현 시점에서 16비트 운영 체제는 일상적으로 사용되지 않고, 32비트 및 호환 운영 체제 가운데에서도 NT 커널을 계승하는 운영 체제가 주로 사용됨을 감안하였을 때, 보통 위와 같이 시그니처들이 있다고 볼 수 있습니다. W라는 접미사가 붙는 것은 세 번째 매개 변수가 문자열 버퍼를 포함하고 있기 때문에 적용되는 Windows 프로그래밍 환경에서의 Convention입니다. 이와 같이 Wide String을 지원하는 함수가 있다면 가장 적극적으로 먼저 쓰이게 됩니다. 그리고 해당되는 함수가 없다면 Ansi String을 지원하는 두 번째 후보가 차선책으로 쓰이게 됩니다. 만약 별도의 파라미터가 없이 불린다면 세 번째 시그니처에 해당되는 함수가 채택됩니다.

DFSHIM.DLL의 문서화되지 않은 API 두 가지

DFSHIM.DLL은 .NET Framework 2.0과 함께 배포되는 ClickOnce의 핵심 기능을 포함하는데, 확장자가 .application인 파일을 실행해주거나 ClickOnce와 직접 확장자를 연결시킬 경우 연결 프로그램으로서 실행해주는 등의 기능, 그리고 ClickOnce 캐시 저장소 초기화 등의 기능을 담당합니다. 인터넷 자료를 검색해보면 대개는 COM 기반의 API나 제한된 몇 종류의 API만을 이야기하는 것으로 이야기가 잘 보입니다.

그러나 공식적으로 사용되면서도 정확하게 문서화되어있지 않은 API가 두 종류가 있으며 사실은 더 사용하기 쉬운 API가 두 종류가 있습니다. 바로 ShOpenVerbApplication(W), CleanOnlineAppCache에 관한 것인데, 양쪽 모두 rundll32.exe로 실행하는 방법은 아래와 같다고 나오지만 실제 프로그래밍 언어에서 다루는 방법에 대한 문서가 거의 없습니다.

  • %windir%\system32\rundll32.exe dfshim.dll,ShOpenVerbApplication <.application 파일의 경로나 URL>
  • %windir%\system32\rundll32.exe dfshim.dll,CleanOnlineAppCache

위와 같이 실행하는 방법 말고 더 간단한 방법은 없을까요? 앞에서 소개한 내용을 바탕으로 시그니처를 대입하면서 맞추어보니 아래와 같이 정의할 수 있었습니다.

  • typedef void (WINAPI *ShOpenVerbApplicationWProc)(IN HWND, IN HINSTANCE, IN LPCWSTR, IN int);
  • typedef void (WINAPI *ShOpenVerbApplicationAProc)(IN HWND, IN HINSTANCE, IN LPCSTR, IN int);
  • typedef void (WINAPI *CleanOnlineAppCacheProc)(VOID);

위의 함수 포인터에 대한 선언을 활용하여 _UNICODE 매크로 선언 여부에 따라 동적으로, 그리고 선택적으로 호출할 수 있도록 만들 수 있었습니다. (Visual C++ 컴파일러 기준)

// 함수 포인터 선언
typedef void (WINAPI *ShOpenVerbApplicationWProc)(IN HWND, IN HINSTANCE, IN LPCWSTR, IN int);
typedef void (WINAPI *ShOpenVerbApplicationAProc)(IN HWND, IN HINSTANCE, IN LPCSTR, IN int);
typedef void (WINAPI *CleanOnlineAppCacheProc)(VOID);
// 조건부 매크로 선언
#ifdef _UNICODE
 #define ShOpenVerbApplicationProc ShOpenVerbApplicationWProc
 #define ShOpenVerbApplicationName "ShOpenVerbApplicationW"
#else // _UNICODE
 #define ShOpenVerbApplicationProc ShOpenVerbApplicationAProc
 #define ShOpenVerbApplicationName "ShOpenVerbApplication"
#endif // _UNICODE
// 변수 선언
 HINSTANCE hLibrary;
 ShOpenVerbApplicationProc pProc;
 CleanOnlineAppCacheProc pClearProc;
 // DLL 로드 시도 및 함수 검색 (DLL 로드에 실패한 경우 .NET Framework 설치를 유도할 수 이
 BOOL LoadDFSHIM(void) {
  hLibrary = LoadLibrary(_T("DFSHIM.DLL"));

  if (hLibrary == NULL)
   return FALSE;

  pProc = (ShOpenVerbApplicationWProc)GetProcAddress(
   hLibrary,
   ShOpenVerbApplicationName);

  pClearProc = (CleanOnlineAppCacheProc)GetProcAddress(
   hLibrary,
   "CleanOnlineAppCache");

  if (pProc == NULL || pClearProc == NULL) {
   pProc = NULL;
   pClearProc = NULL;
   FreeLibrary(hLibrary);
   return FALSE;
  }

  return TRUE;
 }
 // 프로그램 종료 시 호출하여 자원 할당을 해제
 VOID UnloadDFSHIM(void) {
  if (pProc)
   pProc = NULL;

  if (pClearProc)
   pClearProc = NULL;

  if (hLibrary)
  {
   FreeLibrary(hLibrary);
   hLibrary = NULL;
  }
 }
// ClickOnce application 시작 시 호출
if (this->hLibrary != NULL && this->pProc != NULL)
{
  this->pProc(NULL, NULL, _T("ClickOnce .application 파일 경로 또는 URL"), SW_SHOW);
}
// 기존 Online 전용 App의 Cache를 삭제할 때 호출 (설치 시 문제가 있을 경우 활용 가능)
if (this->hLibrary != NULL && this->pClearProc != NULL)
{
  this->pClearProc();
}

위와 같이 C/C++ Application에서 간단하게 ClickOnce Online App 및 Offline App 설치를 호출할 수 있고, Online App Cache를 초기화할 수 있습니다.

결론

Windows Desktop App 가운데에서도 .NET으로 배포하는 App의 경우 설치 도입부부터 특별한 사용자 경험을 제공하기 위한 목적으로 위의 기능을 활용하면, setup.exe 파일 대신 여러분이 직접 디자인한 Setup Bootstrapper를 만들어 배포할 수 있고, 혹은 rundll32.exe 프로그램을 그대로 이용하여 바로가기 아이콘을 만드는데 활용할 수도 있습니다.

이 글에 대한 프리뷰 이미지 출처: http://hummingbird.tistory.com/3614

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 10. 8. 21:36

안녕하세요. Windows Azure MVP 남정현입니다.

오늘 소개하려는 내용은 개발자분들께 매우 유용한 팁이 될 것 같습니다. 요즈음에도 디자이너와 개발자 사이에는 협업을 하기 쉽지 않은 점들이 매우 많습니다. 특히 디자이너가 공들여 작업한 PSD 파일은 막상 개발자의 손에 떨어지면 아무 의미 없는 바이너리 파일이 되기 쉽습니다. 종국에는 개발자가 디자이너의 따가운 눈초리를 애써 무시하면서 레이어 파일들을 일일이 잘라달라고 부탁하지 않으면 안되는 상황이 되곤 하지요. :-)

그러나 이러한 수고스러운 작업을 디자이너에게 요구하지 않고 개발자 스스로 PSD 파일을 레이어 별로 낱개의 투명 PNG 파일로 만들 수 있는 일련의 방법을 찾았습니다. 이를 위하여 Photoshop을 설치하거나 별도의 상용 유틸리티를 써야 하는 것은 더더욱 아니며 온전히 인터넷 상에서 구할 수 있는 도구와 플러그인, 그리고 Paint.net의 힘으로 도달할 수 있는 방법이므로 나름 추천해드릴만 하다고 생각합니다.

1단계: Paint.net 설치하기

Paint.net은 Rick Brewster가 개발한 프리웨어 기반의 Raster Graphic Editor 소프트웨어로 초창기에는 오픈 소스였지만 현재는 프리웨어로 전환한, C#으로 만든 멋진 그래픽 도구입니다. GIMP나 Photoshop을 대체하면서 Windows 환경에서 빠르고 가볍게 사용할 수 있는 그래픽 도구로 널리 알려져 있고 국내에서도 인지도가 제법 높은 편입니다.

Paint.NET은 http://www.getpaint.net/ 에서 최신 버전을 설치할 수 있습니다.

2단계: Paint.net PSD 플러그인 설치하기

Paint.net은 훌륭한 그래픽 편집 도구이지만 PSD를 직접 지원하지는 못합니다. 대신 PDN이라는 자체 파일 형식을 사용하기 때문에 Paint.net만 설치해서는 PSD 파일을 다룰 수 없습니다. 이를 극복하기 위하여 Paint.net PSD 플러그인을 http://psdplugin.codeplex.com/ 에서 최신 버전을 다운로드하고 설치해야합니다. 플러그인 ZIP 파일을 다운로드하면 PhotoShop.dll 파일을 확인할 수 있으며 이 파일을 아래와 같이 설치합니다.

  • 실행 중인 Paint.net 프로그램을 모두 종료합니다.
  • PhotoShop.dll 파일을 %PROGRAMFILES%\Paint.NET\FileTypes 폴더 아래에 복사합니다.
  • 다시 Paint.net을 실행하고 파일 열기 대화 상자에서 파일 유형을 선택할 때 아래와 같이 PSD 파일에 대한 필터가 등록되어있으면 정상적으로 설치된 것입니다.

3단계: PSD 파일을 PDN 파일로 저장하기

변환하려고 하는 PSD 파일을 PDN 파일로 저장해야 합니다. 일단 PSD 파일을 Paint.net에서 열었을 때 원본 PSD 파일과 차이점이 없는지 한 번 확인은 해야 합니다. 디자이너나 아트워크에 관여하는 다른 사람과 내용을 검토해본 다음 내용에 이상이 없으면 PDN 파일로 저장하여 4단계로 진행합니다.

4단계: PDN2PNG 명령줄 유틸리티로 레이어 별로 투명 PNG로 저장하기

PSD 파일을 PDN 파일로 변환한 다음 실제로 하려는 일은 각각의 레이어를 투명 PNG로 나누어 저장하는 일이 되겠지요. 이 작업 역시 Paint.net에서 직접 수행하는 것은 현재 매우 손이 많이 가고 번거로운 작업이기 때문에 자동화를 위하여 반드시 도구가 필요한데 Paint.net 없이 이를 처리해주는 도구가 PDN2PNG 입니다. http://forums.comsquare.ch/viewforum.php?title=pdn2png 에서 다운로드할 수 있으며, 별도로 제품화된 소프트웨어가 아닌 관계로 사이트에 접속되지 않을 가능성을 염두에 두어 제 SkyDrive에 파일 사본을 올려두었습니다. (문제가 될 경우 삭제하겠습니다.)

PDN2PNG 및 PSD Load Plugin 다운로드: http://sdrv.ms/VQfZyE

이 프로그램을 명령줄 도구로 찾기 쉬운 위치에 파일을 압축 해제하여 복사하거나 PATH 환경 변수 등으로 검색할 수 있도록 설치합니다.

PDN 파일이 정상적으로 렌더링되었을 때의 전체 모습을 PNG 파일로 바꾸려면 다른 스위치 없이 아래와 같이 명령어를 지정하면 됩니다.

pdn2png "PDN 파일 경로"

PDN 파일 안에 들어있는 각각의 레이어들을 모두 낱개의 PNG 파일로 바꾸려면 아래와 같이 /split 스위치를 사용하여 명령어를 지정하면 현재 작업 중인 디렉터리 앞으로 낱개의 PNG 파일들이 레이어의 이름을 사용하여 만들어집니다.

pdn2png /split "PDN 파일 경로"

전체 레이어 대신 특정 레이어 인덱스를 PNG 파일로 바꾸려면 아래와 같이 스위치를 지정합니다.

pdn2png /index="인덱스 번호" "PDN 파일 경로"

5단계: 그림 자르기

pdn2png 명령의 /split 스위치를 사용하여 모든 PNG 파일들을 만들고 난 다음에 각 PNG 파일들을 살펴보면 분할은 되어있지만 여전히 프로그램에서 원하는 조각 그림의 형태에는 조금 거리가 있습니다. 디자인 아트워크 기준으로 정확히 제 자리에 아트워크가 변환되어있긴 하지만 불필요하게 여백이 많이 남는 것을 볼 수 있습니다. 이를 깔끔하게 제거할 수 있는 방법은 약간의 노동(?)을 요구합니다. 5단계의 작업을 위해서는 Paint.net 또는 다른 적절한 도구를 사용하면 되지만 여기서는 Paint.net으로 작업하는 요령을 소개하고자 합니다.

  • Paint.net으로 나누어진 PNG 파일을 엽니다.
  • Magic Wand 툴을 도구 모음에서 왼쪽 그림과 같이 선택합니다.
  • Magic Wand 툴의 경계선 감지 유연성을 아래 그림과 같이 0%로 설정합니다. 어차피 투명한 배경과 투명하지 않은 Object로 경계가 극명하게 구분된 상태의 이미지이기 때문에 정확히 이미지를 자를 것에만 신경쓰면 됩니다.
  • 이제 아래 그림과 같이 투명 배경을 Magic Wand로 선택합니다. 이렇게 선택하여 투명한 영역과 투명하지 않은 영역을 집합 관계로 봤을 때 차집합 관계로 설정할 수 있습니다.


  • 키보드 단축키 Ctrl+I 키를 눌러 영역을 반전시킵니다. 투명한 영역 선택에 대한 나머지 반전이므로 투명하지 않은 영역 모두를 선택하는 셈이 됩니다.


  • 이제 여기서 키보드 단축키 Ctrl+Shift+X키를 눌러 선택된 영역에 맞추어 캔버스의 크기를 아래 그림과 같이 줄입니다. 크기는 자동으로 산출되므로 이미지가 잘릴 걱정은 하지 않아도 됩니다.

    주의 사항: SnagIt의 경우 단축키로 Ctrl+Shift+X를 이미 전역적으로 바인딩하고 있기 때문에 이 동작이 Paint.net으로 전달되지 않고 무시될 수 있습니다. SnagIt 혹은 이 단축 키 조합에 의존하는 다른 프로그램이 있을 경우 작업하는 동안 잠시 프로그램을 종료해야 합니다.


  • 키보드의 Esc 키를 눌러 선택 영역을 해제하고 단축키 Ctrl+S 키를 눌러 아래 그림과 같이 최적의 이미지 옵션을 선택하여 저장합니다. 나머지 파일들도 같은 방법으로 계속 작업하면 됩니다.


이렇게 해서 디자이너가 개발자에게 가져다준 PSD 파일을 개발자가 원하는 PNG 파일로 성공적으로 변환할 수 있습니다. 디자이너와 개발자 모두 서로에게 도움이 될 수 있을 것입니다. 오늘 한 번 시험삼아 활용해보시는것은 어떨까요? :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 10. 5. 14:57

안녕하세요. Windows Azure MVP 남정현입니다.

 

오늘은 사소하지만 잘 모르고 접근하면 크게 시간을 낭비하게 만들 수 있는 사소한 트릭에 대해서 이야기를 하려고 합니다. 바로 시스템 디렉터리 접근에 관한 규칙인데요, 32비트 플랫폼을 사용하는 컴퓨터에서는 벌어지지 않기 때문에 흔히 간과하고 지나가기 쉬운 부분이라 블로그 글로 올립니다. 지금 올리는 글은 Windows Vista 이후로 계속 적용되는 내용이며, 서버 플랫폼에 대해서도 해당됩니다.

일반적으로 32비트 플랫폼을 타겟으로 작성된 응용프로그램들은 파일 경로 관련 해석 로직을 호출할 때 들어오는 그대로 (as-is) 해석을 하고 적절한 파일을 찾아 핸들을 열어주거나 정보를 조사해줍니다. 그러나 64비트 플랫폼의 경우, 흔히 잘 알려져있는 호환성의 족쇄라는 것에 의해 과거 32비트 시스템이 16비트 시스템에 대해서 지원하던것과 같이 64비트 시스템에서 32비트 시스템에 대한 지원을 Windows on Windows라는 호환 계층을 통하여 지원하고 있습니다. 32비트 플랫폼을 대상으로 만들어진 프로그램이 별 다른 노력 없이 그대로 실행될 수 있는 가장 중요한 원천이라고 할 수 있을 것입니다.

그러나 단순히 바이너리 코드에 대한 호환성 계층 제공을 하는 것을 넘어서서 시스템 파일에 대해서도 트릭이 하나 들어있는데, 특별한 예약명을 사용하지 않는 한, 32비트 프로그램이 x64 환경에서 실행될 때 %WINDIR% 디렉터리 아래의 System32 디렉터리는 절대 System32 디렉터리가 아니라 SysWOW64 디렉터리를 가리키도록 자동으로 의미가 수정됩니다.

가끔 필요에 의하여 32비트 프로그램이 64비트 시스템 구성 요소의 존재 여부를 확인하고 대리로 프로그램을 실행해야 할 필요가 있습니다. 대개의 경우, 중요한 시스템 파일들은 System32와 SYSWOW64 사이에 차이가 없도록 사전에 조율이 되어있으므로 큰 문제는 없습니다. 하지만 시스템이 설치된 이래로 새로 추가되는 새로운 시스템 파일의 경우, 32비트로 컴파일된 프로그램은 이 사실을 파악할 방법이 없습니다.

이를 해결하기 위하여 사용할 수 있는 기술적인 방법으로 API를 이용하여 리디렉션을 켜거나 끌 수 있는 API가 있습니다. 그러나 이 방법보다 더 쉽고 안전하게 갈 수 있는 방법이 있어 소개를 해드리려고 합니다.

바로 %WINDIR%\SysNative라는 디렉터리에 관한 내용입니다. 사실 SysNative 디렉터리는 실존하는 디렉터리가 아닙니다. 그러나 32비트 프로그램에서 이 디렉터리에 대한 파일 시스템 동작이 일어날 경우, 32비트 프로그램이 64비트 시스템 구성 요소에 대해 접근할 수 있는 경로로 활용할 수 있습니다. 즉, 실제 시스템 디렉터리로 제대로 리디렉션이 되는 것을 확인할 수 있습니다. 그리고 64비트 프로그램에서는 이 디렉터리에 대한 별칭이 작동하지 않으므로 아래와 같이 쉽게 구분이 가능합니다.

string targetPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), @"System32\mrt.exe");

if (!Directory.Exists(targetPath)) {
    targetPath = Path.Combine(Environment.GetEnvironmentVariable("WINDIR"), @"SysNative\mrt.exe");
}

if (!Directory.Exists(targetPath)) {
    // 정말 해당 파일이 시스템 디렉터리에 없는 상황인 경우 여기로 오게 됩니다.
    return;
}
// 파일을 정확하게 찾은 경우 여기로 오게 됩니다.

위와 같이 코드를 작성하면 특수한 스위치나 설정을 건드리지 않고 안전하게 32비트 프로그램에서 64비트 시스템 구성 요소를 검색할 수 있습니다.

감사합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2012. 8. 8. 20:26

안녕하세요. Windows Azure MVP 남정현입니다.

오늘 소개해드리려고 하는 것은 Microsoft Press에서 그동안 출간된 eBook, 백서, 가이드 문서 등을 eBook 형태로 집대성해서 다운로드할 수 있도록 공개한 내용인데요, 상당히 많은 자료들이 있지만 그 중에서도 개발자나 IT 엔지니어에게 도움이 될 만한 부분들만 따로 간추려서 블로그 포스팅을 해 봅니다. 제공되는 모든 eBook은 영어로 작성되어있습니다.

여기서 소개하지 않은 백서나 가이드 문서, 트레이닝 킷 혹은 PDF 이외의 다른 포맷의 다운로드 컨텐츠를 찾으시려면 아래 웹 사이트에 방문하셔서 더 찾아보실 수 있습니다. :-)

제품 별로 자료들을 분류한 것으로 적절한 카테고리의 항목을 찾아 검색하시면 쉽게 다운로드하실 수 있습니다.

클라우드 기술 관련

프로그래밍 관련

Office 365 및 Office 2010 관련

Windows Server 관련

일반 사용자

출처: http://blogs.msdn.com/b/jspark/archive/2012/08/06/ebook-windows-azure-windows-8-windows-phone-7.aspx

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 유용한데요? ^^

    2012.08.09 10:47 신고 [ ADDR : EDIT/ DEL : REPLY ]

Useful Solutions2012. 5. 15. 00:56

최근에 Hyper-V 네트워크 구축과 관련하여 라우팅 및 원격 액세스 서비스를 설치하고 난 다음에 전혀 예상하지 못했던 MMC 스냅인 관련 오류가 나타나서 문제를 해결하기 위하여 방법을 찾던 중에 적절한 해결 방안을 찾아 블로그 글로 정리해서 올립니다.

MMC 스냅인 제한 내역에서 삭제하기

MMC 스냅인으로 불러올 수 있는 항목에 대해 제한이 추가되어있을 수 있습니다. 정책으로 인하여 로드할 수 없다는 메시지를 나타내는 스냅인은 이 방법을 통하여 문제를 해결할 수 있습니다. 이 기능을 사용하려면 시스템 관리자 권한이 필요합니다.

  1. 오류 메시지에서 나타나는 GUID 값을 확인합니다.
  2. 레지스트리 편집기를 시작합니다. (regedit.exe)
  3. HKEY_CURRENT_USER\Software\Policies\Microsoft\MMC 순으로 탐색합니다.
  4. 불러오지 못한다고 되어있던 스냅인의 GUID 값을 찾아 해당 Key 값 자체를 삭제합니다.
  5. 열려있던 모든 MMC 스냅인을 닫고 다시 MMC 콘솔을 엽니다.

Users 그룹에 거부 권한이 지정된 경우

특정 MMC 스냅인의 설치가 정상적인 상태가 아니라고 메시지가 나타나는 경우에는 해당 MMC 스냅인 COM 컴포넌트를 포함하는 Inprocess Server DLL 파일을 찾아 권한 상태를 확인하고 다시 레지스트리에 정보를 업데이트해야 합니다. 정확한 DLL을 찾기 위하여 다음의 순서를 따릅니다.

  1. 오류 메시지에서 나타나는 GUID 값을 확인합니다.
  2. 레지스트리 편집기를 시작합니다. (regedit.exe)
  3. 제일 상위 루트 항목을 선택하고, 레지스트리 항목 검색 창을 열어 (Ctrl+F) 1단계에서 확인한 GUID 값의 처음 몇 자리 - 또는 - 전체 자릿수를 검색어로 넣고 검색을 시작합니다.
  4. HKEY_CLASSES_ROOT 키 아래에서 키 값을 찾으면, InprocServer32 키 아래에 들어있는 파일 경로를 확인합니다.
  5. 4단계에서 확인한 파일 경로가 있는 곳으로 이동하여 파일 보안 속성을 확인한 다음 필요한 모든 설정을 다시 설정하는데, 이 때 Users 그룹이나 다른 그룹에 거부 설정이 지정되어있는 경우 이를 모두 해제하고, 최소한의 권한인 읽기 및 실행 권한만 허용하도록 변경합니다. 소유권 변경은 필요하지 않습니다.
  6. 명령 프롬프트 창을 열고, 해당 DLL 파일에 대해 다시 regsvr32.exe 명령을 사용하여 재 등록합니다.
  7. 열려있던 모든 MMC 스냅인을 닫고 다시 MMC 콘솔을 엽니다.

라우팅 및 원격 액세스 제어 스냅인에 대한 문제 해결

라우팅 및 원격 액세스 역할 제어를 위한 스냅인의 경우, HKEY_CLASSES_ROOT\CLSID\{01A3BF5C-CC93-4C12-A4C3-09B0BBE7F63F} 에서 DLL 파일의 경로를 확인할 수 있고, 보통 %windir%\system32\iasnap.dll을 가리킵니다. 이 파일에 대한 권한 설정을 확인/수정하고 COM 서버로 재등록하면 문제가 해결됩니다. 정상적으로 등록이 완료되면 InprocServer32 키 외에 ProgId, VersionIndependentProgId 키가 추가로 등록되어있어야 합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2010. 10. 13. 22:20

커뮤니티 뉴스 레터를 구독하다가 우연히 발견한 좋은 리소스 소개 페이지가 있어서 한글로 간단히 번역하여 블로그 아티클로 올려봅니다. Client App Dev MVP이신 Anoop Madhusudana님의 블로그로부터 발췌하여 인용한 것임을 밝혀둡니다. (http://amazedsaint.blogspot.com/2010/09/7-freely-available-e-booksguides-i.html)

Foundations Of Programming
다운로드 링크: http://codebetter.com/media/p/179694.aspx

이 e-Book은 단순 명료하면서도 이해하기 쉽게 구성되어있습니다. 특히, 프로그래밍에 첫발을 막 내딛은 - 혹은 - 아직 숙련되지 않은 개발자들에게 더 좋은 코드와 설계력을 부여할 수 있도록 도움을 줄 것입니다. 이 블로그를 운영하시는 MVP 분의 마음에 아주 쏙 드는 책이라는 인상깊은 설명도 덧붙여져있습니다. :-)

Microsoft Application Architecture Guide, 2nd Edition
다운로드 링크: http://www.microsoft.com/downloads/en/details.aspx?FamilyID=ce40e4e1-9838-4c89-a197-a373b2a60df2&displaylang=en

Microsoft에 의하여 작성된 e-Book이며, .NET Framework를 사용하는 개발자 - 또는 - 설계자들이 반드시 읽어보아야할 내용들로 구성되어있습니다. 이 도서를 통하여, Microsoft .NET 기반 소프트웨어 개발 환경에서, 디자인 기본 원칙이나 패턴을 성공적으로 개발하고 적용할 수 있도록 할 수 있습니다. 또한, .NET 기반에서 개발하는 동안 흔히 부딪힐 수 있는 문제점들에 대해 최적의 해결 방안을 언급하고 있으므로 엔터프라이즈 기반의 .NET 개발 환경에서 특히 유용합니다.

Rob Miles C# Yellow Book 2010
http://www.csharpcourse.com/

C#과 .NET의 컨셉을 쉽고 빠르게 이해할 수 있도록 도와줍니다. 이 e-Book을 통하여 최상의 구현 방법을 학습하고 패턴과 컨셉을 빠르게 습득하실 수 있습니다.

Threading in C#
http://www.albahari.com/threading/

제 블로그에서, 그리고 SQL Azure와 LINQ 세미나를 진행하는 동안에 자주 언급했던 무료 개발 도구인 LINQpad의 제작자이자 Microsoft MVP인 Joe Albahari님의 리소스입니다. 복잡하고 까다로울 수 있는 주제인 멀티 스레딩에 대해 알기 쉽게 쓴 책으로, 스레드에 대한 다양한 컨셉, 예를 들어 스레드 풀링이나 동기화, Non-blocking 동기화 등 다양한 주제들을 다룹니다. 그리고 특별히 요즈음 .NET Framework 4.0에서 강조되는 병렬 프로그래밍에 대한 이야기도 같이 소개하고 있습니다. e-Book으로도 다운로드 가능합니다.

Improving .NET Application Performance and Scalability
http://www.microsoft.com/downloads/en/details.aspx?FamilyID=8A2E454D-F30E-4E72-B531-75384A0F1C47

이번에도 역시 Microsoft의 e-Book입니다. 여러분의 응용프로그램에서 발생할 수 있는 다양한 성능 상의 문제를 점검하고 해결할 수 있도록 도움을 주는 최상의 리소스로, 설계자, 개발자, 테스터, 관리자에 이르는 다양한 범위를 포괄합니다. e-Book의 후반에 수록된 부록에는 체크리스트가 있으므로, 체크리스트만을 따로 인쇄하고 책상 옆에 놓아두면 여러분의 응용프로그램을 스스로 점검해볼 때 매우 유용할 것입니다.

Applying Design Patterns
http://amazedsaint.blogspot.com/2009/06/software-design-patterns-for-everyone.html

디자인 패턴을 활용해보고 싶지만 어렵게 느껴지시나요? 그렇다면 이 리소스를 활용해보시면 좋을것 같습니다. 이 리소스에서는 디자인 패턴을 닷넷 개발 환경에서 어떻게하면 좀 더 쉽게 적용할 수 있을지 자세한 내용을 단계별로 소개하고 있습니다. 역시 e-Book으로도 다운로드 가능합니다.

RefCardz from DZone: Getting started with WCF 4.0
http://refcardz.dzone.com/refcardz/getting-started-windows-0

RefCardz from DZone: Getting started with Silverlight + Expression Blend
http://refcardz.dzone.com/refcardz/getting-started-silverlight

RefCardz from DZone: Essential F#
http://refcardz.dzone.com/refcardz/essential-f

위의 세 리소스는 e-Book은 아니지만 책상 옆에 놓고 쓸 수 있는 단어장 카드의 형태로 구성된 리소스입니다. 위 사이트에서 회원 가입을 하고 파일을 다운로드받아 카드로 오려서 바인더 링 등으로 매달아두면 생각날 때 마다 찾아볼 수 있는 여러분만의 리소스가 될 것입니다. 위에서 소개한 세 가지 카드 말고도 다른 카드들이 더 있으니 사이트 이곳저곳을 둘러 보시길 권합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2010. 8. 14. 00:38

2010.09.07 Update: 아크몬드님의 오픈 캐스트 목록에 이 글이 올라왔습니다. 많은 홍보 부탁드립니다. :-)

한동안 잊고 있다가 뒤늦게 창고 한구석에서 꺼내는 포스트입니다. (입이 열개라도 할 말이 없군요. ㅋㅋㅋ)

지난번 구관이 명관! ([Software Development/Windows NT Command Interpreter] - 구관이 명관! Batch File 활용 - 배치 파일로 프로그램을 작성하는데에 필요한 기본 사항 살펴보기)시리즈를 마무리하기 위해서 글을 좀 더 써봅니다.

반복문을 사용할 수 있다는 점은 상당히 중요한 부분입니다. 배치 파일의 경우도, 열거할 수 있는 대상이 있고, 이를 정확하게 열거하고 제어할 수 있으려면 반복문이 당연히 필요합니다. 이를 돕는 명령어가 바로 for 문인데 간단히 다음의 예시를 살펴보기로 하겠습니다. 아래는 한데 묶여있지 않고 각각 분리된 build.xml 파일을 한꺼번에 컴파일하기 위한 목적으로 작성된 배치 파일의 예시입니다. W 은행의 전산 시스템을 자동화하기 위하여 1년전 처음 작성하였으며, 최근 C 은행의 닷넷 프레임워크 기반 프로젝트 (이 때는 msbuild를 호출하기 위함이었습니다.) 에서도 비슷한 이유로 재사용한 적이 있는 저만의 snippet입니다. :-)

@rem Java Source 컴파일 도구
@rem 작성일 - 2010년 8월 14일
@rem 작성자 - 남정현

@rem 명령줄 입력을 숨깁니다.
@echo off

@rem 화면을 초기화합니다.
@cls

@echo Java Source 컴파일 작업 시작
@echo.

@rem /d 스위치는 디렉터리 반복 시 사용합니다.
@rem 배치 파일 내에서 변수 선언을 전달하려면 이스케이프 처리를 해야 합니다.
@rem if 문은 아래 명령과 같이 여러 줄 입력이 가능합니다.
@rem ant 명령이 실패하는 경우 Jakarta Ant Build System이 PATH에 등록되어
@rem 있는 상태인지 확인해야 합니다.

@for /d %%i in (*.*) do @if exist "%%i\build.xml". (
  @echo 처리 중: "%%i"
  @ant -buildfile "%%i\build.xml"
  @echo.
)

@echo on

위의 부분에서 굵게 표시한 부분이 배치 파일 상에서의 for 문의 사용 예시입니다. 배치 파일 안에서 for 문을 사용하기 때문에 조금 변수명에 이스케이프 처리를 위해서 % 지시자를 한번 더 사용한다는 특이 사항만 제외하면 무난한 문법구조를 나타내고 있습니다.

for 문 바로 뒤에 오는 /d 스위치는 열거할 파일 시스템 대상 객체를 디렉터리만으로 한정하는 것으로 이 스위치를 생략할 경우 파일명이 해당 경로상에 존재할 때 같이 열거됩니다. 그 다음, 변수명, 검색할 객체 이름의 패턴 (DOS 방식이므로 전형적인 와일드 카드 패턴을 따릅니다)과 수행할 명령을 do 지시자 다음에 지정합니다. 배치 파일 안이므로 당연히 여러줄의 명령을 한번에 그룹으로 묶을 수 있습니다. 만약 /d 스위치 대신 /f 스위치를 사용할 경우 파일만이 열거될 수 있습니다. 그 외에 /r 스위치를 사용하여 재귀 탐색을 할 수 있고, /l 스위치를 사용하면 우리가 일반적인 프로그래밍 언어에서 사용하는 인덱스 기반 탐색을 위한 카운트 증감 (증가 및 감소 모두 포함됩니다.)을 수행할 수도 있습니다.

@rem 아래 명령은 시작값 1 부터 종료값 5까지 1씩 더하며 반복됩니다.
@rem C 언어로 번역한다면 for (int i = 1; i <= 5; i += 1) 과 같은 의미입니다.
@for /l %%i in (1,1,5) do @echo %%i

@rem 아래 명령은 시작값 5 부터 종료값 1까지 1씩 빼면서 반복됩니다.
@rem C 언어로 번역한다면 for (int i = 5; i >= 1; i -= 1) 과 같은 의미입니다.
@for /l %%i in (5,-1,1) do @echo %%i

보너스: Unix 및 Linux Build Script에서 흔히 사용하는 Stack 기반 Directory 탐색 구현하기

일반적으로 cd 명령 - 혹은 - chdir 명령은 forward only 탐색으로 드라이브를 바꾸거나, 전혀 다른 위치로 갑자기 이동하게 되는 경우 과거로 되돌아갈 근거가 없습니다. 그리고 DOS 기반의 명령이므로 UNIX와 같은 기능은 제공하지 않을 것이라는 일반적인 선입견까지 더해지면서 이런 기능이 "없는 것"으로 분류되기도 합니다만 실제로는 이런 기능이 NT 인터프리터에 존재합니다.

다음의 명령어를 한 번씩 실행해보면 Stack 기반의 탐색이 어떤 의미를 지니는지 아실 수 있습니다.

@rem 참고로 아래에 \ 기호가 더 붙은 이유는 %systemdrive%가 C: 까지이므로 경로임을 표시하기 위해 \를 붙여 C:\로 인지시키기 위함이었습니다.
@pushd %systemdrive%\
@pushd %windir%
@pushd %programfiles%
@popd
@popd
@popd

현재 위치가 어디이든 관계없이 첫 번째 pushd 명령으로 인해서 %systemdrive%\ 경로로 이동하고 내부 스택에 주어진 경로가 Push됩니다. 두 번째 pushd 명령으로 %windir%가 그 뒤를 이어서 내부 스택에 Push되며, 마지막으로 %programfiles% 경로가 내부 스택에 Push됩니다. 여기까지는 출력 결과만으로 놓고 보았을 때 cd 명령과 차이가 없어 보입니다. 그러나 popd 명령을 사용하면 차이가 나타납니다.

popd 명령을 처음 실행하면, 가장 마지막에 내부 스택에 들어갔던 %windir%가 Pop되고 현재 디렉터리로 변경됩니다. 그리고 다시 popd 명령을 실행하면 이번엔 %systemdrive%\로 현재 디렉터리가 변경됩니다. 그리고 다시 popd 명령을 실행하면 원래 위치로 되돌아가는 것을 볼 수 있습니다.

여기서 중요한 점은, 지금 스택에 집어넣고 빼낸 디렉터리들이 원래 위치했던 디렉터리 기준으로는 제각기 독립적인 노드들이었다는 점이며, 디렉터리를 스택 구조에 넣고 관리할 수 있으므로 배치 파일에서 탐색이 자유로워질 수 있다는 이점을 확인할 수 있습니다.

보너스 2: FOR 문으로 텍스트 검색하기

아래의 명령줄은 정규 표현식을 지원하지는 않지만 GREP이 아쉬운 분들을 위한, 간단히 사용할 수 있는 재귀 검색이 지원되는 파일 검색 도구입니다. (출처: http://kennethhunt.com/archives/000173.html)

문법: for /r "검색할 디렉터리" %v in (*.확장자) do find /N /I "검색할 키워드" "%~fv" >> "결과를 저장할 파일 혹은 장치"
예시: for /r "C:\Windows" %v in (*.txt) do find /n /i "Windows" "%~fv" >> "%userprofile%\result.txt"

마무리

보잘것 없어보이는 수단이지만, 때로는 PowerShell을 검토하는 것보다, VBScript를 검토하는 것보다, 그리고 우리 프로그래머 입장에서는 C++이나 C#을 검토하는 것보다 배치 파일에 기대는 것이 더 편할 수 있습니다. 파리를 잡기 위하여 패트리어트 미사일을 날리지 말고, 가까이 있고 쉽게 사용할 수 있는 도구를 여러분의 친구로 만들기를 바라며 소소하게 써내려간 시리즈를 뒤늦게나마 마무리합니다.

감사합니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2010. 1. 15. 16:45

지난번 강좌에 이어서 오늘은 if 문을 사용하여 파일, 디렉터리, 프로그램의 실행 결과를 평가하는 방법, 파일 출력을 수행하는 방법, 그리고 명령줄 인수를 받아들이는 방법을 살펴보도록 하겠습니다. 앞서 살펴본 강좌의 비교 연산자 기능을 바탕으로, 실제 수행 결과를 평가할 수 있다면 배치 파일 구문을 스크립트 프로그래밍 언어처럼 활용할 수 있을 것입니다.

 

1. 파일 및 디렉터리의 존재 여부를 판정하기

 

파일 및 디렉터리의 존재 여부를 판정하기 위하여 exist 키워드를 사용할 수 있습니다. 다음은 if문와 exist 키워드를 조합한 예시입니다.

 

if exist "%windir%\fonts\consola.ttf" echo Your system has Consola font.

 

위의 구문에서 exist 키워드 다음에 오는 인자는 존재 여부를 검사하고자 하는 경로에 대한 것으로, 환경 변수를 사용하여 혼합할 수도 있습니다. 또한, exist 키워드 앞에 not 키워드를 붙여 부정의 의미로 명령을 실행하여 결과를 뒤집는 것도 가능합니다.

 

if not exist "%windir%\fonts\consola.ttf" echo Your system does not have Consola font.

 

만약 디렉터리의 존재 여부를 파악하고자 한다면 파일 경로 대신 디렉터리 경로 대입만 하면 됩니다.

 

if exist "%windir%" echo WINDIR environment variable contains valid path.

 

여기서 한 가지 생각해봐야 할 문제점이 있는데, Windows의 경우 기본 배치 파일 명령만으로는 존재한다고 인지된 대상이 실제로 파일인지 디렉터리인지 파악할 방법이 명확하지 않다는 문제점이 있습니다.

 

파일 및 디렉터리 관련 API를 호출하면서 파일이나 디렉터리를 생성할 수 없다는 오류를 만나는 경우가 종종 있는데, 대개의 경우 권한 문제로 볼 수 있지만, 아주 드물게 디렉터리가 생성되기를 기대한 위치에서 같은 이름의 확장자가 없는 파일이 존재하여 이름이 겹치게 되어 동작이 실패할 수 있고, 반대의 경우도 있을 수 있습니다.

 

이 문제는 배치 파일에 대한 문제 뿐만이 아니라, Win32 프로그래밍을 하면서도 한번쯤 고려해볼 필요가 있는 주제일 것입니다.

 

2. 프로그램의 실행 결과를 판정하기

 

표준 Windows 배치 명령어를 통하여 프로그램의 실행 결과를 판정하는 방법은, 유닉스 기반 시스템의 경우처럼 프로그램이 반환하는 종료 코드를 기준으로 하는 것이 보편적입니다. 명령줄 해석기의 경우, 이를 %ERRORLEVEL% 변수에 보관하며, 우리가 앞서 살펴본 강좌에서처럼 %ERRORLEVEL% 변수에 대해 연산자를 사용하여 코드를 분석할 수 있습니다. 그리고 지금 소개하는 errorlevel 키워드를 if 문과 조합하여 사용하는 방법도 있습니다.

 

if errorlevel 0 echo Program is succeeded.

 

위와 같이 작성하면, 실제로는 %errorlevel% geq 0 로 해석되는 것입니다. 그리고 errorlevel 키워드 앞에 not이 붙으면 geq에 대한 대우 연산자 lss로 의미가 바뀌어 실제로는 %errorlevel% lss 0로 해석될 것입니다.

 

3. 간단한 파일 출력

 

보통의 경우, 리디렉션을 이용하여 프로그램이 표준 출력 스트림에 송신하는 컨텐츠를 하드디스크에 파일로 저장하는 기법을 많이 이용합니다. 이를 좀 더 응용하면, 연속되는 내용을 쌓아서 보관할 수도 있으므로, 이제까지 설명한 기법들을 이용하여 프로그램의 실행 결과나 변수의 내용을 분석하여 출력 파일을 작성하는 똑똑한 배치 파일도 작성할 수 있습니다.

 

echo "Hello World!" > test.txt

echo "Overwrited?" > test.txt

 

위와 같이 작성할 경우, > 연산자는 파일 연산에서 매번 새로운 파일을 만들고 덮어쓰는 의미로 해석되므로 먼저 실행한 명령어에 의하여 저장된 문자열이 담긴 파일은 사라지고, "Overwrited?" 문자열만을 보관하는 파일만 남게 됩니다. 그렇다면, 두 줄을 이어서 저장하려면 어떻게 바꾸어야 할까요? ">" 대신 ">>" 연산자로 바꾸면 답이 됩니다.

 

echo "Hello World!" >> test.txt

echo "Overwrited?" >> test.txt

 

이와 같이 작성한 파일을 화면에 출력하고 싶다면 con 이라는 예약 장치명을 지정하면 됩니다.

 

copy test.txt con

 

PRN이나 LPT1과 같은 예약 장치명이 동작한다면, 사실 더 좋을 수 있겠지만, 아쉽게도 이러한 예약 장치명을 사용하면 경우에 따라서는 인쇄 기능이 실행되지 않는 대신 명령줄 인터프리터의 실행이 중단되고 맙니다. 인쇄 기능을 사용하고자 한다면, 해당 파일에 관련이 있는 소프트웨어의 인쇄 기능을 대신 사용하는 것이 좋습니다. 메모장이나 워드패드의 경우, /p 스위치 다음에 파일 이름을 지정하여 파일을 인쇄하도록 지시할 수 있습니다.

 

notepad /p test.txt

wordpad /p test.txt

 

4. 명령줄 매개 변수 받아들이기

 

명령줄 매개 변수를 받아들이도록 배치 파일을 구성하면, 배치 파일의 활용 용도가 한층 더 깊어질 수 있습니다. 이 기능은 기본으로 제공되는 기능으로 %0 부터 %9까지의 예약 변수를 활용하면 쉽습니다. 이들 예약 변수는 C 언어를 사용하여 작성하는 main() 메서드의 char **argv 변수에서처럼 0번째 인덱스는 실행하는 배치 파일 그 자체의 Full Path를 포함하고, 1부터 실제 명령줄 인자가 포함됩니다.

 

@echo off

echo %0

if %1 equ Test echo Hello World

echo on

 

위와 같이 프로그래밍한 배치 파일을 Hi.bat 으로 저장하였을 때, 명령줄에서 아래와 같이 명령을 입력하면 Hello World라는 문구가 나타나는 것을 볼 수 있습니다.

 

Hi.bat Test

 

배치 파일 명령줄을 위한 인수로 공백을 포함한 문자열을 넘길 필요가 있을 때는, 기존과 마찬가지로 따옴표로 감싸어 넘기면 동일하게 동작합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2009. 8. 31. 18:14

요즈음 빌드 자동화 기능을 제공하는 프레임워크와 도구들이 굉장히 많이 늘었습니다. 각기 다양한 특색이 있고 장점이 존재하지만 가끔 이와 같은 도구들의 힘을 빌리지 않고 이와 유사한 기능을 작성할 필요가 있는 경우가 있습니다. 이럴 때 한치의 손색이 없는 도구가 하나 있는데 그것이 바로 명령줄 인터프리터가 직접 처리하는 Batch File입니다. 생각보다 Batch File의 능력은 다양합니다. :-)

Note: 이 Article은 Windows XP 이상의 운영 체제에 내장되어있는 Command Interpreter에 대하여 서술한 것으로 Windows 2000, Windows 9x (Microsoft DOS 7.x), Microsoft DOS 6.x 이하에는 맞지 않는 내용도 포함되어있습니다. 착오 없으시기 바랍니다. 더불어, 다른 DOS (예: 4DOS, DR-DOS 등)에서 자체적으로 제공하는 내장 Command Interpreter의 경우 자체 내장되어있는 도움말을 참고하여야 할 수 있습니다.

문자열과 숫자의 비교

일부러 찾아보고 활용해보지 않았을 뿐이지 배치 파일에도 if와 else 구문을 그대로 사용할 수 있습니다. 물론 진짜 제대로된 프로그래밍 언어에서처럼 완벽한 논리 연산을 구현한 것은 아닙니다만 배치 파일을 사용하려는 목적에는 알맞을 수 있는 기능들을 빠짐없이 훌륭하게 구현하고 있습니다.

간단한 if / else 명령문 하나를 입력해 보겠습니다.

if test equ test (echo same string) else (echo different string)
if test neq Test (echo different string) else (echo same string)

위의 명령문을 실행하면 same string 이라는 문자열이 나타납니다. 여기서 test는 보통의 DOS 명령에서 요구하는 파일 경로에 대한 것이 아니라 순수한 문자열이나 숫자가 됩니다. 그리고 equ가 동일성 여부를 판정하는 연산자가 됩니다. 만약 같지 않음을 비교하려면 neq 연산자를 대신 사용하시면 됩니다. 나머지는 보시는 그대로 괄호로 명령문이 묶인 것을 볼 수 있습니다. 괄호를 입력하지 않으면 참 조건시 실행될 echo 문의 나머지 뒷쪽 부분들이 전부 echo 명령에 대한 매개 변수로 지정되기 때문에 이를 구분한 것입니다. 그러면 이번엔 아래와 같이 특정 문자를 대문자로 바꿔서 명령을 수행해보도록 하겠습니다.

if Test equ test (echo same string) else (echo different string)

위의 명령문을 실행하면 기대한 대로 different string 이라는 문자열이 나타납니다. 여기에 부수적으로, 대/소문자 구분을 무시하여 비교하는 명령을 수행해보기로 하겠습니다.

if /i Test equ test (echo same string) else (echo different string)

/i 스위치가 대/소문자 구분을 무시하도록 지정한 것으로 결과는 기대한 대로 same string 이라는 문자열이 될 것입니다. 그렇다면 이 결과에 부정 연산자를 취하여 결과를 뒤집는 것도 가능할까요? 방법은 간단합니다.

if /i not Test equ test (echo same string) else (echo different string)

/i 스위치가 없다면 if 문 바로 다음 앞에, /i 스위치가 있다면 /i 스위치 바로 다음 앞에 not 연산자를 지정하여 Test equ test 식에 대한 결과를 반전 연산자를 통하여 뒤집게 되므로 기대하였던대로 different string 이라는 문자열이 대신 출력될 것입니다.

그렇다면 같음을 비교하는 것 말고 문자열과 숫자의 크고 작음을 비교하는 것도 가능할까요? 이번엔 아래와 같이 명령어를 넣어보겠습니다.

if test lss tess (echo a) else (echo b)
if test lss test (echo a) else (echo b)
if test lss tesu (echo a) else (echo b)

위의 명령들에 대한 수행 결과는 각각 b, b, a 가 됩니다. 프로그래밍 코드 식으로 풀이해보면 compare("test", x) < 0 에 비유할 수 있으며 앞서 본 tess와 test는 test보다 앞서거나 동일하므로 else 절의 문장이 수행된 것입니다. 반면 tesu는 test보다 뒤에 오는 단어이므로 if 절의 문장이 수행된 것입니다.

만약 위의 예제에서 lss 대신 leq를 선택한다면 test와 test를 비교하는 부분에서 b 대신 a가 선택 될 것입니다. 프로그래밍 코드 식으로 풀이한다면 compare("test", "test") <= 0 가 되므로 참에 해당되기 때문입니다. 더불어, 위의 연산 식 역시 /i 스위치와 not 연산자의 적용을 그대로 유지할 수 있으므로 이들 옵션이 위의 식에 대하여 끼치는 영향은 동일합니다.

프로그래밍 코드 식으로 compare("test", x) > 0 연산에 해당되는 것은 gtr 연산자이며, compare("test", x) >= 0 연산에 해당되는 것은 geq 연산자가 될 것입니다.

지금 이야기한 기능들은 단독으로 사용될 때 보다는 배치 파일에 주어지는 매개 변수들이나 미리 설정된 환경 변수들의 값을 다루는 데에 더 요긴하게 사용됩니다.

다음 Chapter에서는 if / else 문을 이용하여 파일이나 디렉터리의 존재 여부를 파악하는 방법, 환경 변수의 정의 여부를 파악하고 그 값을 파악하는 방법, 프로그램이나 배치 파일의 수행 결과를 if 문으로 파악하는 방법 등을 다뤄보기로 하겠습니다. :-)

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. DOS 6 책으로 배치 파일 프로그래밍을 배웠을 때가 생각납니다..ㅋㅋ

    2009.09.01 17:24 [ ADDR : EDIT/ DEL : REPLY ]
    • DOS를 사용하지는 않지만 기본 컨셉 자체는 Windows 7이 나오는 이 시점에도 여전히 유효한것 같아서 공부할 겸 올려보려고 합니다. :-)

      2009.09.03 00:44 [ ADDR : EDIT/ DEL ]

Useful Solutions2009. 3. 23. 00:36

버전 관리 시스템에 반드시 등록해두어야 하는 파일이 있고 그렇지 않은 파일 (빌드 후 생성물, 빌드 중간 단계 생성물)이 있는데 이것들을 매번 리포지터리에 속성으로 설정하기가 여간 불편한 것이 아니다. 그래서 개인적인 경험과 현재 사용하고 있는 프로젝트의 설정을 조합하여 프로그램에서 미리 설정할 수 있는 패턴을 조금 적어본다. VC++ 6.0, VS.NET, Delphi (Borland/CodeGear)를 사용하는 사용자에게 "아마도" 적당하지 않을까 싶다.

[업데이트] 2013-06-01

bin obj TempPE Debug Release Publish __history *.tvsconfig *.log *.db *.identcache *.GID *.bak *.dsk *.local *.dcu *.ncb *.user *.obj *.pdb *.pch *.suo *.opt *.aps *.clw *.plg *.~* *.o *.lo *.la *.al .libs *.so *.so.[0-9]* *.a *.pyc *.pyo *.rej *~ #*# .#* .*.swp .DS_Store *.tmp

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2009. 1. 19. 15:23

실무에서 Enterprise Manager류의 유틸리티를 직접 이용할 수 없을 경우 재빠르게 스키마를 확인해볼 수 있는 스크립트 세 종류를 올려 봅니다.

-- Informix의 Column 상세 내역 살펴보기
select a.* from syscolumns a, systables b
where (a.tabid = b.tabid) and (b.tabname = '테이블 이름')

-- Oracle의 Column 상세 내역 살펴보기
select * from sys.all_tab_cols
where table_name = '테이블 이름';

-- Microsoft SQL의 Column 상세 내역 살펴보기
use '대상 DB 이름';
select a.* from syscolumns a, sysobjects b
where (a.id = b.id) and (b.name = '테이블 이름');

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2008. 12. 17. 11:10

Windows Update는 대부분의 경우 잘 동작하지만 환경이 복잡한 네트워크나 가상 PC 환경 아래에서는 제대로 동작하지 않을 가능성이 있습니다. 그 중에서 가장 흔하게 나는 오류는 Windows Update 사이트와 PC 사이의 동적 연결이 끊어졌을 경우이며 이를 해결하는 방법들을 종합해보았습니다.

1. http://qaos.com/article.php?sid=2001

2. http://support.microsoft.com/kb/836941/ko

저의 경우는 위에서 언급한 방법으로도 해결되지 않아서 다음의 방법을 더 적용해 보았고 해결이 잘 되었습니다.

3. http://www.arkesystems.com/blog/post/2008/04/Hyper-V-Miscellaneous.aspx

3번의 방법은 레지스트리 편집기를 통하여 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters에 REG_DWORD 형식의 DisableTaskOffload 값을 추가하고 값을 1로 설정하거나, 이미 등록되어있을 경우 값을 1로 변경하고 시스템을 다시 시작하는 방법입니다.

Windows Update 관련 문제로 고민하시는 분들께 도움이 될듯하여 글을 올려봅니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 푸른하늘

    정말감사드립니다 덕분에해결되었네요
    그리고퍼감...

    2009.01.05 11:17 [ ADDR : EDIT/ DEL : REPLY ]

Useful Solutions2008. 9. 1. 13:24

사용자 삽입 이미지
 Windows Shell에서 기본으로 제공하는 Band Object를 이용하여 만들 수 있는 일상적인 도구 모음 패널을 개인적으로 애용합니다. 하지만 패널을 사용하기위하여 한참 다른 프로그램을 사용하다가 이 패널을 펼쳐보면 하드 디스크 액세스가 갑자기 심해지면서 속도가 느려지는 것을 볼 수 있습니다. 캐쉬 상에 존재하지 않는 아이콘을 다시 구축하기 위해서 취하는 동작이기는 하지만 상당히 불편합니다. 이런 불편을 최소화할 수 있는 방안을 찾아 레지스트리로 만들어보았습니다.

위의 레지스트리를 다운로드 받아서 시스템 레지스트리에 병합한 후, 제어판 - 폴더 옵션 - 보기를 살펴보면 다음과 같이 새로운 설정 항목이 나타나는 것을 볼 수 있습니다.

사용자 삽입 이미지

레지스트리와 함께 설정되는 기본 값은 2048개이며, 필요한만큼 더 늘려서 선택할 수 있습니다.적정한 수준의 캐쉬 크기를 설정하여 효과를 볼 수 있지만, 너무 많은 캐쉬를 사용할 경우 Windows Shell 프로세스의 크기가 증가할 수 있으므로 사용에 유의하여야 합니다. 이 레지스트리 설정은 Windows XP Professional Service Pack 3 (x86), Windows Vista Business SP1 (x86)에서 테스트해보았습니다.

** 주의: 이 레지스트리를 사용하는 것은 개인의 선택이며 레지스트리 사용 전에는 시스템 상태 백업 등을 수행하실 것을 권장합니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2008. 6. 17. 16:33
Out of Process 자동화 서버와 같이 스스로 메모리 관리에 책임이 있는 형태의 COM 서버들은 메모리 충돌 오류를 일으킬 가능성이 상대적으로 적다고 볼 수 있습니다. 하지만, In Process 자동화 서버의 경우, 특히 ActiveX들은 기능이 복잡할 수록 이러한 문제를 일으킬 가능성이 큽니다. 이번에 작업한 프로그램 중 하나인 HwpCtrl을 호스팅하는 닷넷 기반 응용프로그램에서도 예외는 아니었는데, 두 가지 문제점이 있었습니다.

첫 번째: 트레이 아이콘이 정리되지 않고 잔상이 남는 문제

아래아한글 소프트웨어 연구실 (http://swlab.haansoft.com) 에도 같은 문제에 관한 FAQ가 있었습니다만 "해결할 수 없다" 는 것이 답이었습니다. 그러나, 이 답에 만족하지 못해서 인터넷 이곳저곳을 찾아다니다가 문제에 매우 훌륭하게 접근하는 소스 코드 하나를 발견하였습니다.

http://cpueblo.com/programming/api/contents/197.html

위의 아티클에서 제공한 Visual C++ 소스 코드를 C#으로 이식한 후, 정리되지 않은 아이콘이 대부분 제거가 잘 된다는 것을 확인하였습니다. 하지만 제가 해결하고자 하는 문제였던 HwpCtrl ActiveX 컨트롤의 아이콘 제거는 여전히 이루어지지 않았습니다. 단순히 프로세스 ID 값을 얻어오지 못한 경우에는 속하지 않았기 때문에 이 코드가 기대하는대로 동작해주지는 않았습니다. 따라서, 프로세스를 열도록 시도하여 존재하지 않는 프로세스임을 재 확인하는 코드를 추가해야 했습니다.


위의 소스 코드 파일은 C#을 기준으로 프로그래밍된 것이지만 기본적인 컨셉은 다른 프로그래밍 언어에서도 참고할 수 있을 것입니다. 위의 코드를 컴파일 시에는 /unsafe 스위치를 지정하여 Unsafe Code를 컴파일할 수 있도록 허용해야 합니다.

위의 코드를 호출하기 위해서는, 프로세스가 한 번 이상 종료된 상태여야 했기 때문에 진입점 메서드를 이중으로 프로그래밍했습니다. 특정한 명령줄 스위치가 전달된 경우와 그렇지 않은 경우를 구분 지어 정상 모드에서 종료한 경우 프로세스를 연이어 다시 시작하게 만들고 그 자신은 종료하게 두면, 나중에 Cleanup 모드로 시작된 프로세스에 의해 실제 트레이 아이콘 정리 작업이 발생하게 됩니다.

두 번째: 프로그램 종료 직후 발생하는 알 수 없는 메모리 위반 오류

HwpCtrl을 호스팅하는 프로세스를 종료한 직후에 발생하는 알 수 없는 메모리 위반 오류 때문에 고민이 많았습니다. 이 현상은, VSHOST.EXE에서 실행되는 Visual Studio Hosting Process 모드에서는 문제가 되지 않지만, 단독으로 응용프로그램을 실행할 때 발생하는 문제였습니다.

이 문제의 해결을 위하여 Internet Explorer Control 위에서 호스팅하도록 접근 방법을 변경해 보았습니다. 참조 대상 어셈블리의 수를 줄이고 프로그램의 크기를 줄이는 효과는 있었지만 문제는 여전히 그대로였습니다. 적당한 해결 방법이 없는 상태에서 생각해낸 최종 방법은 강제 프로세스 종료였는데 문제는 시점이었습니다.

System.Windows.Forms.Application.Run 메서드가 폼 이외에 컨텍스트 개체를 통해서 GUI 메시지 루프를 시작할 수 있다는 것을 알았고, 이 컨텍스트 개체가 제공하는 메시지 루프 이탈 시점에 발생하는 이벤트를 이용하여 프로그램을 종료하도록 하였습니다. 그리고 Main 메서드 전체에 SEH 구성을 두어 catch, finally 절 이후에 강제 종료가 일어나도록 하였습니다.

결론

위의 두 가지 방법 모두 정상적인 방법이 아니지만, 문제의 해결을 위하여 적용할 수 있었던 최선의 방법이었다고 생각합니다. 또한, 위의 방법을 적용한 경우 적용된 프로그램이 Windows Vista에서 관리자 권한을 필요로 할 수도 있습니다.
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2008. 3. 27. 13:25

유지보수를 위하여 K 은행의 인천공항지점에 방문하여 알게 된 유용한 정보입니다. 비슷한 문제로 고민하고 계시는 분이 있다면 한 번 적용해보시면 어떨까 싶습니다. Windows NT 기반의 서버로 연결하는 것이 아니라면 Windows NT 인증은 필요하지 않기 때문에 sqlnet.ora 파일에서 다음의 설정을 변경하거나 주석 처리하여 문제를 해결할 수 있을듯 싶습니다.

SQLNET.AUTHENTICATION_SERVICES= (NTS)
NAMES.DIRECTORY_PATH= (TNSNAMES, EZCONNECT)
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 11. 12. 00:13

Windows Server 2003 SP1 이상에서 Visual Studio 2005 SP1을 설치하면 예상하지 못한 오류를 만나게 되는데, 정확한 설명 없이 오류 로그를 보면 단지 0x643 오류 코드만을 반환하고 설치가 종료되어 당황스러운데요, 여기에 대한 정확한 해결법이 있어서 소개해 봅니다. (이 가이드는 Microsoft Update를 통해서 Visual Studio 2005 SP1을 설치하려다 실패하신 분들에게도 적용됩니다.)

1. 시작 메뉴를 클릭하고 실행을 클릭한 후 secpol.msc를 입력하고 확인 버튼을 클릭합니다. 또는 시작 메뉴를 클릭하고 (모든) 프로그램의 관리 도구의 로컬 보안 정책을 클릭합니다. 시작 메뉴에서 관리 도구 그룹을 찾을 수 없을 경우에는 제어판을 이용하여 관리 도구 폴더를 찾을 수 있습니다.

2. 로컬 보안 설정 관리 콘솔이 나타나면 좌측의 트리 영역에 나열된 항목들 중 소프트웨어 제한 정책을 클릭합니다. 그러면 오른쪽 창에는 "정의된 소프트웨어 제한 정책 없음"을 안내하는 메시지가 나타날 것입니다. (만약 이러한 메시지 없이 어떤 항목들이 표시된다면 3단계는 건너 뜁니다.)

3. 좌측의 트리 영역에 나열된 항목들 중 소프트웨어 제한 정책을 오른쪽 버튼으로 클릭하여 나타나는 팝업 메뉴에서 "새 소프트웨어 제한 정책"을 클릭합니다.

4. 오른쪽 창에 보안 수준, 추가 규칙, 강요 등의 항목이 나타나게 되는데, 이 중에서 강요를 더블 클릭합니다.

5. "다음 항목에 소프트웨어 제한 정책 적용:" 란에 "라이브러리(예: DLL)를 제외한 모든 소프트웨어 파일" 라디오 버튼이 선택되어있는지 확인합니다. 선택되어있지 않을 경우 변경합니다.

6. "다음 사용자에게 소프트웨어 제한 정책 적용: "란에 "로컬 관리자를 제외한 모든 사용자" 라디오 버튼이 선택되어있는지 확인합니다. 선택되어있지 않을 경우 변경합니다.

7. 확인 버튼을 클릭하고, 로컬 보안 설정 관리 콘솔 창을 닫습니다.

8. 작업 중인 모든 문서와 자료들을 저장하고 컴퓨터를 다시 시작한 뒤 Visual Studio 2005 SP1 설치를 다시 시도합니다.

출처: http://blogs.msdn.com/michael_howard/archive/2007/01/01/visual-studio-2005-service-pack-1-update-for-windows-vista-beta-available.aspx

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 10. 22. 19:04

Delphi의 VCL 컨트롤 중에서 TStatusBar 컨트롤이 있습니다. 이 컨트롤은 대부분의 경우 정상적으로 원하는대로 Owner Draw를 구현하여 사용할 수 있지만 뜻하지 않게 일부 운영 체제에서는 Owner Draw가 회피당하거나 (Windows 2000), Owner Draw에 대한 처리가 정확히 마무리되지 않아서 잔상이 남는 버그 (Windows XP, Windows Server 2003)가 발생하곤 합니다. 이 문제를 해결하기 위한 두 가지 방법을 소개하고자 합니다. 참고로 이 버그는 Windows NT 4.0 + Delphi 5.0 환경에서도 발견이 되었으며 이에 그치지 않고 Delphi 2007 + Windows 2000/XP/Server 2003에서도 여전히 나타나는 버그로 보입니다.

Solution 1: 제일 손쉬운 방법은 TStatusBar 컨트롤의 부모를 TForm이 아닌 TPanel로 하여 TPanel을 대신 TForm에 올려놓는 방법입니다. 이렇게 하면 고질적인 Owner Draw 렌더링 버그를 원천적으로 해결하고 멤버 변수 선언에도 영향을 주지 않으므로 리팩터링이 필요하지 않습니다.

Solution 2: 이미 디자인타임에서 컨트롤을 많이 사용하였고 마우스로 조작하기 까다로운 UI를 가진 창에서 문제가 발생한다면 - 또는 - 프로그래밍 방식으로 문제를 해결할 필요가 있다면 다음의 지침에 따라 WndProc 메서드를 추가 구현합니다.

Procedure TForm1.WndProc(var Message: TMessage);
Begin
   Case Message.Msg Of
      { 이런저런 메시지 처리 코드가 포함될 것입니다. 생략합니다. }
      WM_DRAWITEM:
      Begin
         If (Message.WParam) <> 0 And (Message.LParam) <> 0 Then
         Begin
            With PDrawItemStruct(Message.LParam)^ Do
            Begin
               If ctlType = ODT_TYPE Then
                  ctlType := 0;
            End;
         End;
      End;
   End;
   { 상위 윈도 메시지 처리기를 호출하지 않으면 문제가 발생하므로 꼭 확인합니다. }
   Inherited WndProc(Message);
End;

굵게 표시한 코드가 문제를 해결하는데 필요한 코드와 잊지 말아야 할 코드들입니다. 만약 WndProc 메서드를 처음 오버라이드하는 경우 상위 메시지 처리기 호출을 놓치기 쉽습니다. 폼을 생성하지 못하고 에러 메시지만 나온 후 프로그램이 바로 종료되어버린다면 반드시 WndProc 메서드가 상위 메시지 처리기를 올바르게 호출하고 있는지 점검해야 하겠습니다.

도움이 되셨기를 바랍니다. :-)

자료 출처: http://buglist.jrsoftware.org/generated/entry0624.htm

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 10. 15. 23:43

Windows Live의 새로운 서비스 중 하나인 Custom Domains 서비스는 자기가 가지고 있는 도메인 주소를 실용적으로 사용할 수 있게 해주는 보석같은 서비스이다. Custom Domain이 처음 소개된 것은 자기 도메인 주소 앞으로 발급받을 수 있는 무료 전자 메일 서비스덕이었고, 이제는 기능이 더 늘어나서 특정 사이트 검색, Windows Live Space 연동, live.com 페이지 스크랩 등의 기능까지 제공한다.

Custom Domain 서비스를 사용하기 위해서는 사실 개인이 직접 운영하는 DNS 서버가 필요하다. 하지만 DNS 서버를 구축하는데 드는 금전적인 비용은 물론 시간과 노력이 상당히 크기 때문에 보통의 사용자들에게는 큰 무리이다. 그러나 Custom Domain 서비스와 궁합이 잘 맞는 매력적인 DNS 서비스가 있는데 바로 dnsever.com이다.

dnsever.com은 DNS 서버 구축에 드는 비용을 최소화하면서도 빠른 응답 속도와 성능, 그리고 인터넷 브라우저 기반의 편리한 환경 설정 시스템을 자랑하는 무료 서비스이다. 필요하다면 공짜 도메인도 가져다 쓸 수 있으며 Dynamic DNS 서비스도 제공하므로 홈페이지 운영을 웹 호스팅 없이 개인이 직접 하고자하는 경우에도 유용하다.

또한 dnsever.com은 Custom Domain 서비스의 모든 기능을 사용할 수 있도록 고급 옵션들을 전부 개방하고 있는데, SRV 레코드, CNAME 레코드, TXT 레코드, MX 레코드를 관리할 수 있다. 이 외에도 IPv6 주소를 위한 AAAA 레코드, 주소 포워딩 서비스까지 제공하고 있다.

결론은 Windows Live 서비스와 dnsever.com 만으로 사실상 개인이 원하는 모든 서비스를 한꺼번에 제공받고 구축할 수 있다. 블로그, 사이트 통합 검색, 웹 브라우저를 위한 맞춤형 시작 페이지, 전자 메일 서비스까지 없는게 없다.

DNSEVER 홈페이지: http://www.dnsever.com
Windows Live Custom Domains 홈페이지: http://domains.live.com

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 8. 9. 15:07
프로그래밍을 하거나 컴퓨터 관리 작업 따위를 하면서 파일이나 폴더에 관한 경로 문제는 다루기가 참 껄끄럽다. 특히 프로그래밍을 할 때에는 파일이나 폴더에 관해서만큼은 정확하고 세심해야 한다고 생각하기 때문에 어떤 기준이 필요하다고 개인적으로 생각한다.

적어도 몇 가지 디렉터리에 관해서는 확실히 해두면 편리하지 않을까라는 생각에서 우연히 환경 변수들을 조사해보기 시작하게 되었다. 환경 변수들 가운데서는 우리가 전혀 모르고 있었거나 기억에서 사라진 변수들도 꽤 있다.

%WINDIR%와 %SYSTEMROOT%: 현재 실행 중인 Windows 운영 체제가 설치된 경로를 저장하는 환경 변수이다. 여기에는 설치된 파티션을 가리키는 드라이브 문자도 같이 포함된다. 이 변수를 기준으로 System32 폴더에는 매우 손쉽게 접근할 수 있을 것이다.

%PROGRAMFILES%: 현재 실행 중인 Windows 운영 체제와 직접 관련이 있는 Program Files 폴더에 대한 경로를 저장하는 환경 변수이다. %WINDIR% 변수와 마찬가지로 설치된 프로그램에 대한 손쉬운 접근을 하고 싶다면 이 변수를 이용하면 된다.

%HOMEDRIVE%: 현재 로그인한 사용자의 프로파일 디렉터리가 위치한 파티션 드라이브의 문자를 저장하는 환경 변수이다. C:, D: 같은 값을 반환한다.

%SYSTEMDRIVE%: 현재 실행 중인 Windows 운영 체제가 설치된 파티션의 드라이브 문자를 저장하는 환경 변수이다. C:, D: 같은 값을 반환한다.

%USERPROFILE%: Documents And Settings 폴더 아래의 현재 로그인한 사용자의 프로파일 디렉터리 경로를 저장하는 환경 변수이다.

%ALLUSERSPROFILE%: 새로운 사용자를 생성하거나 여러 사용자에 걸쳐서 공통되는 내용을 저장하는 공용 사용자의 프로파일 디렉터리 경로를 저장하는 환경 변수이다.

%COMSPEC%: cmd.exe 프로그램의 경로를 %WINDIR% 등의 변수로 일일이 찾지 않아도 이 변수 하나면 바로 가리킬 수 있다.

%APPDATA%: 현재 로그인한 사용자의 프로파일 디렉터리 밑의 Application Data 폴더에 대한 경로를 저장하는 환경 변수이다.

%COMMONPROGRAMFILES%: Common Program Files 폴더에 대한 디렉터리 경로를 저장하는 환경 변수이다.

%LOGONSERVER%: 현재 로그인한 서버의 UNC 경로나 Active Directory 경로 등을 저장하는 환경 변수이다.

%NUMBER_OF_PROCESSORS%: 시스템에 장착된 CPU 코어의 수를 저장하는 환경 변수이다.

%OS%: 기본적으로 Windows_NT 라는 문자열을 반환한다.

%PATH%: 따로 설명하지 않아도 너무 유명한 환경 변수이다. 명령어 해석기나 Shell 실행 등에서 검색할 기본 경로들을 이곳에 넣어주어도 되고 반대로 세미콜론을 토큰 분할자로 사용하여 각각의 경로를 찾을 수도 있다.

%PATHEXT%: %PATH%로 검색하고자 하는 파일의 유형들을 이곳에서 설정하면 된다. 주로 실행 파일의 확장자들을 이곳에 배치시켜두는 것이 일반적이다.

%PROCESSOR_ARCHITECTURE%: 프로세서의 아키텍처를 설명하는 문자열을 저장하는 환경 변수이다. 우리가 사용하는 컴퓨터들을 기준으로 해보면 주로 x86이라는 문자열을 반환할 확률이 높다.

%PROCESSOR_IDENTIFIER%: 프로세서 식별 문자열을 저장하는 환경 변수이다.

%PROCESSOR_LEVEL%과 %PROCESSOR_REVISION%: 프로세서의 기타 세부 정보들을 저장하는 환경 변수들이다.

%PROMPT%: 명령 프롬프트의 프롬프트 서식을 가져오거나 설정할 수 있는 환경 변수이다.

%TEMP%와 %TMP%: 현재 사용자에게 할당된 임시 디렉터리 경로를 저장하는 환경 변수들이다.

%ERRORLEVEL%: 어떤 프로그램을 실행하고난 직후 그 프로그램이 반환한 코드 값을 저장하는 환경 변수이다.

환경 변수들을 쭉 살펴보면서 상당히 편리하고 유리한 것들이 많다는 것을 알 수 있다. 그런데 환경 변수에는 놀랍게도 두 가지 맹점이 있다. 첫 번째는 일부 환경 변수들은 사용자나 관리자에 의해서 임의로 편집될 수 있다는 것과 두 번째는 정식으로 Windows 운영 체제를 설치하여 구동한 환경이 아닌 Windows Preinstallation Environment에서는 위에서 언급한 환경 변수들을 사용할 수 없다.
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 8. 5. 17:42

닷넷 프레임워크에서 DLL을 호출하고 다루는 방법은 2.0에 들어와서부터는 사실상 완전해졌다. 1.0/1.1때부터는 종전의 Visual Basic 6.0과 비슷한 방식으로 함수의 시그니처를 제어하는 방식으로 외부 DLL에 대한 링크를 걸 수 있었고 2.0에 와서는 드디어 GetProcAddress와 같은 함수가 노출하는 함수 포인터 주소를 직접적으로 대리자로 치환하거나 반대의 일도 할 수 있게 되었기 때문이다. 그리고 같이 추가된 기능이 있다면 MDA 에이전트가 있다는 점이다. 닷넷 프레임워크의 입장에서보기에 "이건 좀 어폐가 있는게 아니냐"는 불평이 MDA 에러 방식으로 나타난다.

서버 관리 도구를 작성하는 도중 종전의 제어판 모듈과 몇 몇 숨겨진 위저드 DLL 모듈을 호출할 일이 있어서 구글에게 물어보니 ~RunDLL 시리즈 함수들에 대한 호출법은 열의 아홉이 rundll32.exe를 사용하는 방식이었다. 사실 이런 함수들은 프로그래밍 언어에서는 직접 연결할 수가 없다. 그저 Shell 명령어 해석기를 통해 간접적으로 rundll32.exe에게 호출을 의뢰하는 것 밖에는 방법이 없다. 하지만 rundll32.exe를 통하여 대리 실행하는 방법말고 좀 더 빠른 방법을 찾아보고 싶었다. 즉, 직접 해당 DLL의 해당 함수에 연결하는 방법이다.

특별한 명시가 없어도 대부분의 Windows용 DLL의 노출된 함수들은 호출자 시그니처에 WINAPI 어트리뷰트가 붙는다는 것을 "가정"해 보고 작업을 시작해보았지만 생각보다 일이 어려웠다. 진짜 문제는 닷넷 프레임워크의 P/Invoke가 너무 관대하다는데에 있었는데, 함수 시그니처까지 정확히 검사하지는 않고 있었고 그저 함수 진입점만 찾을 수 있었다고 하면 일단 들어가고 보는 것이었다. 들어가는 것은 좋지만 나올때가 문제인데, 시그니처가 정확하지 않기 때문에 스택이 함수 호출 전과 후의 모습이 상이하게 달라지게 되었기 때문이다.

일단은 rundll32.exe를 가지고 호출하는 방법으로 아쉽게 넘어갔지만 좀 더 시간을 내어 한 번 살펴볼 생각이다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 4. 10. 10:16

SysInternals.com에서 오픈소스로 공개하고 있는 유용한 시스템 유틸리티들이 많이 있습니다. 이 중에서 엄선한 유틸리티 몇 개를 소개합니다. Windows NT 관리자라면 누구나 필요할만한 유틸리티들입니다.

* du.exe: 디스크 사용량을 조사하는 명령행 유틸리티입니다.

* junction.exe: Windows 2000 및 NTFS 5.0 이상의 시스템에서 사용 가능한 유틸리티로 리눅스나 유닉스에서처럼 특정 디렉터리 아래에 특정 파티션을 링크합니다.

* movefile.exe: 실행 중인 웜 바이러스나 시스템 개체들처럼 사용 중이기 때문에 이동이 불가능한 파일들을 시스템 시작 전에 이동하도록 예약하는 프로그램입니다.

* pagedfrg.exe / pagedfrg.hlp: 페이징 파일, 레지스트리 하이브와 같이 사용자 모드에서는 "조각 모음"이 안되는 개체들을 시스템이 시작하기 직전에 "조각 모음"을 수행합니다. hlp 파일은 도움말 파일이며 pagedfrg.exe 자체는 명령행 유틸리티로서도 사용이 가능하고 그냥 실행하면 대화 상자가 나타납니다.

* pendmoves.exe: 시스템을 재시작하면 이동하거나 제어하기 위하여 예약해둔 파일들의 목록을 조회하거나 편집합니다.

* sdelete.exe: 복구할 수 없게 파일을 완전히 삭제하는 유틸리티입니다. FAT32 및 NTFS 모두 사용 가능하며 삭제한 구역을 n회만큼 반복하여 덮어씌우는 방식으로 파일을 완전히 소거합니다.

* sigcheck.exe: 인증서로 서명된 파일의 상세 정보를 보거나 기록을 덤프로 남겨둡니다.

* sync.exe: Unix 및 Linux의 Disk Sync 유틸리티와 기능은 같습니다. 캐시에 저장된 모든 내용을 실제 디스크에 모두 내보내고 디스크를 분리할 수 있도록 준비하며, 실제로 디스크를 분리하는 옵션도 있습니다.

* volumeid.exe: 디스크 포맷 등으로 보통은 자동으로 설정되는 Volume ID를 수동으로 편집하거나 확인하는 유틸리티입니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2007. 2. 3. 00:00
Subversion 1.4 시리즈 이후부터 가능한 것으로 sc.exe 유틸리티가 필요하다. sc.exe는 Visual Studio .NET / Visual Studio 2005을 설치하거나 Windows SDK 최신 버전을 설치하면 자동으로 포함된다.

sc.exe 유틸리티는 Windows NT 서비스에 관한 운영 체제의 API를 커맨드 라인 유틸리티의 형식으로 직접 노출한 것이기 때문에 매우 다양하고 구체적인 옵션을 제공한다. 그러나 아무렇게나 사용하면 완벽한 해킹 툴이 되기 쉽다. 쉽게 말해서 굉장히 예리한 도구이다.

sc.exe로 서비스를 등록하기

sc create [프로그래밍 ID 방식의 서비스 이름] binpath= "서비스로 실행할 실행 파일의 경로와 해당 파일에 전달할 매개 변수" displayname= "서비스 관리자 애플릿에서 표시할 정식 이름" depend= "다른 관련된 서비스의 ID" start= "시작 형태" obj= "서비스 시작에 사용할 Windows NT 계정 이름"

굉장히 긴 옵션들이다. 하지만 서비스 등록을 위하여 모두 필요한 사항이니 놓치면 안된다. 그리고 미리 이야기하자면 sc.exe의 명령줄 옵션은 문법이 까다로운 편이다. 등호 다음에 오는 공백은 sc.exe가 나름의 구문 분석 규칙을 정의해 놓은 것으로 이해하고 따라야 한다. 즉, sc.exe는 스위치 이름을 binpath, displayname과 같이 인식한다기보다 binpath=, displayname= 까지 인식한다고 보는 것이 정확하다.

sc create까지가 하나의 명령어라고 생각하면 편리하다. 그 다음에 오는 필수 인수가 [프로그래밍 ID 방식의 서비스 이름]이다. 여기에는 영문명만을 사용하는 것을 권장하며 영어 대/소문자를 구분하지는 않는다.

binpath는 서비스로 실행할 파일의 경로와 해당 실행 파일에 전달할 인수를 한꺼번에 지정하는 옵션이다. 파일 경로 상에 공백이 포함되면 따옴표로 묶는다는 것은 기본 상식이다. 하지만 이렇게 한 번 따옴표를 쓰고 나면 인수에는 따옴표를 전달할 수 없는게 아니냐는 고민에 빠지기 쉬운데 그런 고민은 할 필요 없다. 신경쓰지 말고 필요한 만큼 따옴표를 쓰면 된다. 하지만 너무 복잡한 따옴표 표기 규칙을 요구하면 잘못 전달될 수도 있다.

displayname은 서비스 관리자 애플릿 (services.msc)에서 표시할 이름을 의미한다. 서비스 관리자에서 알아볼 수 있는 편리한 이름을 정해서 기입하면 되며 한국어나 중국어와 같은 2바이트 언어를 사용하여도 무방하다.

depend는 이 서비스를 실행하기 위하여 필요한 다른 서비스의 ID를 써주는 곳이다. 여러 개의 서비스에 종속되어있다면 '/' 기호를 써서 구분해주면 된다.

start는 이 서비스를 언제 실행할 것인가에 대한 사항을 적는 곳이다. 보통은 auto, demand 중 하나를 선택한다. auto는 시스템 서비스가 모두 시작되었으며 아직 로그인은 하지 않은 상태에서 실행하는 것을 말하며, demand는 어떤 형태로든 시스템에 대한 사용 권한을 얻은 이후에 직접 구동하는 것 (사용자가 아닌 프로그램에 의한 것도 포함하여)을 말한다. 다른 옵션으로는 disabled, boot, system이 있는데 boot와 system은 일반적인 Windows NT 서비스에는 적당하지 않다. boot와 system은 주로 장치 드라이버와 연관된 서비스나 운영 체제 핵심 서비스에만 한정되는 내용이다. disabled는 거의 쓸 일이 없으며 이름 그대로 "사용하지 않도록 등록한다"는 의미이다.

obj는 이 서비스를 실행할 사용자 계정을 지정하는 곳이다. 대개 서비스를 등록하는 것은 특정 사용자와는 무관하게 독립적으로 실행되기 위한 것이므로 NT AUTHORITY\LocalService를 지정하면 적당하다. 하지만 직접 계정을 지정한다면 password 옵션을 써서 비밀 번호를 따로 지정해야 한다.

위의 설명에 따라서 svnserve.exe를 서비스로 등록하려면 다음과 같이 명령을 내리면 되겠다. %programfiles% 환경 변수를 사용하여 Program Files 폴더를 편리하게 지정할 수 있는데, 만약 이 환경 변수를 사용할 수 없다면 직접 기입해야 할 것이다.

sc create svnserve binpath= "%programfiles%\Subversion\bin\svnserve.exe --service --root "C:\Repos"" displayname= "Subversion Server" depend= tcpip start= auto obj= "NT AUTHORITY\LocalService"

이렇게 등록하고 서비스를 서비스 관리자에서 시작하면 TCP 포트를 점유한 상태로 시작할 것이다. 좀 더 자세한 내용은 svnserve.exe가 TCP 모드로 동작하는 경우를 살펴보면 되겠다.

sc delete로 서비스 제거하기

sc delete는 사용법이 간단하다.

sc delete [프로그래밍 ID 방식의 서비스 이름]

마찬가지로 [프로그래밍 ID 방식의 서비스 이름] 부분이 해당 서비스의 ID로 바뀌면 된다. 하지만 이 명령어를 사용할 때 챙겨야 할 것은 서비스를 종료한 상태에서 호출해야 한다는 점이다. 또한 여기에 올 수 있는 서비스는 Windows 핵심 서비스가 될 수도 있으므로 각별히 주의해야 하겠다.
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2006. 12. 25. 23:00

개인적으로는 Install Shield를 이용한 패키징 작업을 선호하지 않는 편이기 때문에 NSIS나 Inno Setup 같이 시스템에 적은 영향을 주면서 패키징할 수 있는 Installer 제작 시스템을 계속 찾고 있었다. 이러한 무료 Installer 제작 시스템들은 굉장히 강력하지만, 모든 것을 스크립팅에 의존하여 프로그래밍해야 한다는 점이 다소 걸렸다.

NSIS의 경우 Eclipse의 Plugin 형태로 설치하여 편리하게 개발할 수 있는 도구가 소개되었다. 하지만 Install Shield를 사용하는 것에 익숙한 사용자들에게는 다소 불편함이 있을 수 있겠다. 그리고 개인적으로 더 구미에 당기는 것은 ISTool 이라는 소프트웨어로 Inno Setup을 위한 전용 개발 툴이다.

http://www.istool.org

최신 버전의 Inno Setup Compiler를 지원하고 있고 배우기가 참 쉽다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

  1. 뭔가 멋진 블로그가 되었군요 :D

    2006.12.29 21:39 [ ADDR : EDIT/ DEL : REPLY ]

Useful Solutions2006. 12. 9. 11:32

유명한 데이터베이스들에 접근하기 위한 연결 문자열 컬렉션을 제공하는 사이트가 있다. 흔히 사용하는 데이터베이스는 물론 데이터 파일, 액티브 디렉터리등에 연결할 수 있도록 해주는 연결 문자열을 모아놓았다. 보잘것 없어뵈지만 절대 보잘것 없지 않은 그런 사이트이니 북마크에 빠지면 안되겠다.

http://www.connectionstrings.com

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Useful Solutions2004. 11. 19. 00:03

아마도 이 게시물의 성격 상 해킹 존으로 이동하는 것이 바람직할 것이라 생각되어 올립니다.

Win32의 API 중에 GetWindowText라는 API를 캡슐링한 콘솔 프로그램 하나를 급조했습니다. 필요에 의해서 작성한 것이지만 무척 요긴하게 쓰는 중입니다. Visual Studio의 개발 보조 도구 중 Spy++ 라는 유틸리티와 같이 사용하시면 편리합니다.

Spy++를 통하여 찾은 16진수 형태의 윈도우 핸들 값을 다음과 같이 명령줄로 실행하면 표준 출력 스트림으로 GetWindowText API의 결과물이 나옵니다.

whook [16진수 윈도우 핸들값]

이것을 리디렉션을 사용하여 파일로 쓰시면 텍스트 박스의 내용을 그대로 가져올 수 있습니다.

whook [16진수 윈도우 핸들값] > log.txt

모노와 크게 상관은 없는 것이지만 Win32용 모노에서도 빌드가 가능하니 많은 활용 바랍니다. ^^; 리플렉션 강좌를 올리기 전에 팁도 하나 올렸으면 하여 이곳에 소스 코드와 프로그램을 같이 올립니다.

using System;
using System.Text;
using System.Globalization;
using System.Runtime.InteropServices;

namespace DevDream.Services.WindowHook
{
   internal sealed class MainObject
   {
       [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
       private static extern int GetWindowText(
           IntPtr hWnd,
           [Out] StringBuilder lpString,
           int nMaxCount);

       [MTAThread()]
       private static void Main(string[] arguments)
       {
           try
           {
               IntPtr targetHandle = new IntPtr(Int64.Parse(arguments[0], NumberStyles.AllowHexSpecifier));
               StringBuilder buffer = new StringBuilder();
               GetWindowText(targetHandle, buffer, Int32.MaxValue);
               Console.Out.Write(buffer.ToString());
           }
           catch(IndexOutOfRangeException)
           {
               Console.Error.WriteLine("Handle value is not specified. whook is now closing.");
               Environment.Exit(-1);
           }
           catch(ArgumentNullException)
           {
               Console.Error.WriteLine("Handle value is not specified. whook is now closing.");
               Environment.Exit(-1);
           }
           catch(ArgumentException)
           {
               Console.Error.WriteLine("Handle value is not specified. whook is now closing.");
               Environment.Exit(-1);
           }
           catch(FormatException)
           {
               Console.Error.WriteLine("Handle value not contains ANSI characters. whook is now closing.");
               Environment.Exit(-1);
           }
           catch(OverflowException)
           {
               Console.Error.WriteLine("Handle value is too big. whook is now closing.");
               Environment.Exit(-1);
           }
           catch
           {
               Console.Error.WriteLine("Unexpected exception occurred. whook is now closing.");
               Environment.Exit(-1);
           }
       }
   }
}
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요