Freigeben über


Exemplarische Vorgehensweise: Erstellen eines Request-Level HTTP-Moduls mithilfe von systemeigenem Code

In dieser exemplarischen Vorgehensweise wird veranschaulicht, wie Sie mit C++ ein HTTP-Beispielmodul auf Anforderungsebene erstellen, das die neue Anforderungsverarbeitungsarchitektur in IIS 7 implementiert. Diese neue Architektur erweitert die Funktionen der systemeigenen Codeprogrammierung, wenn Sie IIS-Anwendungen über frühere Versionen von ASP.NET HTTP-Module und ISAPI-Filter oder Erweiterungen schreiben. Weitere Informationen zum Entwerfen von HTTP-Modulen mithilfe der neuen Anforderungsverarbeitungsarchitektur finden Sie unter Entwerfen Native-Code HTTP-Module.

In dieser exemplarischen Vorgehensweise erstellen Sie ein C++-Projekt für Ihr HTTP-Modul, fügen den erforderlichen Code für ein "Hello World"-Projekt hinzu und kompilieren und testen dann das Modul.

Voraussetzungen

Die folgende Software ist erforderlich, um die Schritte im Beispiel auszuführen:

  • IIS 7.

  • Visual Studio 2005.

  • Windows Software Development Kit (SDK).

    Hinweis Sie können Visual Studio .NET 2003 oder früher verwenden, obwohl die exemplarischen Schritte möglicherweise nicht identisch sind.

Erstellen des Moduls

In diesem Teil der exemplarischen Vorgehensweise erstellen Sie ein leeres C++-DLL-Projekt für Ihr HTTP-Modul.

So erstellen Sie ein neues C++-DLL-Projekt

  1. Öffnen Sie Visual Studio 2005.

  2. Stellen Sie sicher, dass die globalen Optionen die korrekten Pfade zu den SDK-Headerdateien enthalten.

    1. Klicken Sie im Menü Extras auf Optionen.

    2. Erweitern Sie den Knoten Projekte und Lösungen in der Strukturansicht, und klicken Sie dann auf VC++-Verzeichnisse.

    3. Wählen Sie im Dropdownfeld "Verzeichnisse anzeigen " die Option "Dateien einschließen" aus.

    4. Stellen Sie sicher, dass der Pfad, in dem Sie das Windows SDK installiert haben, mit den Include-Dateien aufgeführt ist. Wenn der Pfad nicht aufgeführt ist, klicken Sie auf das Symbol Neue Zeile und fügen Sie dann den Pfad hinzu, in dem Sie die SDK-Include-Dateien installiert haben. Das Standardinstallationsverzeichnis ist $(VCInstallDir)PlatformSDK\bin.

    5. Klicke auf OK.

  3. Erstellen eines neuen C++-Projekts:

    1. Zeigen Sie im Menü Datei auf Neu, und klicken Sie dann auf Projekt.

      Das Dialogfeld "Neues Projekt " wird geöffnet.

    2. Erweitern Sie im Bereich "Projekttypen " den Visual C++ -Knoten, und klicken Sie dann auf Win32.

    3. Wählen Sie im Bereich "Vorlagen " "Win32-Projekt" aus.

    4. Geben Sie im Feld "Name " "HelloWorld" ein.

    5. Geben Sie im Feld "Speicherort " den Pfad für das Beispiel ein.

    6. Klicke auf OK.

      Der Win32-Anwendungs-Assistent wird geöffnet.

    7. Klicken Sie auf "Anwendungseinstellungen".

    8. Klicken Sie unter "Anwendungstyp" auf "DLL".

    9. Klicken Sie unter "Weitere Optionen" auf "Projekt leeren".

    10. Klicken Sie auf Fertig stellen.

Hinzufügen von Code- und Quelldateien

Der nächste Schritt besteht darin, dem Projekt die erforderlichen C++- und Moduldefinitionsdateien hinzuzufügen.

