Operaciones de Windows (C++/CLI)

Muestra varias tareas específicas de Windows mediante Windows SDK.

En los temas siguientes se muestran varias operaciones de Windows realizadas con Windows SDK mediante Visual C++.

Determinación de si se ha iniciado el cierre del sistema

En el ejemplo de código siguiente se muestra cómo determinar si la aplicación o .NET Framework está terminando actualmente. Esto resulta útil para acceder a elementos estáticos en .NET Framework porque, durante el apagado, el sistema finaliza estas construcciones y no se pueden usar de forma confiable. Al comprobar primero la propiedad HasShutdownStarted, puede evitar posibles errores al no tener acceso a estos elementos.

Ejemplo

// check_shutdown.cpp
// compile with: /clr
using namespace System;
int main()
{
   if (Environment::HasShutdownStarted)
      Console::WriteLine("Shutting down.");
   else
      Console::WriteLine("Not shutting down.");
   return 0;
}

Determinación del estado de interacción con el usuario

En el ejemplo de código siguiente se muestra cómo determinar si el código se ejecuta en un contexto interactivo del usuario. Si UserInteractive es false, el código se ejecuta como un proceso de servicio o desde dentro de una aplicación web, en cuyo caso no debe intentar interactuar con el usuario.

Ejemplo

// user_interactive.cpp
// compile with: /clr
using namespace System;

int main()
{
   if ( Environment::UserInteractive )
      Console::WriteLine("User interactive");
   else
      Console::WriteLine("Noninteractive");
   return 0;
}

Lectura de datos en el Registro de Windows

El ejemplo de código siguiente utiliza la clave CurrentUser para leer los datos del Registro de Windows. Primero, se enumeran las subclaves utilizando el método GetSubKeyNames y, a continuación, se abre la subclave Identities utilizando el método OpenSubKey. Del mismo modo que las claves raíz, cada subclave se representa mediante la clase RegistryKey. Finalmente, el nuevo objeto RegistryKey se utiliza para enumerar los pares clave/valor.

Ejemplo

// registry_read.cpp
// compile with: /clr
using namespace System;
using namespace Microsoft::Win32;

int main( )
{
   array<String^>^ key = Registry::CurrentUser->GetSubKeyNames( );

   Console::WriteLine("Subkeys within CurrentUser root key:");
   for (int i=0; i<key->Length; i++)
   {
      Console::WriteLine("   {0}", key[i]);
   }

   Console::WriteLine("Opening subkey 'Identities'...");
   RegistryKey^ rk = nullptr;
   rk = Registry::CurrentUser->OpenSubKey("Identities");
   if (rk==nullptr)
   {
      Console::WriteLine("Registry key not found - aborting");
      return -1;
   }

   Console::WriteLine("Key/value pairs within 'Identities' key:");
   array<String^>^ name = rk->GetValueNames( );
   for (int i=0; i<name->Length; i++)
   {
      String^ value = rk->GetValue(name[i])->ToString();
      Console::WriteLine("   {0} = {1}", name[i], value);
   }

   return 0;
}

Comentarios

La clase Registry es simplemente un contenedor para instancias estáticas de RegistryKey. Cada instancia representa un nodo de Registro raíz. Las instancias son ClassesRoot, CurrentConfig, CurrentUser, LocalMachine y Users.

Además de ser estáticos, los objetos incluidos en la clase Registry son de sólo lectura. Por otra parte, las instancias de la clase RegistryKey que se crean para tener acceso al contenido de los objetos del Registro también son de sólo lectura. Para obtener un ejemplo de cómo invalidar este comportamiento, vea Cómo: Escribir datos en el Registro de Windows.

Hay dos objetos adicionales en la clase Registry: DynData y PerformanceData. Los dos son instancias de la clase RegistryKey. El objeto DynData contiene información dinámica del Registro, que solo se admite en Windows 98 y Windows Me. El objeto PerformanceData se puede usar para tener acceso a información del contador de rendimiento para aplicaciones que usan el sistema de supervisión de rendimiento de Windows. El nodo PerformanceData representa información que no está almacenada realmente en el Registro y, por consiguiente, no se puede ver utilizando Regedit.exe.

Lectura de contadores de rendimiento de Windows

Algunas aplicaciones y subsistemas de Windows exponen datos de rendimiento a través del sistema de rendimiento de Windows. Se puede acceder a estos contadores utilizando las clases PerformanceCounterCategory y PerformanceCounter, que residen en el espacio de nombres System.Diagnostics.

En el ejemplo de código siguiente se usan estas clases para recuperar y mostrar un contador actualizado por Windows para indicar el porcentaje de tiempo que el procesador está ocupado.

Nota:

Este ejemplo exige privilegios administrativos para ejecutarse en Windows Vista.

Ejemplo

