Operazioni Windows (C++/CLI)
Illustra varie attività specifiche di Windows con Windows SDK.
Gli argomenti seguenti illustrano varie operazioni di Windows eseguite con Windows SDK usando Visual C++.
Determinare se l'arresto è stato avviato
Nell'esempio di codice seguente viene illustrato come determinare se l'applicazione o .NET Framework sta terminando. Ciò è utile per accedere agli elementi statici in .NET Framework perché, durante l'arresto, questi costrutti vengono finalizzati dal sistema e non possono essere usati in modo affidabile. Controllando prima la HasShutdownStarted proprietà, è possibile evitare potenziali errori non accedendo a questi elementi.
Esempio
// 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;
}
Determinare lo stato interattivo dell'utente
Nell'esempio di codice seguente viene illustrato come determinare se il codice viene eseguito in un contesto interattivo dell'utente. Se UserInteractive è false, il codice viene eseguito come processo del servizio o dall'interno di un'applicazione Web, nel qual caso non è consigliabile tentare di interagire con l'utente.
Esempio
// user_interactive.cpp
// compile with: /clr
using namespace System;
int main()
{
if ( Environment::UserInteractive )
Console::WriteLine("User interactive");
else
Console::WriteLine("Noninteractive");
return 0;
}
Leggere i dati dal Registro di sistema di Windows
Nell'esempio di codice seguente viene usata la CurrentUser chiave per leggere i dati dal Registro di sistema di Windows. Prima di tutto, le sottochiavi vengono enumerate usando il metodo e quindi la GetSubKeyNames sottochiave Identities viene aperta usando il OpenSubKey metodo . Come le chiavi radice, ogni sottochiave è rappresentata dalla RegistryKey classe . Infine, il nuovo RegistryKey oggetto viene usato per enumerare le coppie chiave/valore.
Esempio
// 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;
}
Osservazioni:
La Registry classe è semplicemente un contenitore per le istanze statiche di RegistryKey. Ogni istanza rappresenta un nodo del Registro di sistema radice. Le istanze sono ClassesRoot, CurrentConfigCurrentUser, LocalMachine, e Users.
Oltre a essere statici, gli oggetti all'interno della Registry classe sono di sola lettura. Inoltre, anche le istanze della RegistryKey classe create per accedere al contenuto degli oggetti del Registro di sistema sono di sola lettura. Per un esempio di come eseguire l'override di questo comportamento, vedere Procedura: Scrivere dati nel Registro di sistema di Windows (C++/CLI).
Nella classe sono presenti due oggetti Registry aggiuntivi: DynData e PerformanceData. Entrambe sono istanze della RegistryKey classe . L'oggetto DynData contiene informazioni dinamiche del Registro di sistema, supportate solo in Windows 98 e Windows Me. L'oggetto PerformanceData può essere utilizzato per accedere alle informazioni sul contatore delle prestazioni per le applicazioni che usano il sistema di Monitor prestazioni Windows. Il PerformanceData nodo rappresenta informazioni non effettivamente archiviate nel Registro di sistema e pertanto non possono essere visualizzate utilizzando Regedit.exe.
Leggere i contatori delle prestazioni di Windows
Alcune applicazioni e sottosistemi Windows espongono dati sulle prestazioni tramite il sistema di prestazioni windows. È possibile accedere a questi contatori usando le PerformanceCounterCategory classi e PerformanceCounter che risiedono nello spazio dei System.Diagnostics nomi .
L'esempio di codice seguente usa queste classi per recuperare e visualizzare un contatore aggiornato da Windows per indicare la percentuale di tempo occupata dal processore.
Nota
Per l'esecuzione di questo esempio in Windows Vista sono necessari privilegi di amministratore.
Esempio
// 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;
}
Recuperare testo dagli Appunti
Nell'esempio di codice seguente viene utilizzata la GetDataObject funzione membro per restituire un puntatore all'interfaccia IDataObject . Questa interfaccia può quindi essere eseguita una query per il formato dei dati e usata per recuperare i dati effettivi.
Esempio
// 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;
}
Recuperare il nome utente corrente
Nell'esempio di codice seguente viene illustrato il recupero del nome utente corrente (il nome dell'utente connesso a Windows). Il nome viene archiviato nella UserName stringa, definita nello spazio dei Environment nomi .
Esempio
// username.cpp
// compile with: /clr
using namespace System;
int main()
{
Console::WriteLine("\nCurrent user: {0}", Environment::UserName);
return 0;
}
Recuperare la versione di .NET Framework
Nell'esempio di codice seguente viene illustrato come determinare la versione di .NET Framework attualmente installata con la Version proprietà , ovvero un puntatore a un Version oggetto che contiene le informazioni sulla versione.
Esempio
// 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;
}
Recuperare il nome del computer locale
Nell'esempio di codice seguente viene illustrato il recupero del nome del computer locale (il nome del computer visualizzato in una rete). A tale scopo, ottenere la MachineName stringa definita nello spazio dei Environment nomi .
Esempio
// machine_name.cpp
// compile with: /clr
using namespace System;
int main()
{
Console::WriteLine("\nMachineName: {0}", Environment::MachineName);
return 0;
}
Recuperare la versione di Windows
Nell'esempio di codice seguente viene illustrato come recuperare le informazioni sulla piattaforma e sulla versione del sistema operativo corrente. Queste informazioni vengono archiviate nella System.Environment.OSVersion proprietà e sono costituite da un'enumerazione che descrive la versione di Windows in termini generali e un Version oggetto che contiene la build esatta del sistema operativo.
Esempio
// 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;
}
Recuperare il tempo trascorso dall'avvio
Nell'esempio di codice seguente viene illustrato come determinare il conteggio dei tick o il numero di millisecondi trascorsi dall'avvio di Windows. Questo valore viene archiviato nel System.Environment.TickCount membro e, poiché è un valore a 32 bit, viene reimpostato su zero circa ogni 24,9 giorni.
Esempio
// 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;
}
Archiviare testo negli Appunti
Nell'esempio di codice seguente viene usato l'oggetto Clipboard definito nello System.Windows.Forms spazio dei nomi per archiviare una stringa. Questo oggetto fornisce due funzioni membro: SetDataObject e GetDataObject. I dati vengono archiviati negli Appunti inviando qualsiasi oggetto derivato da Object a SetDataObject.
Esempio
// 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;
}
Scrivere dati nel Registro di sistema di Windows
Nell'esempio di codice seguente viene usata la CurrentUser chiave per creare un'istanza scrivibile della RegistryKey classe corrispondente alla chiave Software . Il CreateSubKey metodo viene quindi usato per creare una nuova chiave e aggiungere a coppie chiave/valore.
Esempio
// 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;
}
Osservazioni:
È possibile usare .NET Framework per accedere al Registro di sistema con le Registry classi e RegistryKey , entrambe definite nello spazio dei Microsoft.Win32 nomi . La classe Registry è un contenitore per le istanze statiche della RegistryKey classe . Ogni istanza rappresenta un nodo del Registro di sistema radice. Le istanze sono ClassesRoot, CurrentConfigCurrentUser, LocalMachine, e Users.