So fügen Sie dem Projekt die Quelldateien hinzu

  1. Erstellen Sie die Moduldefinitionsdatei zum Exportieren der RegisterModule-Funktion :

    1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf "Quelldateien", zeigen Sie auf "Hinzufügen", und klicken Sie dann auf "Neues Element".

      Das Dialogfeld " Neues Element hinzufügen " wird geöffnet.

    2. Erweitern Sie den Visual C++ -Knoten im Bereich "Kategorien ", und klicken Sie dann auf "Code".

    3. Wählen Sie im Bereich „Vorlagen“ die Vorlage Moduldefinitionsdatei aus.

    4. Geben Sie im Name-Feld HelloWorld ein und lassen Sie den Standardpfad für die Datei im Speicherort-Feld unverändert.

    5. Klicken Sie auf Hinzufügen.

    6. Fügen Sie eine Zeile mit EXPORTS und RegisterModule. Ihre Datei sollte wie der folgende Code aussehen:

      LIBRARY"HelloWorld"  
      EXPORTS  
          RegisterModule  
      

      Hinweis

      Anstatt eine Moduldefinitionsdatei zu erstellen, können Sie die RegisterModule-Funktion mithilfe der Option "/EXPORT:RegisterModule " exportieren.

  2. Erstellen Sie die C++-Datei:

    1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf "Quelldateien", zeigen Sie auf "Hinzufügen", und klicken Sie dann auf "Neues Element".

      Das Dialogfeld " Neues Element hinzufügen " wird geöffnet.

    2. Erweitern Sie den Visual C++ -Knoten im Bereich "Kategorien ", und klicken Sie dann auf "Code".

    3. Wählen Sie im Vorlagenbereich die C++-Dateivorlage aus.

    4. Geben Sie im Feld "Name"HelloWorld ein, und lassen Sie den Standardpfad für die Datei im Feld "Speicherort" stehen.

    5. Klicken Sie auf Hinzufügen.

    6. Fügen Sie den folgenden Code hinzu:

      #define _WINSOCKAPI_
      #include <windows.h>
      #include <sal.h>
      #include <httpserv.h>
      
      // Create the module class.
      class CHelloWorld : public CHttpModule
      {
      public:
          REQUEST_NOTIFICATION_STATUS
          OnBeginRequest(
              IN IHttpContext * pHttpContext,
              IN IHttpEventProvider * pProvider
          )
          {
              UNREFERENCED_PARAMETER( pProvider );
      
              // Create an HRESULT to receive return values from methods.
              HRESULT hr;
              
              // Retrieve a pointer to the response.
              IHttpResponse * pHttpResponse = pHttpContext->GetResponse();
      
              // Test for an error.
              if (pHttpResponse != NULL)
              {
                  // Clear the existing response.
                  pHttpResponse->Clear();
                  // Set the MIME type to plain text.
                  pHttpResponse->SetHeader(
                      HttpHeaderContentType,"text/plain",
                      (USHORT)strlen("text/plain"),TRUE);
      
                  // Create a string with the response.
                  PCSTR pszBuffer = "Hello World!";
                  // Create a data chunk.
                  HTTP_DATA_CHUNK dataChunk;
                  // Set the chunk to a chunk in memory.
                  dataChunk.DataChunkType = HttpDataChunkFromMemory;
                  // Buffer for bytes written of data chunk.
                  DWORD cbSent;
                  
                  // Set the chunk to the buffer.
                  dataChunk.FromMemory.pBuffer =
                      (PVOID) pszBuffer;
                  // Set the chunk size to the buffer size.
                  dataChunk.FromMemory.BufferLength =
                      (USHORT) strlen(pszBuffer);
                  // Insert the data chunk into the response.
                  hr = pHttpResponse->WriteEntityChunks(
                      &dataChunk,1,FALSE,TRUE,&cbSent);
      
                  // Test for an error.
                  if (FAILED(hr))
                  {
                      // Set the HTTP status.
                      pHttpResponse->SetStatus(500,"Server Error",0,hr);
                  }
      
                  // End additional processing.
                  return RQ_NOTIFICATION_FINISH_REQUEST;
              }
      
              // Return processing to the pipeline.
              return RQ_NOTIFICATION_CONTINUE;
          }
      };
      
      // Create the module's class factory.
      class CHelloWorldFactory : public IHttpModuleFactory
      {
      public:
          HRESULT
          GetHttpModule(
              OUT CHttpModule ** ppModule, 
              IN IModuleAllocator * pAllocator
          )
          {
              UNREFERENCED_PARAMETER( pAllocator );
      
              // Create a new instance.
              CHelloWorld * pModule = new CHelloWorld;
      
              // Test for an error.
              if (!pModule)
              {
                  // Return an error if the factory cannot create the instance.
                  return HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY );
              }
              else
              {
                  // Return a pointer to the module.
                  *ppModule = pModule;
                  pModule = NULL;
                  // Return a success status.
                  return S_OK;
              }            
          }
      
          void
          Terminate()
          {
              // Remove the class from memory.
              delete this;
          }
      };
      
      // Create the module's exported registration function.
      HRESULT
      __stdcall
      RegisterModule(
          DWORD dwServerVersion,
          IHttpModuleRegistrationInfo * pModuleInfo,
          IHttpServer * pGlobalInfo
      )
      {
          UNREFERENCED_PARAMETER( dwServerVersion );
          UNREFERENCED_PARAMETER( pGlobalInfo );
      
          // Set the request notifications and exit.
          return pModuleInfo->SetRequestNotifications(
              new CHelloWorldFactory,
              RQ_BEGIN_REQUEST,
              0
          );
      }
      

