연습: 네이티브 코드를 사용하여 Global-Level HTTP 모듈 만들기

이 연습에서는 C++를 사용하여 IIS 7에서 새 요청 처리 아키텍처를 구현하는 샘플 글로벌 수준 HTTP 모듈을 만드는 방법을 보여 줍니다. 이 새로운 아키텍처는 이전 버전의 ASP.NET HTTP 모듈 및 ISAPI 필터 또는 확장을 통해 IIS 애플리케이션을 작성할 때 네이티브 코드 프로그래밍의 기능을 확장합니다. 새 요청 처리 아키텍처를 사용하여 HTTP 모듈을 디자인하는 방법에 대한 자세한 내용은 Native-Code HTTP 모듈 디자인을 참조하세요.

이 연습에서는 HTTP 모듈에 대한 C++ 프로젝트를 만들고 "헬로 월드" 프로젝트에 필요한 코드를 추가한 다음 모듈을 컴파일하고 테스트합니다.

사전 요구 사항

예제의 단계를 완료하려면 다음 소프트웨어가 필요합니다.

  • IIS 7.

  • Visual Studio 2005.

참고

연습 단계가 동일하지 않을 수도 있지만 Visual Studio .NET 2003 이하를 사용할 수도 있습니다.

모듈 만들기

연습의 이 부분에서는 HTTP 모듈에 대한 빈 C++ DLL 프로젝트를 만듭니다.

새 C++ DLL 프로젝트를 만들려면

  1. Visual Studio 2005를 시작합니다.

  2. 전역 옵션에 SDK에 대한 올바른 경로가 모두 포함되어 있는지 확인합니다.

    1. 도구 메뉴에서 옵션을 클릭합니다.

    2. 트리 뷰에서 프로젝트 및 솔루션 노드를 확장한 다음 VC++ 디렉터리를 클릭합니다.

    3. 디렉터리 표시 드롭다운 상자에서 파일 포함을 선택합니다.

    4. SDK 포함 파일을 설치한 경로가 나열되어 있는지 확인합니다. 경로가 나열되지 않은 경우 새 줄 아이콘을 클릭한 다음 SDK 포함 파일을 설치한 경로를 추가합니다.

    5. 확인을 클릭합니다.

  3. 새 C++ 프로젝트를 만듭니다.

    1. 파일 메뉴에서 새로 만들기를 가리킨 다음 프로젝트를 클릭합니다.

      새 프로젝트 대화 상자가 열립니다.

    2. 프로젝트 형식 창에서 Visual C++ 노드를 확장한 다음 Win32를 클릭합니다.

    3. 템플릿 창에서 Win32 프로젝트를 선택합니다.

    4. 이름 상자에 HelloWorld를 입력합니다.

    5. 위치 상자에 샘플의 경로를 입력합니다.

    6. 확인을 클릭합니다.

      Win32 애플리케이션 마법사가 열립니다.

    7. 애플리케이션 설정을 클릭합니다.

    8. 애플리케이션 유형에서 DLL을 클릭합니다.

    9. 추가 옵션에서 빈 프로젝트를 클릭합니다.

    10. Finish를 클릭합니다.

코드 및 소스 파일 추가

다음 단계는 필요한 C++ 및 모듈 정의 파일을 프로젝트에 추가하는 것입니다.

