Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Informacin General
En esta seccin
Resumen de la tecnologa para WMI .NET
Resume los conceptos sobre WMI .NET y el uso de clases en los espacios de nombres WMI .NET.
Arquitectura de WMI .NET
Traza un diagrama de la arquitectura de la API de WMI .NET e ilustra cmo interactan las aplicaciones
creadas con la API con proveedores y clases WMI.
Escenarios con WMI .NET
Describe los escenarios ms habituales para la implementacin de clases WMI .NET.
Directorio de cdigo de WMI .NET
Proporciona vnculos a ejemplos de cdigo para diversas tareas con los espacios de nombres
System.Management y System.Management.Instrumentation. Estos ejemplos se clasifican por tipo de
tarea.
Referencia
Espacio de nombres System.Management
Proporciona documentacin de referencia para el espacio de nombres System.Management, que contiene
clases que se utilizan para el acceso y la manipulacin de informacin de administracin de WMI.
Espacio de nombres System.Management.Instrumentation
Proporciona documentacin de referencia para el espacio de nombres System.Management.
Instrumentation, que contiene clases que se utilizan para crear proveedores de eventos y datos.
Secciones relacionadas
Ms informacin sobre WMI .NET
Proporciona una descripcin general de WMI en .NET Framework y cmo funciona con el WMI original.
Introduccin al acceso a datos WMI
Describe qu se necesita para empezar a utilizar WMI en .NET Framework.
Temas de programacin avanzada en WMI .NET
Proporciona vnculos a temas que contienen ejemplos de operaciones avanzadas relacionadas con WMI en
.NET Framework.
Proporcionar informacin de administracin mediante instrumentacin de aplicaciones
Explica para qu se utiliza un proveedor WMI y cmo puede usarse WMI en .NET Framework para crear un
proveedor WMI.
Palabras clave
Calificador, proveedor, lenguaje de consulta WMI, consumidor de eventos, modelo de informacin comn, asincrnico,
semisincrnico, esquema Win32, aplicacin de administracin
Espacios de nombres
System.Management, System.Management.Instrumentation
Tecnologas relacionadas
Instrumental de administracin de Windows (WMI)
WMI en .NET Framework se basa en la tecnologa WMI original.
Informacin previa
La versin no administrada de WMI es la implementacin de Microsoft de WBEM (Web-Based Enterprise Management),
una iniciativa del sector desarrollada para normalizar la tecnologa de administracin de entornos informticos
empresariales. WMI utiliza clases basadas en el estndar del sector CIM (modelo de informacin comn) para
representar sistemas, procesos, redes, dispositivos y otros componentes empresariales.
WMI suministra un esquema de clases preinstalado que permite a secuencias de comandos o aplicaciones programadas
con lenguajes de secuencias de comandos, Visual Basic o C++, supervisar y configurar aplicaciones, componentes de
sistema o de red y hardware de una organizacin. Por ejemplo, las instancias de la clase Win32_Process representan
todos los procesos de un equipo y la clase Win32_LogicalDisk puede representar los dispositivos de disco.
La arquitectura de WMI consta de los niveles siguientes:
Los componentes de software cliente realizan operaciones mediante WMI, como leer detalles de
administracin, configurar sistemas y realizar suscripciones a eventos.
El administrador de objetos es un intermediario entre los proveedores y los clientes que proporciona ciertos
servicios esenciales, como la publicacin y suscripcin estndar de eventos, el filtrado de eventos, motor de
consultas y otros servicios.
Los componentes de software de proveedor capturan y devuelven datos activos a las aplicaciones cliente,
procesan llamadas a mtodos procedentes de los clientes y vinculan al cliente con la infraestructura que se
est administrando.
Elementos de arquitectura
En la siguiente ilustracin se identifican los tres niveles de WMI, as como el modo en que el espacio de nombres
System.Management se distribuye en capas en WMI:
Niveles de WMI
Los clientes que obtienen acceso a los datos a travs de WMI pueden ser:
Formularios Windows Forms
Formularios Web Forms/ASP.NET
Aplicaciones de administracin, como Management Operations Manager (MOM), Systems Management
Server (SMS) o HP OpenView.
Los proveedores de datos de administracin pueden ser:
Proveedores de WMI original que exponen datos de sistema o de aplicacin, como el proveedor
Win32_Provider o el proveedor de Registro del sistema.
Aplicaciones de Windows Forms y de marco de pginas Web Forms/ASP.NET que exponen su instrumental de
administracin a otros clientes, como SMS.
Ms informacin
En los siguientes temas se proporciona ms informacin sobre las distintas reas de WMI .NET:
Ventajas de WMI en .NET Framework
Describe las ventajas derivadas de utilizar WMI .NET en lugar de WMI original.
Limitaciones de WMI en .NET Framework
Explica las limitaciones de WMI .NET en comparacin con las que supone el uso de WMI original.
Seguridad de WMI en .NET Framework
Proporciona una descripcin general de la seguridad de WMI .NET para obtener acceso y proporcionar datos
de un modo seguro.
Esquema de WMI y .NET Framework
Explica en qu consiste WMI y cmo se incorpora en .NET Framework. En este tema se describen de forma
detallada los componentes de WMI.
Introduccin al acceso a datos WMI
Proporciona un punto de partida para crear aplicaciones WMI en .NET Framework.
Temas de programacin avanzada en WMI .NET
Proporciona vnculos a temas que contienen ejemplos de operaciones avanzadas para WMI en .NET
Framework.
Proporcionar informacin de administracin mediante instrumentacin de aplicaciones
Explica para qu se utiliza un proveedor WMI y cmo puede usarse WMI en .NET Framework para crear un
proveedor WMI.
Definicin de clases y publicacin de instancias ntegramente con clases .NET Framework para instrumentar
aplicaciones con objeto de que las aplicaciones puedan proporcionar datos a WMI.
Las clases de System.Management.Instrumentation le permiten registrar un nuevo proveedor, crear clases
nuevas y publicar instancias sin utilizar el cdigoMOF (Managed Object Format).
Simplicidad de uso.
En ocasiones, resulta difcil o muy laborioso desarrollar aplicaciones C++ para WMI original. La estructura de
clases de System.Management aporta una mayor simplicidad, comparable a las secuencias de comandos, a las
aplicaciones desarrolladas en .NET Framework. El desarrollo de aplicaciones y proveedores puede realizarse
con mayor rapidez con una depuracin ms sencilla.
Acceso a todos los datos WMI.
Las aplicaciones cliente tienen el mismo tipo de acceso a datos WMI y pueden realizar las mismas operaciones
con stos que en WMI original. Las aplicaciones instrumentadas por proveedor presentan ms restricciones.
Nota
En esta cadena, "(A;;0x1;;;PU)" (al final de la cadena) es la nueva cadena ACE para permitir a los miembros del grupo
Usuarios avanzados que proporcionen instrumental. WMI requiere el bit menos significativo establecido (es decir, 0x1)
para el valor de derechos de usuario en una cadena ACE.
Espacios de nombres
El trmino "espacio de nombres" se utiliza tanto en el contexto de WMI como de .NET Framework, si bien hace
referencia a entidades diferentes. Un espacio de nombres WMI es una subdivisin del repositorio WMI, tambin
conocido como repositorio CIM. El espacio de nombres WMI ms frecuente es root\cimv2, donde se almacena el
enorme conjunto de clases Win32. En esta documentacin se hace referencia a estos espacios de nombres como
espacios de nombres WMI.
Un espacio de nombres de .NET Framework es el mecanismo que permite limitar el mbito de un nombre de clase de
manera que su definicin queda circunscrita a un espacio especfico. System.Management y System.Management.
Instrumentation son espacios de nombres dentro de la Biblioteca de clases .NET Framework. En esta documentacin se
hace referencia a estos espacios de nombres como espacios de nombres .NET Framework.
Esquema WMI
WMI utiliza el concepto orientado a objetos de una clase para modelar una empresa. Las instancias de las clases WMI
preinstaladas, como Win32_Process oWin32_Processor, representan entidades de una red, un sistema informtico o un
sistema operativo. Varios proveedores integrados definen y suministran datos activos para las clases con nombres que
empiezan por "Win32_". Un subconjunto de las clases Win32, las clases Win32_PerfRawData y las clases
Win32_PerfFormattedData, proporcionan los mismos datos de rendimiento activos que la herramienta Monitor de
sistema. El proveedor de contadores de rendimiento y el proveedor de contador suministran datos a las instancias de
estas clases. El proveedor de volmenes de almacenamiento suministra otro subconjunto de clases WMI, del
que Win32_Volume constituye un ejemplo. Otros proveedores integrados, como el proveedor de directivas, suministran
clases preinstaladas con otros nombres, como MSFT_Providers.
Las clases incluyen propiedades que describen datos y mtodos para describir y controlar el comportamiento de una
aplicacin o de un dispositivo. Otros programadores pueden crear sus propios esquemas para describir entornos
especficos de su organizacin. Debido a que los esquemas estn diseados de manera que se puedan extender
infinitamente, siempre es posible agregar clases nuevas para representar nuevos objetos administrados en un entorno
existente.
La herencia es una herramienta muy eficaz en el esquema WMI. No es necesario que cree clases desde cero, ya que a
menudo se pueden derivar a partir de clases CIM o WMI existentes.
Al exponer informacin a travs de WMI, es esencial disponer de una buena estructura de clases que permita a las
herramientas administrar la aplicacin. La estructuracin de la informacin en un esquema es una caracterstica esencial
de un sistema de administracin distribuido: permite definir operaciones que se pueden procesar con total confianza en
toda una serie de sistemas que admitan el esquema.
El esquema WMI es autodescriptivo. Es decir, puede describir mediante programacin qu propiedades y mtodos
proporciona una clase.
WMI le permite definir asociaciones, o vinculaciones, entre clases. Estas asociaciones pueden representar relaciones
entre instancias especficas de las clases vinculadas. Las aplicaciones de administracin pueden recorrer esas relaciones
de asociacin a travs de mtodos y consultas como RelatedObjectQuery o RelationshipQuery. Los programadores de
terceros tambin pueden definir clases de asociacin para su entorno de administracin.
Tema Description
Cmo configurar el entorno de Cmo configurar un proyecto de Visual Studio para el desarrollo
desarrollo para utilizar WMI de System.Management.
.NET
Consultas WMI Cmo utilizar los mtodos de la clase ManagementClass para enumerar u
obtener una coleccin de objetos WMI y cmo utilizar la
clase ManagementObjectSearcher para consultar una coleccin de objetos
que cumplan criterios especificados.
Cmo recuperar informacin Cmo utilizar clases de consulta para obtener subconjuntos especificados
acerca de objetos administrados de objetos WMI.
mediante consultas
Compilar el cdigo
Sugerencia No es necesario agregar al cdigo la instruccin del espacio de nombres using (instruccin Imports en VB
.NET), aunque puede simplificar los nombres de objeto. Si no agrega esta instruccin, deber declarar un objeto como
System.Management.ManagementObject en lugar de ManagementObject.
Ejemplo
En el ejemplo de cdigo siguiente se crea una aplicacin que permite al usuario explorar las clases WMI disponibles en
un espacio de nombres especificado.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Management;
using System.Data;
namespace SchemaBrowser
{
// This application browses WMI classes available in local namespace enter by users.
public class SchemaBrowerForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox namespaceValue;
private System.Windows.Forms.ListBox classList;
private System.Windows.Forms.Button searchButton;
// Number of namespaces or classes found
private int count;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label statusValue;
private System.ComponentModel.Container components = null;
public SchemaBrowerForm()
{
count = 0;
InitializeComponent();
}
this.label1.TabIndex = 1;
this.label1.Text = "Namespace:";
//
// statusValue
//
this.statusValue.BorderStyle = System.Windows.Forms.
BorderStyle.FixedSingle;
this.statusValue.Location = new System.Drawing.Point(56, 250);
this.statusValue.Name = "statusValue";
this.statusValue.Size = new System.Drawing.Size(224, 18);
this.statusValue.TabIndex = 6;
//
// label3
//
this.label3.Location = new System.Drawing.Point(16, 251);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(40, 18);
this.label3.TabIndex = 5;
this.label3.Text = "Status:";
//
// Form1
//
this.AcceptButton = this.searchButton;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(298, 279);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.statusValue, this.label3, this.label2, this.classList,
this.searchButton, this.label1, this.namespaceValue});
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Schema Browser";
this.ResumeLayout(false);
En el siguiente ejemplo de cdigo se enumeran todas las instancias de la clase WMI Win32_Service.
using System;
using System.Management;
class Sample
{
public static void Main()
{
ManagementClass c = new ManagementClass("Win32_Service");
foreach (ManagementObject o in c.GetInstances())
{
Console.WriteLine("Service Name = {0} ProcessId = {1} Instance Path = {2}",
o["Name"], o["ProcessId"], o.Path);
}
}
}
En el siguiente ejemplo de cdigo VBScript se enumeran todas las instancias de la clase WMI Win32_Service.
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Ejemplo
El cdigo siguiente ofrece un ejemplo de cmo invocar un mtodo WMI esttico. En el ejemplo se invoca el
mtodo Create de la clase Win32_Process con objetos de parmetro para iniciar Calc.exe. En el ejemplo tambin se
muestra cmo invocar el mtodo Create de la clase Win32_Process con una matriz de argumentos para iniciar
Notepad.exe. En este caso en concreto, el mtodo es esttico y se invoca en la propia clase; sin embargo, los mtodos se
invocarn normalmente en instancias.
using System;
using System.Management;
El cdigo siguiente ofrece un ejemplo de cmo invocar un mtodo WMI en una instancia de una clase WMI. En el
ejemplo se invoca el mtodo StartService de la clase Win32_Service en la instancia de la clase en la que la propiedad
Name es igual a 'PlugPlay' (el servicio Plug and Play).
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class CallWMIMethod
{
public static void Main()
{
try
{
ManagementObject classInstance = new ManagementObject("root\\CIMV2",
"Win32_Service.Name='PlugPlay'", null);
// no method [in] parameters to define
// Execute the method and obtain the return values.
ManagementBaseObject outParams = classInstance.InvokeMethod(
"StartService", null, null);
// List outParams
Console.WriteLine("Out parameters:");
Console.WriteLine("ReturnValue: " + outParams["ReturnValue"]);
}
catch(ManagementException err)
{
MessageBox.Show("An error occured while trying to execute" +
" the WMI method: " + err.Message);
}
}
}
}
Ejemplo
En el ejemplo de cdigo siguiente se muestra cmo realizar una suscripcin a eventos intrnsecos de WMI y recibirlos de
manera sincrnica. En el ejemplo se crea en sintaxis WQL una consulta de eventos, que se utiliza para inicializar un
objeto ManagementEventWatcher y, despus, se espera a que se entreguen los eventos que cumplan las condiciones
especificadas en el filtro.
En este ejemplo de cdigo, el cliente recibe una notificacin cuando se crea una instancia de Win32_Process porque la
clase de eventos es__InstanceCreationEvent. El cliente recibe eventos de forma sincrnica tras llamar al mtodo
System.Management.ManagementEventWatcher.WaitForNextEvent. Este ejemplo se puede probar mediante el
inicio de un proceso, como el Bloc de notas, mientras se ejecuta el cdigo de ejemplo.
using System;
using System.Management;
WMI en .NET Framework tiene una serie de clases de consulta en el esquema de Framework. Algunas realizan ciertos
tipos de consultas WQL, como las consultas WQL SELECT o las consultas WQL ASSOCIATORS OF.
En la siguiente tabla se muestran las clases de consulta que se pueden utilizar para crear consultas de los datos WMI.
Clase .NET
Description
Framework
EventQuery Consulta de evento WMI. Los objetos de esta clase o sus derivados se utilizan en el
constructor de la clase ManagementEventWatcherpara la suscripcin a eventos WMI.
Siempre que pueda, utilice un derivado ms especfico de esta clase, como la
clase WqlEventQuery.
RelatedObjectQuery Consulta WQL ASSOCIATORS OF que se puede utilizar tanto para consultas de
instancias como de esquema, en funcin de si solicita la clase o un subconjunto de
instancias. Se utiliza para especificar la consulta en el constructor de la
clase ManagementObjectSearcher con el fin de obtener todas las instancias de clases
relacionadas a travs de clases de asociacin.
RelationshipQuery Consulta WQL REFERENCES OF que se puede utilizar tanto para consultas de
instancias como de esquema, en funcin de si solicita la clase o un subconjunto de
instancias.
SelectQuery Consulta WQL SELECT que se puede utilizar tanto para consultas de instancias
como de esquema, en funcin de si solicita la clase o un subconjunto de instancias.
WqlEventQuery Consulta de evento WMI en formato WQL. Los objetos de esta clase o sus derivados
se utilizan en la clase ManagementEventWatcherpara la suscripcin a eventos
WMI.
WqlEventQuery Consulta WMI en formato WQL. Los objetos de esta clase o sus derivados se utilizan
para especificar una consulta en el constructor de la clase Management
ObjectSearcher. Para una mayor especificidad, utilice cuando sea posibles derivados
de esta clase ms concisos, como la clase SelectQuery.
En el siguiente diagrama se muestra la herencia de clases de consulta WMI en la biblioteca de clases .NET Framework.
WMI en .NET Framework tiene clases de consulta de eventos y de objetos.
return 0;
}
}
En este ejemplo de cdigo se utiliza la forma WQL original de una consulta SELECT.
using System;
using System.Management;
class Query_Select_FullString
{
public static int Main(string[] args)
{
WqlObjectQuery wqlQuery = new WqlObjectQuery("SELECT * FROM Win32_LogicalDisk");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(wqlQuery);
foreach (ManagementObject disk in searcher.Get())
{
Console.WriteLine(disk.ToString());
}
Console.ReadLine();
return 0;
}
}
Ejemplo
En el cdigo de ejemplo siguiente se utilizan las clases de la coleccin System.Management para enumerar las
variables de entorno de un equipo. En este ejemplo, algunos parmetros se pueden dejar con los valores
predeterminados porque la informacin se obtiene del equipo local. Asimismo, se devuelve una coleccin que incluye
todos los objetos de Win32_Environment, la clase de datos WMI que representa variables de entorno. Despus de
recuperar la coleccin, el cdigo la enumera mediante la instruccin foreach y muestra el nombre y el valor de cada
variable de la coleccin. Los programadores que estn familiarizados con la API Scripting para WMI notarn algunas
similitudes.
Ejemplo
En el ejemplo de cdigo siguiente se muestra cmo se puede realizar una consulta mediante la clase Management
ObjectSearcher. En este caso, la clase SelectQuery se usa para especificar una solicitud de variables de entorno bajo el
nombre de usuario System. La consulta devuelve resultados en una coleccin.
using System;
using System.Management;
Tema Descripcin
Cmo conectarse a un equipo Las conexiones remotas para WMI en .NET Framework se realizan a
remoto travs del objeto ManagementScope.
Cmo llamar a un mtodo de Una aplicacin cliente puede llamar a un mtodo de forma asincrnica y
forma asincrnica realizar otras operaciones mientras se ejecuta el mtodo.
Cmo recibir eventos de Una aplicacin cliente puede configurar una suscripcin asincrnica y
administracin sin esperar realizar otras operaciones mientras espera eventos.
Cmo recibir informacin de Las operaciones de administracin pueden realizarse de forma asincrnica.
administracin sin esperar
Cmo utilizar objetos con WMI permite generar automticamente contenedores enlazados en tiempo
establecimiento inflexible de de compilacin para objetos WMI.
tipos
otras tareas mientras se llama y ejecuta el mtodo. Si llama al mtodo de forma semi sincrnica, debe esperar a que el
mtodo termine la ejecucin antes de iniciar otras tareas.
Ejemplo
El cdigo siguiente llama a un mtodo de forma asincrnica. Se llama al mtodo Win32_Process.Create para crear un
nuevo proceso de Calc.exe.
using System;
using System.Management;
// Delegate called when the method completes and results are available
private void NewObject(object sender, ObjectReadyEventArgs e)
{
Console.WriteLine("New Object arrived!");
returnObject = e.NewObject;
}
Adems, cuando conecte remotamente, podr especificar credenciales para cualquier otro usuario que no sea el que ha
iniciado la sesin en curso y las operaciones en el equipo remoto se realizarn en el contexto del usuario especificado.
Para ello, se puede emplear un objeto ConnectionOptions.
Ejemplo
En el siguiente ejemplo de cdigo se establece una conexin con un equipo remoto del mismo dominio que el del
usuario y se muestra informacin acerca del sistema operativo del equipo remoto. El usuario debe ser administrador en
el equipo remoto para que pueda establecerse la conexin.
using System;
using System.Management;
public class RemoteConnect
{
public static void Main()
{
/*// Build an options object for the remote connection
// if you plan to connect to the remote
// computer with a different user name
// and password than the one you are currently using
ConnectionOptions options = new ConnectionOptions();
// and then set the options.Username and
// options.Password properties to the correct values
// and also set
// options.Authority = "ntdlmdomain:DOMAIN";
// and replace DOMAIN with the remote computer's
// domain. You can also use kerberose instead
// of ntdlmdomain.
*/
// Make a connection to a remote computer.
// Replace the "FullComputerName" section of the
// string "\\\\FullComputerName\\root\\cimv2" with
// the full computer name or IP address of the
// remote computer.
ManagementScope scope = new ManagementScope(
"\\\\FullComputerName\\root\\cimv2");
scope.Connect();
// Use this code if you are connecting with a
// different user name and password:
//
// ManagementScope scope = new ManagementScope(
// "\\\\FullComputerName\\root\\cimv2", options);
// scope.Connect();
//Query system for Operating System information
ObjectQuery query = new ObjectQuery(
"SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher searcher =
new ManagementObjectSearcher(scope,query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach ( ManagementObject m in queryCollection)
{
// Display the remote computer information
Console.WriteLine("Computer Name : {0}", m["csname"]);
Console.WriteLine("Windows Directory : {0}",
m["WindowsDirectory"]);
Console.WriteLine("Operating System: {0}", m["Caption"]);
Console.WriteLine("Version: {0}", m["Version"]);
Console.WriteLine("Manufacturer : {0}", m["Manufacturer"]);
}
}
}
El objeto ConnectionOptions controla tambin los niveles de suplantacin y autenticacin utilizados por WMI en las
operaciones remotas con DCOM. Las configuraciones predeterminadas de estos parmetros son Impersonate y
Unchanged, respectivamente.
El valor Unchanged significa que el cliente toma de forma predeterminada los requisitos de autenticacin del servidor,
utilizando el proceso estndar de negociacin DCOM. En Windows 2000, Windows NT 4.0 y Windows 98, el servicio WMI
requerir autenticacin de nivel de conexin, mientras que en Windows XP Home Edition, Windows XP Professional,
Windows Server 2003 y Windows Server 2003 ser necesaria la autenticacin del nivel de paquete. Si el cliente requiere
una configuracin de autenticacin especfica, la propiedad de autenticacin en el objeto ConnectionOptions se puede
utilizar para controlar el nivel de autenticacin en esta conexin concreta.
El valor Impersonate significa que el cliente permite al proveedor de datos de WMI que suplante su identidad cuando
rena la informacin requerida. Esta configuracin predeterminada es ventajosa cuando el proveedor es una aplicacin
o servicio de confianza, porque elimina la necesidad de que el proveedor realice comprobaciones explcitas de identidad
y de acceso al obtener informacin para este cliente. Sin embargo, si por cualquier motivo el proveedor de destino o la
aplicacin instrumentada no son de confianza, la suplantacin del cliente puede constituir una amenaza para la
seguridad. En tales casos, es recomendable que la aplicacin cliente cambie el nivel de suplantacin a un nivel inferior,
como Identify. Tenga en cuenta que esto puede llevar a impedir que ciertos proveedores tengan acceso a la
informacin, en casos en los que el proveedor no realiza comprobaciones de acceso o no tiene suficientes permisos en
su propio contexto de ejecucin para obtener la informacin requerida.
En siguiente ejemplo de cdigo se establece una conexin con un equipo remoto y se muestra informacin acerca del
sistema operativo del equipo remoto. El cdigo tambin crea un formulario con el fin de recopilar la informacin de
nombre de usuario y contrasea para la conexin.
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Management;
namespace WMISample
{
public class MyQuerySample : System.Windows.Forms.Form
{
private System.Windows.Forms.Label userNameLabel;
private System.Windows.Forms.TextBox userNameBox;
private System.Windows.Forms.TextBox passwordBox;
private System.Windows.Forms.Label passwordLabel;
private System.Windows.Forms.Button OKButton;
private System.Windows.Forms.Button cancelButton;
private System.ComponentModel.Container components = null;
public MyQuerySample()
{
InitializeComponent();
}
//
this.userNameLabel.Location = new System.Drawing.Point(16, 8);
this.userNameLabel.Name = "userNameLabel";
this.userNameLabel.Size = new System.Drawing.Size(160, 32);
this.userNameLabel.TabIndex = 0;
this.userNameLabel.Text = "Enter the user name for the remote computer:";
//
// userNameBox
//
this.userNameBox.Location = new System.Drawing.Point(160, 16);
this.userNameBox.Name = "userNameBox";
this.userNameBox.Size = new System.Drawing.Size(192, 20);
this.userNameBox.TabIndex = 1;
this.userNameBox.Text = "";
//
// passwordBox
//
this.passwordBox.Location = new System.Drawing.Point(160, 48);
this.passwordBox.Name = "passwordBox";
this.passwordBox.PasswordChar = '*';
this.passwordBox.Size = new System.Drawing.Size(192, 20);
this.passwordBox.TabIndex = 3;
this.passwordBox.Text = "";
//
// passwordLabel
//
this.passwordLabel.Location = new System.Drawing.Point(16, 48);
this.passwordLabel.Name = "passwordLabel";
this.passwordLabel.Size = new System.Drawing.Size(160, 32);
this.passwordLabel.TabIndex = 2;
this.passwordLabel.Text =
"Enter the password for the remote computer:";
//
// OKButton
//
this.OKButton.Location = new System.Drawing.Point(40, 88);
this.OKButton.Name = "OKButton";
this.OKButton.Size = new System.Drawing.Size(128, 23);
this.OKButton.TabIndex = 4;
this.OKButton.Text = "OK";
this.OKButton.Click += new System.EventHandler(this.OKButton_Click);
//
// cancelButton
//
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Location = new System.Drawing.Point(200, 88);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(128, 23);
this.cancelButton.TabIndex = 5;
this.cancelButton.Text = "Cancel";
this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
//
// MyQuerySample
//
this.AcceptButton = this.OKButton;
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(368, 130);
this.ControlBox = false;
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.OKButton);
this.Controls.Add(this.passwordBox);
this.Controls.Add(this.passwordLabel);
this.Controls.Add(this.userNameBox);
this.Controls.Add(this.userNameLabel);
this.Name = "MyQuerySample";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Remote Connection";
this.ResumeLayout(false);
}
[STAThread]
static void Main()
{
Application.Run(new MyQuerySample());
}
1. Cree una consulta en la que se especifiquen los eventos mediante la clase EventQuery o la
clase WqlEventQuery.
2. Cree una nueva instancia de ManagementEventWatcher para suscribirse a eventos que respondan a la
consulta.
3. Configure un agente de escucha de eventos mediante los eventos EventArrived y Stopped de la clase
ManagementEventWatcher.
4. Cree una clase de controlador de eventos con un mtodo que reciba la clase EventArrivedEventArgs.
5. Cree una instancia del delegado EventArrivedEventHandler que utilice el mtodo de controlador de eventos.
6. Inicie la escucha de eventos llamando al mtodo Start de la clase ManagementEventWatcher.
Esta operacin equivale a llamar a IWbemServices::ExecNotificationQueryAsync o a SWbemServices::
ExecNotificationQueryAsync en WMI sin administrar.
7. Realice otras operaciones.
8. Llame al mtodo Stop de la clase ManagementEventWatcher para detener la escucha.
Esta llamada da fin a la suscripcin.
Ejemplo
En el siguiente ejemplo de cdigo asincrnico se configura un temporizador WMI para provocar un evento cada
segundo, y se quita cuando ya no es necesario. El objeto ManagementEventWatcher define varios eventos .NET
Framework que se generan cuando se entregan eventos de WMI. Con el fin de controlar los datos entrantes, se asocian
delegados a estos eventos.
using System;
using System.Management;
Ejemplo
En el siguiente ejemplo de cdigo se demuestra cmo consultar informacin de administracin de forma asincrnica. La
consulta es para instancias de la clase Win32_Service (servicios que se ejecutan en el equipo local); se muestran el
nombre y estado de las instancias de la clase Win32_Service.
using System;
using System.Management;
Ejemplo
En el siguiente ejemplo de cdigo se conceden todos los derechos al grupo Usuarios avanzados para un espacio de
nombres determinado. Para cambiar el nombre del espacio de nombres, cambie el valor de la variable namespace
Name en la clase Sample.
using System;
using System.Management;
using System.ComponentModel;
using System.Runtime.InteropServices;
namespace ManagementSample
{
class Sample
{
private readonly string namespaceName = "TestNamespaceSecurity";
Marshal.Copy(securityDescriptorPtr,
securityDescriptor, 0, securityDescriptorSize);
//Set the new SD for the namespace
ManagementBaseObject inParams =
systemSecurity.GetMethodParameters("SetSD");
inParams["SD"] = securityDescriptor;
outParams = systemSecurity.InvokeMethod("SetSD",
inParams, null);
if ((uint)outParams["ReturnValue"] != 0)
{
Console.WriteLine("SetSD returns error: " +
outParams["ReturnValue"]);
return;
}
Console.WriteLine("\nNew string security descriptor"
+ " is set. Press Enter to exit.");
Console.ReadLine();
}
finally
{
// Free unmanaged memory
if (securityDescriptorPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(securityDescriptorPtr);
securityDescriptorPtr = IntPtr.Zero;
}
if (stringSecurityDescriptorPtr != IntPtr.Zero)
{
Marshal.FreeHGlobal(stringSecurityDescriptorPtr);
stringSecurityDescriptorPtr = IntPtr.Zero;
}
this.DeleteTestNamespace();
}
}
[DllImport("Advapi32.dll", CharSet=CharSet.Auto,
SetLastError=true, ExactSpelling=false)]
private static extern bool
ConvertSecurityDescriptorToStringSecurityDescriptor(
[In] byte[] SecurityDescriptor,
[In] int RequestedStringSDRevision,
[In] SecurityInformation SecurityInformation,
[Out] out IntPtr StringSecurityDescriptor,
[Out] out int StringSecurityDescriptorLen
);
[STAThread]
static void Main(string[] args)
{
try
{
new Sample().Run();
}
catch (Win32Exception e)
{
Console.WriteLine(e);
}
}
}
}
Ejemplo
En el siguiente ejemplo de cdigo se incluye la clase con establecimiento inflexible de tipos Service, que es un
contenedor de la clase Win32_Service. Para ejecutar este ejemplo, antes debe generar una clase especfica mediante el
siguiente comando desde la lnea de comandos de Visual Studio 2005 (cambie el valor del lenguaje de cdigo en
funcin de si desea generar un archivo de cdigo C# o Visual Basic .NET):
C:\> MgmtClassGen Win32_Service /L CS /N root\cimv2 /P C:\temp\service.cs
El resultado de la herramienta de generador ser el archivo de cdigo .cs del servicio, que se debe agregar a
continuacin al proyecto junto con el cdigo que aparece abajo. Observe el uso de la clase con establecimiento
inflexible de tipos "Service" en la instruccin foreach en vez de la clase genrica ManagementObjecty el uso de la
notacin estndar simplificada que emplea puntos para el acceso a las propiedades de los objetos devueltos.
using System;
using ROOT.CIMV2.Win32;
// Contains the strongly typed generated class "Service"
// in ROOT.CIMV2.Win32 namespace. This namespace was
// generated using the MgmtClassGen tool for the Win32_Service class
class Sample
{
// Enumerate instances of Win32_Service class
void EnumerateServices()
{
Console.WriteLine("List services and their state");
foreach(Service ser in Service.GetInstances())
Console.WriteLine("Service: "+ ser.Name + " is " + ser.State);
}
clase. La clase generada desde Mgmtclassgen.exe permite al usuario obtener acceso a todos los mtodos y propiedades
de la clase WMI a travs de una clase de enlace en tiempo de compilacin, en contraste con las clases de enlace en
tiempo de ejecucin del espacio de nombres System.Management. Un objeto se enlaza en tiempo de compilacin
cuando se asigna a una variable que se declara de un tipo de objeto especfico. Los objetos enlazados en tiempo de
compilacin permiten al compilador asignar memoria y realizar otras optimizaciones antes de que se ejecute la
aplicacin. Por el contrario, un objeto se enlaza en tiempo de ejecucin cuando se asigna a una variable que se declara
como variable de tipo Object.
Cdigo generado
El cdigo generado desde Mgmtclassgen.exe tiene las siguientes especificaciones:
Todas las propiedades de la clase generada tienen una propiedad equivalente en la clase WMI.
o Las propiedades de slo lectura de la clase WMI, que se identifican por la ausencia de un calificador
Write o por el establecimiento de un calificador Write como null, se representan en el cdigo
generado mediante propiedades que slo utilizan el descriptor de acceso de propiedad get.
o Las propiedades estticas de la clase WMI, identificadas por un calificador esttico en la propiedad,
se representan en el cdigo generado como propiedades estticas.
o Para las propiedades de la clase WMI con calificadores ValueType y Value numricos, las clases de
enumeracin se crean en el cdigo generado. Las propiedades se asignan a un tipo Enum recin
generado.
o Para las propiedades de la clase WMI con calificadores Bitmap y BitValue numricos, las clases de
enumeracin se crean en el cdigo generado. Las propiedades se asignan al tipo Enum recin
generado.
o Todas las propiedades se marcan con atributos Visual Studio para que Visual Studio Intellisense
pueda descubrirlas.
o Todas las propiedades ValueType en el cdigo generado tienen un atributo TypeConverter
establecido como WMIValueTypeConverter. Esto permite la serializacin de estas propiedades en
cadenas.
Todos los mtodos de la clase generada tienen un mtodo equivalente en la clase WMI.
o Todos los mtodos se marcan con el atributo Visual Studio para que Visual Studio Intellisense
pueda descubrirlos.
o Los mtodos estticos de la clase WMI, identificados por un calificador esttico, se crean como
mtodos estticos en el cdigo generado.
Se crean varios constructores en el cdigo generado para inicializar una instancia de la clase generada.
o Un constructor que toma los valores de las propiedades de clase WMI clave (que identifica el
calificador clave) como argumentos de entrada. Este constructor se puede utilizar para inicializar
una instancia mediante los valores clave de la instancia de la clase.
o Una clase WMI Singleton tendr el constructor predeterminado para inicializar la instancia en la
instancia singleton de la clase.
Una clase ManagementSystemProperties interna. Esta clase tiene todas las propiedades de sistema WMI
estndar.
Se generan un enumerador interno y una clase de coleccin para controlar las enumeraciones de la instancia
de la clase WMI. Las clases generadas son <GeneratedClassName> Collection y <GeneratedClassName>
Enumerator.
Variables miembro private
o Variable ManagementBaseObject para almacenar el objeto WMI subyacente.
o Variable de cadena inicializada con el espacio de nombres WMI.
o Variable de cadena inicializada con el nombre de clase WMI.
o Variable ManagementSystemProperties para almacenar las propiedades del sistema.
o Variable AutoCommitProp de tipo Boolean para indicar si la propiedad debe guardarse en WMI
inmediatamente o si debera guardarse en WMI cuando se llame al mtodo CommitObject.
o Variable isEmbedded de tipo Boolean y variable embeddedObj de tipo ManagementBaseObject
para controlar objetos incrustados.
Propiedades public
o Propiedad AutoCommit de tipo Boolean para indicar si las propiedades deben guardarse
inmediatamente despus de establecerse, o bien cuando se llama al mtodo CommitObject.
o Propiedad CreatedWmiNamespace de tipo String que almacena el espacio de nombres WMI de la
clase.
o Propiedad CreatedClassName de tipo String que almacena el nombre de clase WMI.
o La propiedad SystemProperties del tipo ManagementSystemProperties que representa las
propiedades del sistema de la instancia WMI.
o Propiedad LateBoundObject de tipo ManagementBaseObject que almacena el objeto WMI
subyacente.
uint8 Byte
sint8 SByte
uint16 UInt16
sint16 Int16
uint32 UInt32
sint32 Int32
uint64 UInt64
sint64 Int64
string String
boolean Boolean
real32 Single
real64 Double
datetime DateTime
char16 Char
Las matrices en cdigo administrado se asignan a matrices en las definiciones de clase WMI.
La CLI distingue entre tipos de valor y tipos de referencia.
WMI no establece esta distincin y tanto los tipos de valor como los tipos de referencia se pueden asignar a
una definicin de clase WMI.
WMI admite objetos incrustados as como referencias a otros objetos.
El espacio de nombres System.Management.Instrumentation slo admite objetos incrustados, no
referencias. Para clases administradas que contienen miembros de tipo de valor, es lgico que stos se
asignen a clases WMI que contienen un objeto incrustado. Las clases administradas que contienen miembros
de tipo de referencia tambin se asignan a clases WMI con objetos incrustados, pero las futuras versiones
podran permitir que los programadores especifiquen que las referencias en tiempo de ejecucin deban estar
representadas por referencias WMI.
Las jerarquas de herencia de clases administradas estn representadas por jerarquas de herencia en WMI.
El espacio de nombres System.Management.Instrumentation no permite valores WMI predeterminados.
A los inicializadores de campo en campos de clases administradas no se les asignan valores predeterminados
WMI.
WMI no distingue entre campos y propiedades.
En una definicin de clase administrada, tanto a los campos como a las propiedades se les asignan
propiedades WMI.
El espacio de nombres de una definicin de clase administrada no est relacionado con el espacio de
nombres de la definicin de clase WMI.
En otras palabras, una clase administrada podra estar definida en el espacio de nombres
MyCompany.MyApplication y la correspondiente clase de instrumental WMI podra estar definida como el
espacio de nombres WMI root\MyCompany.
WMI admite un concepto similar al de atributo, denominado calificador.
En el espacio de nombres System.Management.Instrumentation no hay asignacin entre atributos de
cdigo administrado y calificadores WMI. Hay atributos en el espacio de nombres System.
Management.Instrumentation, pero no estn representados por calificadores en la definicin de clase WMI.
Para permitir la asignacin entre los dos, el espacio de nombres System.Management.Instrumentation
define varias clases de atributos que permiten a los programadores definir la asignacin en una sintaxis
declarativa (un conocimiento consolidado), en lugar de hacerlo a travs de una nueva API. Como se ha
mencionado, el instrumental consta principalmente de dos fases: definicin de las clases en tiempo de diseo
y provisin de datos en tiempo de ejecucin. El uso de atributos es crucial en la primera fase y permite que los
metadatos de clases administradas describan completamente el esquema del instrumental. Despus, los
metadatos se usan para crear el esquema WMI que pueden ver las herramientas de administracin.
Ejemplo
En el ejemplo de cdigo siguiente se demuestra cmo definir una clase de instrumental de administracin y cmo
publicar una instancia de dicha clase en WMI.
using System;
using System.Management;
using System.Configuration.Install;
using System.Management.Instrumentation;
// Let the system know that the InstallUtil.exe tool will be run against this assembly
[System.ComponentModel.RunInstaller(true)]
public class MyInstaller : DefaultManagementProjectInstaller {}
sencilla mediante la tcnica de derivar una sola clase de la clase auxiliar de Instance en el espacio de
nombres System.Management.Instrumentation, la clase WMI aparece como una sola clase de instancia de nivel superior.
Las jerarquas de instancias, sin embargo, son algo ms complejas. En la versin actual de System.Management, slo los
nodos hoja de una jerarqua de instancias pueden permitir en realidad la publicacin de instancias. Los nodos que no
son hoja se consideran clases WMI abstractas. En otras palabras, si tiene dos clases, BaseInstance y una clase
derivada DerivedInstance, puede crear instancias de la clase DerivedInstance pero no de la clase BaseInstance. Otro
trmino utilizado con frecuencia para describir clases que pueden admitir instancias es clase concreta. Por lo tanto, la
regla de herencia para el instrumental de instancias podra expresarse de la siguiente manera: slo los nodos hoja de
una jerarqua de herencias pueden ser clases concretas de instancia. El resto de los nodos de la jerarqua deben
marcarse como clases WMI abstractas.
Para marcar una clase como clase de instrumental WMI abstracta, debe tener el atributo [InstrumentationClassAttribute
(InstrumentationType.Abstract)]. La clase auxiliar Instance se marca con [InstrumentationClassAttribute
(InstrumentationType.Instance)], que se propaga a clases secundarias de manera predeterminada. Esto no constituye
un problema cuando se tiene una clase de instancia concreta de nivel superior pero, con una jerarqua ms compleja,
tiene que agregar manualmente el atributo Abstract a la clase de nivel superior.
En el siguiente ejemplo de cdigo se muestra una jerarqua que agrega manualmente el atributo Abstract a la clase de
nivel superior. La clase de nivel superior,TopInstance, se deriva de la clase Instance y se marca explcitamente
con Abstract. Las clases derivadas que no son nodos hoja heredarn correctamente este atributo (y sern clases WMI
abstractas como TopInstance). Los nodos hoja deben marcarse como instancias concretas y, por lo tanto, tendrn
atributos Instanceexplcitos en sus definiciones de clase.
using System;
using System.Management.Instrumentation;
[assembly:Instrumented]
// A simple tree of instances derived from Instance
// TopInstance--Branch1Instance--Leaf1AInstance
// \ \-Leaf1BInstance
// \
// Branch2Instance--Leaf2AInstance
// Only the leafs of the tree can be concrete instances.
// All other nodes on the tree must be abstract.
// This is a top-level abstract class. It must have the
// 'InstrumentationType.Abstract' attribute or it would
// inherit the 'Instance' attribute
// from the base class 'Instance'
[InstrumentationClass(InstrumentationType.Abstract)]
public class TopInstance : Instance
{
}
{
}
class App {
static void Main(string[] args)
{
// Publish an instance of each leaf
Leaf1AInstance leaf1a = new Leaf1AInstance();
Leaf1BInstance leaf1b = new Leaf1BInstance();
Leaf2AInstance leaf2a = new Leaf2AInstance();
leaf1a.Published = true;
leaf1b.Published = true;
leaf2a.Published = true;
// Instances now visible through WMI
Console.WriteLine("Instances now visible through WMI");
Console.ReadLine();
// Revoke all instances
leaf1a.Published = false;
leaf1b.Published = false;
leaf2a.Published = false;
}
}
[assembly:Instrumented]
// A simple tree of instances declared with attributes
// TopInstance2--Branch1Instance2--Leaf1AInstance2
// \ \-Leaf1BInstance2
// \
// Branch2Instance2--Leaf2AInstance2
// Only the leafs of the tree can be concrete instances.
// All other nodes on the tree must be abstract.
// This is a top level abstract class.
[InstrumentationClass(InstrumentationType.Abstract)]
public class TopInstance2 {
}
class App {
static void Main(string[] args) {
// Publish an instance of each leaf
Leaf1AInstance2 leaf1a = new Leaf1AInstance2();
Leaf1BInstance2 leaf1b = new Leaf1BInstance2();
Leaf2AInstance2 leaf2a = new Leaf2AInstance2();
Instrumentation.Publish(leaf1a);
Instrumentation.Publish(leaf1b);
Instrumentation.Publish(leaf2a);
// Instances now visible through WMI
Console.WriteLine("Instances now visible through WMI");
Console.ReadLine();
// Revoke all instances
Instrumentation.Revoke(leaf1a);
Instrumentation.Revoke(leaf1b);
Instrumentation.Revoke(leaf2a);
}
}
Los instaladores admiten generalmente un modificador de desinstalacin que se utiliza normalmente de la forma
siguiente:
installutil.exe /U <nombre_del_ensamblado>
donde <nombre_del_ensamblado> es el ensamblado que contiene la definicin del esquema registrado anteriormente.
Sin embargo, en esta versin, la clase ManagementInstaller no realiza ninguna operacin en el proceso de
desinstalacin; ms concretamente, no elimina el registro del esquema. El motivo es que el mismo esquema puede ser
utilizado por ms de un proveedor WMI, y no se est aplicando ningn mecanismo que identifique si un esquema
concreto no est siendo utilizado por otra entidad y se puede quitar de forma segura.
Herencia de eventos
Si deriva ms clases de su propia clase, se reflejarn en un rbol de herencia de eventos WMI.
Con cdigo administrado se puede generar cualquier evento de la jerarqua de clases de evento administradas. De este
modo, las aplicaciones cliente pueden suscribirse a una amplia gama de eventos similares o a un slo evento
especializado. Por ejemplo, si tiene dos clases de eventos, MyBaseEvent y una clase derivada MyDerivedEvent, la
consulta WQL SELECT * FROM MyBaseEvent permitir que una aplicacin cliente detecte ambos
eventos, MyBaseEvent yMyDerivedEvent, generados desde su aplicacin. Por otro lado, un cliente que emita la
consulta WQL SELECT * FROM MyDerivedEvent no vera nada cuando su aplicacin generara MyBaseEvent, pero
obtendra eventos cuando la aplicacin generara MyDerivedEvent.
Ejemplo
En el ejemplo de cdigo siguiente se demuestra cmo crear una clase de eventos de administracin mediante la
derivacin de la clase BaseEvent y cmo generar el evento de administracin con cdigo administrado.
using System;
using System.Management;
using System.Configuration.Install;
using System.Management.Instrumentation;
namespace WMISample
{
// Create a management instrumentation event class
public class MyEvent : System.Management.Instrumentation.BaseEvent
{
private string EventName;
public void setEventName(string name)
{
EventName = name;
}
}
class App {
static void Main(string[] args) {
// Raise each type of event
new TopEvent().Fire();
new Branch1Event().Fire();
new Leaf1AEvent().Fire();
new Leaf1BEvent().Fire();
new Branch2Event().Fire();
new Leaf2AEvent().Fire();
}
}
Ejemplo
En el siguiente ejemplo de cdigo se muestra cmo crear una clase de eventos de administracin mediante el
atributo InstrumentationClass y cmo generar un evento de administracin con cdigo administrado.
using System;
using System.Management;
using System.Configuration.Install;
using System.Management.Instrumentation;
// This example demonstrates how to create a management event class by using
// the InstrumentationClass attribute and to raise a management event from
// managed code.
// Specify which namespace the management event class is created in
[assembly:Instrumented("Root/Default")]
namespace WMISample
{
// Let the system know you will run InstallUtil.exe tool against this assembly
[System.ComponentModel.RunInstaller(true)]
public class MyInstaller : DefaultManagementProjectInstaller {}
using System;
using System.Management.Instrumentation;
[assembly:Instrumented]
// A simple tree of events declared with attributes
// TopEvent2--Branch1Event2--Leaf1AEvent2
// \ \-Leaf1BEvent2
// \
// Branch2Event2--Leaf2AEvent2
// Any event in the hierarchy can be raised by the application
// This is a top-level event class
[InstrumentationClass(InstrumentationType.Event)]
public class TopEvent2 {
}
class App {
static void Main(string[] args) {
// Raise each type of event
Instrumentation.Fire(new TopEvent2());
Instrumentation.Fire(new Branch1Event2());
Instrumentation.Fire(new Leaf1AEvent2());
Instrumentation.Fire(new Leaf1BEvent2());
Instrumentation.Fire(new Branch2Event2());
Instrumentation.Fire(new Leaf2AEvent2());
}
}