Пошаговое руководство: Создание HTTP-модуля глобального уровня с использованием нативного кода

В этом пошаговом руководстве показано, как использовать C++ для создания примера модуля HTTP глобального уровня, реализующего новую архитектуру обработки запросов в IIS 7. Эта новая архитектура расширяет возможности программирования на нативном коде при разработке приложений IIS, когда используются более ранние версии ASP.NET, модули HTTP и фильтры или расширения ISAPI. Дополнительные сведения о проектировании модулей HTTP с использованием новой архитектуры обработки запросов см. в "Проектирование модулей HTTP в собственном коде".

В этом пошаговом руководстве вы создадите проект C++ для модуля HTTP, добавьте необходимый код для проекта Hello World, а затем скомпилируйте и протестируйте модуль.

Необходимые условия

Для выполнения действий, описанных в примере, требуется следующее программное обеспечение:

  • IIS 7.

  • Visual Studio 2005.

Замечание

Вы также можете использовать Visual Studio .NET 2003 или более ранних версий, хотя пошаговое руководство может не совпадать.

Создание модуля

В этой части пошагового руководства вы создадите пустой проект DLL C++ для модуля HTTP.

Создание проекта библиотеки DLL C++

  1. Запустите Visual Studio 2005.

  2. Убедитесь, что в глобальных параметрах указаны все правильные пути доступа к файлам включения SDK.

    1. В меню Сервис выберите пункт Параметры.

    2. Разверните узел "Проекты и решения " в представлении дерева и выберите каталоги VC++.

    3. В раскрывающемся списке " Показать каталоги" выберите "Включить файлы".

    4. Убедитесь, что путь, по которому вы установили SDK, перечислен и содержит необходимые файлы включения. Если путь не указан, щелкните значок "Новая строка" и добавьте путь к файлам include SDK, установленным вами.

    5. Нажмите кнопку ОК.

  3. Создайте проект C++ :

    1. В меню Файл выберите пункт Создать и затем пункт Проект.

      Откроется диалоговое окно "Новый проект ".

    2. В области "Типы проектов " разверните узел Visual C++ и нажмите кнопку Win32.

    3. В области "Шаблоны " выберите "Проект Win32".

    4. В поле "Имя" введите HelloWorld.

    5. В поле "Расположение " введите путь для примера.

    6. Нажмите кнопку ОК.

      Откроется мастер приложений Win32 .

    7. Щелкните "Параметры приложения".

    8. В разделе "Тип приложения" щелкните DLL.

    9. В разделе "Дополнительные параметры" нажмите кнопку "Пустой проект".

    10. Нажмите кнопку "Готово".

Добавление кода и исходных файлов

Следующим шагом является добавление необходимых файлов определения C++ и модулей в проект.

Добавление исходных файлов в проект

  1. Создайте файл определения модуля для экспорта функции RegisterModule :

    1. В обозревателе решений щелкните правой кнопкой мыши исходные файлы, наведите указатель мыши на добавление и нажмите кнопку "Создать элемент".

      Откроется диалоговое окно "Добавить новый элемент ".

    2. Разверните узел Visual C++ в области категорий и нажмите кнопку "Код".

    3. В области шаблонов выберите шаблон файла Module-Definition.

    4. В поле "Имя" введите HelloWorld и оставьте путь по умолчанию для файла в поле "Расположение ".

    5. Нажмите кнопку Добавить.

    6. Добавьте следующий код:

      LIBRARY HelloWorld  
      
      EXPORTS  
          RegisterModule  
      
  2. При необходимости можно экспортировать функцию RegisterModule с помощью переключателя /EXPORT: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 не вернул никаких ошибок или предупреждений. При возникновении ошибок или предупреждений необходимо устранить эти проблемы перед тестированием проекта.

  2. Скопируйте DLL-файл модуля HTTP в папку IIS:

    1. Откройте проводник Windows и найдите папку по умолчанию, указанную при создании проекта C++.

      В зависимости от параметров сборки вы увидите папку с именем Debug или Release в папке по умолчанию для проекта.

    2. В папке отладки или выпуска найдите файл с именем HelloWorld.dll.

    3. Скопируйте файл HelloWorld.dll в папку Inetsrv, расположенную по умолчанию в %WinDir%\System32\Inetsrv.

  3. Добавьте модуль HelloWorld.dll в список модулей (инструкции см. в разделе "Проектирование Native-Code http modules").

  4. Перейдите на веб-сайт с помощью Internet Explorer; Вы должны увидеть обычное содержимое веб-сайта.

  5. Откройте средство просмотра событий Windows и перейдите в глобальный журнал приложений; Вы увидите запись, которая выводит список IISADMIN в качестве источника событий.

  6. Щелкните событие правой кнопкой мыши и выберите пункт "Свойства ", чтобы просмотреть сведения о событии. В области описания появится сообщение "Hello World!".

Устранение неполадок с настройками

Если модуль не компилируется или не работает должным образом, вот несколько областей, которые можно проверить:

  • Убедитесь, что вы указали __stdcall для экспортированных функций или настроили компиляцию с помощью соглашения о вызовах __stdcall (/Gz) .

  • Убедитесь, что вы добавили правильный RegisterModule экспорт в файл определения.

  • Убедитесь, что вы добавили файл определения в параметры проекта. Чтобы добавить файл в параметры проекта, выполните следующие действия.

    1. В меню проекта щелкните Свойства.

    2. Разверните узел свойств конфигурации в представлении дерева, разверните узел компоновщика и нажмите кнопку "Входные данные".

    3. Для параметров файла определения модуля убедитесь, что ваш файл определения перечислен.

См. также