프로젝트에 원본 파일을 추가하려면

  1. RegisterModule 함수를 내보내는 모듈 정의 파일을 만듭니다.

    1. 솔루션 탐색기 원본 파일을 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음 새 항목을 클릭합니다.

      새 항목 추가 대화 상자가 열립니다.

    2. 범주 창에서 Visual C++ 노드를 확장한 다음 코드를 클릭합니다.

    3. 템플릿 창에서 모듈 정의 파일 템플릿을 선택합니다.

    4. 이름 상자에 HelloWorld를 입력하고 위치 상자에 파일의 기본 경로를 그대로 둡니다.

    5. 추가를 클릭합니다.

    6. 다음 코드를 추가합니다.

      LIBRARY HelloWorld  
      
      EXPORTS  
          RegisterModule  
      
  2. 필요에 따라 /EXPORT:RegisterModule 스위치를 사용하여 RegisterModule 함수를 내보낼 수 있습니다.

    1. 프로젝트 메뉴에서 HelloWorld 속성을 클릭합니다.

    2. 트리 뷰에서 구성 속성 노드를 확장하고 링커 노드를 확장한 다음 명령줄을 클릭합니다.

    3. 구성 드롭다운 상자에서 모든 구성을 선택합니다.

    4. 추가 옵션 상자에 /EXPORT:RegisterModule을 입력합니다.

    5. 확인을 클릭합니다.

  3. C++ 파일을 만듭니다.

    1. 솔루션 탐색기 원본 파일을 마우스 오른쪽 단추로 클릭하고 추가를 가리킨 다음 새 항목을 클릭합니다.

      새 항목 추가 대화 상자가 열립니다.

    2. 범주 창에서 Visual C++ 노드를 확장한 다음 코드를 클릭합니다.

    3. 템플릿 창에서 C++ 파일 템플릿을 선택합니다.

    4. 이름 상자에 HelloWorld를 입력하고 위치 상자에 파일의 기본 경로를 그대로 둡니다.

    5. 추가를 클릭합니다.

    6. 다음 코드를 추가합니다.

      #define _WINSOCKAPI_
      #include <windows.h>
      #include <sal.h>
      #include <httpserv.h>
      
      // Create the module's global class.
      class MyGlobalModule : public CGlobalModule
      {
      public:
      
          // Process a GL_APPLICATION_START notification.
          GLOBAL_NOTIFICATION_STATUS
          OnGlobalPreBeginRequest(
              IN IPreBeginRequestProvider * pProvider
          )
          {
              UNREFERENCED_PARAMETER( pProvider );
              WriteEventViewerLog( "Hello World!" );
              return GL_NOTIFICATION_CONTINUE;
          }
      
          VOID Terminate()
          {
              // Remove the class from memory.
              delete this;
          }
      
          MyGlobalModule()
          {
              // Open a handle to the Event Viewer.
              m_hEventLog = RegisterEventSource( NULL,"IISADMIN" );
          }
      
          ~MyGlobalModule()
          {
              // Test whether the handle for the Event Viewer is open.
              if (NULL != m_hEventLog)
              {
                  // Close the handle to the Event Viewer.
                  DeregisterEventSource( m_hEventLog );
                  m_hEventLog = NULL;
              }
          }
      
      private:
      
          // Create a handle for the event viewer.
          HANDLE m_hEventLog;
      
          // Define a method that writes to the Event Viewer.
          BOOL WriteEventViewerLog(LPCSTR szNotification)
          {
              // Test whether the handle for the Event Viewer is open.
              if (NULL != m_hEventLog)
              {
                  // Write any strings to the Event Viewer and return.
                  return ReportEvent(
                      m_hEventLog,
                      EVENTLOG_INFORMATION_TYPE, 0, 0,
                      NULL, 1, 0, &szNotification, NULL );
              }
              return FALSE;
          }
      };
      
      // Create the module's exported registration function.
      HRESULT
      __stdcall
      RegisterModule(
          DWORD dwServerVersion,
          IHttpModuleRegistrationInfo * pModuleInfo,
          IHttpServer * pGlobalInfo
      )
      {
          UNREFERENCED_PARAMETER( dwServerVersion );
          UNREFERENCED_PARAMETER( pGlobalInfo );
      
          // Create an instance of the global module class.
          MyGlobalModule * pGlobalModule = new MyGlobalModule;
          // Test for an error.
          if (NULL == pGlobalModule)
          {
              return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
          }
          // Set the global notifications and exit.
          return pModuleInfo->SetGlobalNotifications(
              pGlobalModule, GL_PRE_BEGIN_REQUEST );
      }
      
  4. 필요에 따라 호출 규칙을 사용하여 코드를 컴파일할 __stdcall (/Gz) 수 있습니다.

    1. 프로젝트 메뉴에서 HelloWorld 속성을 클릭합니다.

    2. 트리 뷰에서 구성 속성 노드를 확장하고 C/C++ 노드를 확장한 다음 고급을 클릭합니다.

    3. 구성 드롭다운 상자에서 모든 구성을 선택합니다.

    4. 호출 규칙 드롭다운 상자에서 __stdcall(/Gz)를 선택합니다.

    5. 확인을 클릭합니다.

모듈 컴파일 및 테스트

HTTP 모듈에는 필요한 모든 것이 있습니다. HTTP 모듈을 컴파일하고 테스트하기만 하면 됩니다.

프로젝트를 컴파일하고 테스트하려면

  1. HTTP 모듈을 컴파일합니다.

    1. 빌드 메뉴에서 솔루션 빌드를 클릭합니다.

    2. Visual Studio에서 오류 또는 경고를 반환하지 않았는지 확인합니다. 오류 또는 경고가 발생하는 경우 프로젝트를 테스트하기 전에 해당 문제를 resolve 합니다.

  2. HTTP 모듈의 DLL 파일을 IIS 폴더에 복사합니다.

    1. Windows Explorer 열고 C++ 프로젝트를 만들 때 지정된 기본 폴더를 찾습니다.

      빌드 옵션에 따라 프로젝트의 기본 폴더에 디버그 또는 릴리스라는 폴더가 표시됩니다.

    2. 디버그 또는 릴리스 폴더 내에서 HelloWorld.dll 파일을 찾습니다.

    3. 기본적으로 %WinDir%\System32\Inetsrv에 있는 Inetsrv 폴더에 HelloWorld.dll 파일을 복사합니다.

  3. 모듈 목록에 HelloWorld.dll 모듈을 추가합니다(지침은 Native-Code HTTP 모듈 디자인 참조).

  4. 인터넷 Explorer 사용하여 웹 사이트로 이동합니다. 일반적인 웹 사이트 콘텐츠가 표시됩니다.

  5. Windows 이벤트 뷰어 열고 전역 애플리케이션 로그로 전환합니다. "IISADMIN"을 이벤트 원본으로 나열하는 항목이 표시됩니다.

  6. 이벤트를 마우스 오른쪽 단추로 클릭한 다음 속성을 클릭하여 이벤트 세부 정보를 봅니다. 설명 창에 "헬로 월드!" 메시지가 표시됩니다.

설정 문제 해결

모듈이 컴파일되지 않거나 예상대로 작동하지 않는 경우 검사 수 있는 몇 가지 영역은 다음과 같습니다.

  • 내보낸 함수에 대해 지정 __stdcall 했거나 호출 규칙을 사용하여 컴파일을 __stdcall (/Gz) 구성했는지 확인합니다.

  • 정의 파일에 올바른 RegisterModule 내보내기를 추가했는지 확인합니다.

  • 프로젝트 설정에 정의 파일을 추가해야 합니다. 프로젝트 설정에 파일을 추가하려면 다음 단계를 완료합니다.

    1. 프로젝트 메뉴에서 속성을 클릭합니다.

    2. 트리 뷰에서 구성 속성 노드를 확장하고 링커 노드를 확장한 다음 입력을 클릭합니다.

    3. 모듈 정의 파일 설정의 경우 정의 파일이 나열되어 있는지 확인합니다.

추가 정보