Tutorial: Creación de un módulo HTTP de Global-Level mediante código nativo
En este tutorial se muestra cómo usar C++ para crear un módulo HTTP de nivel global de ejemplo que implementa la nueva arquitectura de procesamiento de solicitudes en IIS 7. Esta nueva arquitectura amplía las funcionalidades de programación de código nativo cuando se escriben aplicaciones IIS en versiones anteriores de ASP.NET módulos HTTP e extensiones de ISAPI. Para obtener más información sobre cómo diseñar módulos HTTP mediante la nueva arquitectura de procesamiento de solicitudes, consulte Diseño de Native-Code módulos HTTP.
En este tutorial, creará un proyecto de C++ para el módulo HTTP, agregará el código necesario para un proyecto de "Hola mundo" y, a continuación, compilará y probará el módulo.
Prerrequisitos
El software siguiente es necesario para completar los pasos del ejemplo:
IIS 7.
Visual Studio 2005.
Nota
También puede usar Visual Studio .NET 2003 o versiones anteriores, aunque es posible que los pasos del tutorial no sean idénticos.
Creación del módulo
En esta parte del tutorial, creará un proyecto DLL de C++ vacío para el módulo HTTP.
Para crear un nuevo proyecto DLL de C++
Inicie Visual Studio 2005.
Compruebe que las opciones globales tienen todas las rutas de acceso correctas al SDK incluyen archivos:
En el menú Herramientas , haga clic en Opciones.
Expanda el nodo Proyectos y soluciones en la vista de árbol y, a continuación, haga clic en Directorios de VC++.
En el cuadro desplegable Mostrar directorios para , seleccione Incluir archivos.
Compruebe que aparece la ruta de acceso donde instaló los archivos de inclusión del SDK. Si la ruta de acceso no aparece, haga clic en el icono Nueva línea y agregue la ruta de acceso donde instaló los archivos de inclusión del SDK.
Haga clic en OK.
Cree un nuevo proyecto de C++:
En el menú Archivo , elija Nuevoy haga clic en Proyecto.
Aparece el cuadro de diálogo Nuevo proyecto .
En el panel Tipos de proyecto , expanda el nodo Visual C++ y, a continuación, haga clic en Win32.
En el panel Plantillas , seleccione Proyecto Win32.
En el cuadro Nombre , escriba HelloWorld.
En el cuadro Ubicación , escriba la ruta de acceso del ejemplo.
Haga clic en OK.
Se abre el Asistente para aplicaciones Win32 .
Haga clic en Configuración de la aplicación.
En Tipo de aplicación, haga clic en DLL.
En Opciones adicionales, haga clic en Proyecto vacío.
Haga clic en Finalizar
Agregar el código y los archivos de código fuente
El siguiente paso consiste en agregar los archivos de definición de módulo y C++ necesarios al proyecto.
Para agregar los archivos de origen al proyecto
Cree el archivo module-definition para exportar la función RegisterModule :
En Explorador de soluciones, haga clic con el botón derecho en Archivos de origen, seleccione Agregary, a continuación, haga clic en Nuevo elemento.
Se abrirá el cuadro de diálogo Agregar nuevo elemento.
Expanda el nodo Visual C++ en el panel Categorías y, a continuación, haga clic en Código.
En el panel Plantillas , seleccione la plantilla Archivo de definición de módulo .
En el cuadro Nombre , escriba HelloWorld y deje la ruta de acceso predeterminada para el archivo en el cuadro Ubicación .
Haga clic en Agregar.
Agregue el siguiente código:
LIBRARY HelloWorld EXPORTS RegisterModule
Opcionalmente, puede exportar la función RegisterModule mediante el modificador /EXPORT:RegisterModule :
En el menú Proyecto , haga clic en Propiedades helloWorld.
Expanda el nodo Propiedades de configuración en la vista de árbol, expanda el nodo Enlazador y, a continuación, haga clic en Línea de comandos.
En el cuadro desplegable Configuración , seleccione Todas las configuraciones.
En el cuadro Opciones adicionales , escriba /EXPORT:RegisterModule.
Haga clic en OK.
Cree el archivo de C++:
En Explorador de soluciones, haga clic con el botón derecho en Archivos de origen, seleccione Agregary, a continuación, haga clic en Nuevo elemento.
Se abrirá el cuadro de diálogo Agregar nuevo elemento.
Expanda el nodo Visual C++ en el panel Categorías y, a continuación, haga clic en Código.
En el panel Plantillas , seleccione la plantilla Archivo de C++ .
En el cuadro Nombre , escriba HelloWorld y deje la ruta de acceso predeterminada para el archivo en el cuadro Ubicación .
Haga clic en Agregar.
Agregue el siguiente código:
#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 ); }
Opcionalmente, puede compilar el código mediante la
__stdcall (/Gz)
convención de llamada:En el menú Proyecto , haga clic en Propiedades helloWorld.
Expanda el nodo Propiedades de configuración en la vista de árbol, expanda el nodo C/C++ y, a continuación, haga clic en Avanzado.
En el cuadro desplegable Configuración , seleccione Todas las configuraciones.
En el cuadro desplegable Convención de llamada, seleccione __stdcall (/Gz).
Haga clic en OK.
Compilación y prueba del módulo
El módulo HTTP tiene todo lo que necesita. Todo lo necesario es compilar y probar el módulo HTTP.
Para compilar y probar el proyecto
Compile el módulo HTTP:
En el menú Compilar , haga clic en Compilar solución.
Compruebe que Visual Studio no devolvió errores ni advertencias. Si encuentra errores o advertencias, deberá resolver esos problemas antes de probar el proyecto.
Copie el archivo DLL del módulo HTTP en la carpeta IIS:
Abra el Explorador de Windows y busque la carpeta predeterminada que se especificó al crear el proyecto de C++.
En función de las opciones de compilación, debería ver una carpeta denominada Depurar o Liberar en la carpeta predeterminada del proyecto.
Dentro de la carpeta Depurar o Liberar, busque el archivo denominado HelloWorld.dll.
Copie el archivo HelloWorld.dll en la carpeta Inetsrv, que se encuentra de forma predeterminada en %WinDir%\System32\Inetsrv.
Agregue el módulo HelloWorld.dll a la lista de módulos (para obtener instrucciones, consulte Diseño Native-Code módulos HTTP).
Use Internet Explorer para ir a su sitio web; debería ver el contenido normal del sitio web.
Abra el Visor de eventos de Windows y cambie al registro de aplicaciones global; debería ver una entrada que muestra "IISADMIN" como origen del evento.
Haga clic con el botón derecho en el evento y, a continuación, haga clic en Propiedades para ver los detalles del evento. Debería ver un mensaje "Hola mundo!" que se muestra en el panel Descripción.
Solución de problemas de la configuración
Si el módulo no compila o no funciona según lo previsto, estas son varias áreas que puede comprobar:
Asegúrese de que ha especificado
__stdcall
para las funciones exportadas o que ha configurado la compilación mediante la__stdcall (/Gz)
convención de llamada.Asegúrese de que ha agregado la exportación correcta
RegisterModule
al archivo de definición.Asegúrese de que ha agregado el archivo de definición a la configuración del proyecto. Para agregar el archivo a la configuración del proyecto, complete los pasos siguientes:
En el menú Proyecto , haga clic en Propiedades.
Expanda el nodo Propiedades de configuración en la vista de árbol, expanda el nodo Enlazador y, a continuación, haga clic en Entrada.
Para la configuración del archivo de definición de módulo , asegúrese de que aparece el archivo de definición.