Kompilieren und Testen des Moduls

So kompilieren und testen Sie das Projekt

  1. Kompilieren des HTTP-Moduls:

    1. Klicken Sie im Menü "Erstellen" auf "Lösung erstellen".

    2. Stellen Sie sicher, dass Visual Studio keine Fehler oder Warnungen zurückgegeben hat.

    3. Fügen Sie das Modul HelloWorld.dll (mit dem vollständigen Pfad) zum globalModules-Abschnitt der Datei %windir%\system32\inetsrv\config\applicationHost.config hinzu.

  2. Verwenden Sie Internet Explorer, um zu Ihrer Website zu navigieren; Sie sollten "Anfrage beginnen" sehen, wobei die Anzahl der Anfragen angezeigt wird.

Hinweis

Sie müssen IIS beenden, bevor Sie Ihr Projekt mit nachfolgenden Builds verknüpfen.

Problembehandlung für Ihre Einstellungen

Wenn Ihr Modul nicht wie erwartet kompiliert wird oder nicht funktioniert, finden Sie hier mehrere Bereiche, die Sie überprüfen können:

  • Stellen Sie sicher, dass Sie __stdcall für Ihre exportierten Funktionen angegeben haben oder dass Sie die Kompilierung mithilfe der __stdcall (/Gz) Aufrufkonvention konfiguriert haben.

  • Stellen Sie sicher, dass IIS HelloWorld.dllgeladen hat:

    1. Klicken Sie im IIS-Manager im Bereich "Verbindungen" auf "Standardwebsite".

    2. Wählen Sie im Arbeitsbereich (mittlerer Bereich) die Option "Featureansicht" aus.

    3. Wählen Sie im Feld "Gruppieren nach " die Option "Kategorie" aus.

    4. Doppelklicken Sie in der Kategorie "Serverkomponenten" auf "Module".

    5. Stellen Sie sicher, dass das HelloWorld-Modul aufgeführt ist.

  • Stellen Sie sicher, dass Sie der Definitionsdatei den richtigen RegisterModule Export hinzugefügt haben.

  • Stellen Sie sicher, dass Sie die Definitionsdatei den Projekteinstellungen hinzugefügt haben. Führen Sie die folgenden Schritte aus, um die Datei zu den Projekteinstellungen hinzuzufügen:

    1. Klicken Sie im Menü Projekt auf Eigenschaften.

    2. Erweitern Sie den Knoten "Konfigurationseigenschaften" in der Strukturansicht, erweitern Sie den Linker-Knoten , und klicken Sie dann auf "Eingabe".

    3. Stellen Sie für die Einstellungen für die Moduldefinitionsdatei sicher, dass Ihre Definitionsdatei aufgeführt ist.

Siehe auch

Erstellen von Native-Code-HTTP-Modulen
Entwerfen Native-Code HTTP-Module