// processor_timer.cpp
// compile with: /clr
#using <system.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Diagnostics;
using namespace System::Timers;

ref struct TimerObject
{
public:
   static String^ m_instanceName;
   static PerformanceCounter^ m_theCounter;

public:
   static void OnTimer(Object^ source, ElapsedEventArgs^ e)
   {
      try
      {
         Console::WriteLine("CPU time used: {0,6} ",
          m_theCounter->NextValue( ).ToString("f"));
      }
      catch(Exception^ e)
      {
         if (dynamic_cast<InvalidOperationException^>(e))
         {
            Console::WriteLine("Instance '{0}' does not exist",
                  m_instanceName);
            return;
         }
         else
         {
            Console::WriteLine("Unknown exception... ('q' to quit)");
            return;
         }
      }
   }
};

int main()
{
   String^ objectName = "Processor";
   String^ counterName = "% Processor Time";
   String^ instanceName = "_Total";

   try
   {
      if ( !PerformanceCounterCategory::Exists(objectName) )
      {
         Console::WriteLine("Object {0} does not exist", objectName);
         return -1;
      }
   }
   catch (UnauthorizedAccessException ^ex)
   {
      Console::WriteLine("You are not authorized to access this information.");
      Console::Write("If you are using Windows Vista, run the application with ");
      Console::WriteLine("administrative privileges.");
      Console::WriteLine(ex->Message);
      return -1;
   }

   if ( !PerformanceCounterCategory::CounterExists(
          counterName, objectName) )
   {
      Console::WriteLine("Counter {0} does not exist", counterName);
      return -1;
   }

   TimerObject::m_instanceName = instanceName;
   TimerObject::m_theCounter = gcnew PerformanceCounter(
          objectName, counterName, instanceName);

   System::Timers::Timer^ aTimer = gcnew System::Timers::Timer();
   aTimer->Elapsed += gcnew ElapsedEventHandler(&TimerObject::OnTimer);
   aTimer->Interval = 1000;
   aTimer->Enabled = true;
   aTimer->AutoReset = true;

   Console::WriteLine("reporting CPU usage for the next 10 seconds");
   Thread::Sleep(10000);
   return 0;
}

Recuperación de texto del Portapapeles

En el ejemplo de código siguiente se usa la función miembro GetDataObject para devolver un puntero a la interfaz IDataObject. A continuación, se puede consultar esta interfaz para conocer el formato de los datos y utilizarla para recuperar los datos reales.

Ejemplo

// read_clipboard.cpp
// compile with: /clr
#using <system.dll>
#using <system.Drawing.dll>
#using <system.windows.forms.dll>

using namespace System;
using namespace System::Windows::Forms;

[STAThread] int main( )
{
   IDataObject^ data = Clipboard::GetDataObject( );

   if (data)
   {
      if (data->GetDataPresent(DataFormats::Text))
      {
         String^ text = static_cast<String^>
           (data->GetData(DataFormats::Text));
         Console::WriteLine(text);
      }
      else
         Console::WriteLine("Nontext data is in the Clipboard.");
   }
   else
   {
      Console::WriteLine("No data was found in the Clipboard.");
   }

   return 0;
}

Recuperación del nombre de usuario actual

En el ejemplo de código siguiente se muestra la recuperación del nombre de usuario actual (el nombre del usuario que inició sesión en Windows). El nombre se almacena en la cadena UserName, que se define en el espacio de nombres Environment.

Ejemplo

// username.cpp
// compile with: /clr
using namespace System;

int main()
{
   Console::WriteLine("\nCurrent user: {0}", Environment::UserName);
   return 0;
}

Recuperación de la versión de .NET Framework

En el ejemplo de código siguiente se muestra cómo determinar la versión de .NET Framework instalada actualmente con la propiedad Version, que es un puntero a un objeto Version que contiene la información de versión.

Ejemplo

// dotnet_ver.cpp
// compile with: /clr
using namespace System;
int main()
{
   Version^ version = Environment::Version;
   if (version)
   {
      int build = version->Build;
      int major = version->Major;
      int minor = version->Minor;
      int revision = Environment::Version->Revision;
      Console::Write(".NET Framework version: ");
      Console::WriteLine("{0}.{1}.{2}.{3}",
            build, major, minor, revision);
   }
   return 0;
}

Recuperación del nombre del equipo local

En el ejemplo de código siguiente se muestra la recuperación del nombre del equipo local (el nombre del equipo tal como aparece en una red). Para ello, obtenga la cadena MachineName, que se define en el espacio de nombres Environment.

Ejemplo

// machine_name.cpp
// compile with: /clr
using namespace System;

int main()
{
   Console::WriteLine("\nMachineName: {0}", Environment::MachineName);
   return 0;
}

Recuperación de la versión de Windows

En el ejemplo de código siguiente se muestra cómo recuperar la información de la plataforma y la versión del sistema operativo actual. Esta información se almacena en la propiedad System.Environment.OSVersion y consta de una enumeración que describe la versión de Windows en términos generales y un objeto Version que contiene la compilación exacta del sistema operativo.

Ejemplo

// os_ver.cpp
// compile with: /clr
using namespace System;

int main()
{
   OperatingSystem^ osv = Environment::OSVersion;
   PlatformID id = osv->Platform;
   Console::Write("Operating system: ");

   if (id == PlatformID::Win32NT)
      Console::WriteLine("Win32NT");
   else if (id == PlatformID::Win32S)
      Console::WriteLine("Win32S");
   else if (id == PlatformID::Win32Windows)
      Console::WriteLine("Win32Windows");
   else
      Console::WriteLine("WinCE");

   Version^ version = osv->Version;
   if (version)
   {
      int build = version->Build;
      int major = version->Major;
      int minor = version->Minor;
      int revision = Environment::Version->Revision;
      Console::Write("OS Version: ");
      Console::WriteLine("{0}.{1}.{2}.{3}",
                   build, major, minor, revision);
   }

   return 0;
}

Recuperación del tiempo transcurrido desde el inicio

En el ejemplo de código siguiente se muestra cómo determinar el contador o el número de milisegundos que han transcurrido desde que se inició Windows. Este valor se almacena en el miembro System.Environment.TickCount y, dado que es un valor de 32 bits, se restablece a cero aproximadamente cada 24,9 días.

Ejemplo

// startup_time.cpp
// compile with: /clr
using namespace System;

int main( )
{
   Int32 tc = Environment::TickCount;
   Int32 seconds = tc / 1000;
   Int32 minutes = seconds / 60;
   float hours = static_cast<float>(minutes) / 60;
   float days = hours / 24;

   Console::WriteLine("Milliseconds since startup: {0}", tc);
   Console::WriteLine("Seconds since startup: {0}", seconds);
   Console::WriteLine("Minutes since startup: {0}", minutes);
   Console::WriteLine("Hours since startup: {0}", hours);
   Console::WriteLine("Days since startup: {0}", days);

   return 0;
}

Almacenamiento de texto en el Portapapeles

En el ejemplo de código siguiente se usa el objeto Clipboard definido en el espacio de nombres System.Windows.Forms para almacenar una cadena. Este objeto proporciona dos funciones miembro: SetDataObject y GetDataObject. Los datos se almacenan en el Portapapeles mediante el envío de cualquier objeto derivado de Object a SetDataObject.

Ejemplo

// store_clipboard.cpp
// compile with: /clr
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>

using namespace System;
using namespace System::Windows::Forms;

[STAThread] int main()
{
   String^ str = "This text is copied into the Clipboard.";

   // Use 'true' as the second argument if
   // the data is to remain in the clipboard
   // after the program terminates.
   Clipboard::SetDataObject(str, true);

   Console::WriteLine("Added text to the Clipboard.");

   return 0;
}

Escritura de datos en el Registro de Windows

El ejemplo de código siguiente utiliza la clave CurrentUser para crear una instancia editable de la clase RegistryKey que corresponde a la clave Software. El método CreateSubKey se utiliza después para crear una nueva clave y agregarla a pares clave/valor.

Ejemplo

// registry_write.cpp
// compile with: /clr
using namespace System;
using namespace Microsoft::Win32;

int main()
{
   // The second OpenSubKey argument indicates that
   // the subkey should be writable.
   RegistryKey^ rk;
   rk  = Registry::CurrentUser->OpenSubKey("Software", true);
   if (!rk)
   {
      Console::WriteLine("Failed to open CurrentUser/Software key");
      return -1;
   }

   RegistryKey^ nk = rk->CreateSubKey("NewRegKey");
   if (!nk)
   {
      Console::WriteLine("Failed to create 'NewRegKey'");
      return -1;
   }

   String^ newValue = "NewValue";
   try
   {
      nk->SetValue("NewKey", newValue);
      nk->SetValue("NewKey2", 44);
   }
   catch (Exception^)
   {
      Console::WriteLine("Failed to set new values in 'NewRegKey'");
      return -1;
   }

   Console::WriteLine("New key created.");
   Console::Write("Use REGEDIT.EXE to verify ");
   Console::WriteLine("'CURRENTUSER/Software/NewRegKey'\n");
   return 0;
}

Comentarios

Puede utilizar .NET Framework para tener acceso al Registro con las clases Registry y RegistryKey, que se definen ambas en el espacio de nombres Microsoft.Win32. La clase Registry es un contenedor para las instancias estáticas de la clase RegistryKey. Cada instancia representa un nodo de Registro raíz. Las instancias son ClassesRoot, CurrentConfig, CurrentUser, LocalMachine y Users.

Environment

Consulte también

Programación de .NET con C++/CLI (Visual C++)