Windows 操作 (C++/CLI)

使用 Windows SDK 演示各种特定于 Windows 的任务。

以下主题演示了使用 Visual C++ 通过 Windows SDK 执行的各种 Windows 操作。

确定关闭是否已启动

以下代码示例演示如何确定应用程序或 .NET Framework 当前是否正在终止。 这对于访问 .NET Framework 中的静态元素很有用,因为在关闭期间,这些构造由系统完成,无法可靠使用。 首先检查 HasShutdownStarted 属性,可以通过不访问这些元素来避免潜在的失败。

示例

// 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;
}

确定用户交互状态

以下代码示例演示如何确定代码是否在用户交互上下文中运行。 如果 UserInteractive 为 false,则代码作为服务进程或从 Web 应用程序内部运行,在这种情况下,不应尝试与用户交互。

示例

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

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

从 Windows 注册表中读取数据

下面的代码示例使用 CurrentUser 键从 Windows 注册表读取数据。 首先,使用 GetSubKeyNames 方法枚举子键,然后使用 OpenSubKey 方法打开 Identities 子键。 与根键一样,每个子键都由 RegistryKey 类表示。 最后一点,新的 RegistryKey 对象用于枚举键/值对。

示例

// 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;
}

备注

Registry 类只是 RegistryKey 的静态实例的容器。 每个实例表示根注册表节点。 实例为 ClassesRoot、CurrentConfig、CurrentUser、LocalMachine 和 Users。

除了是静态的,Registry 类中的对象也是只读的。 此外,创建用于访问注册表对象内容的 RegistryKey 类的实例也是只读的。 有关如何替代此行为的示例,请参阅如何:将数据写入 Windows 注册表 (C++/CLI)。

Registry 类中有两个附加对象:DynData 和 PerformanceData。 这两个对象都是 RegistryKey 类的实例。 DynData 对象包含动态注册表信息,该信息仅在 Windows 98 和 Windows ME 中受支持。 PerformanceData 对象可用于访问使用 Windows 性能监视系统的应用程序的性能计数器信息。 PerformanceData 节点表示实际上并未存储在注册表中的信息,因此无法使用 Regedit.exe 进行查看。

读取 Windows 性能计数器

某些应用程序和 Windows 子系统通过 Windows 性能系统公开性能数据。 可以使用驻留在 PerformanceCounterCategory 命名空间中的 PerformanceCounter 和 System.Diagnostics 类访问这些计数器。

以下代码示例使用这些类来检索和显示由 Windows 更新的计数器,指示处理器忙碌的时间百分比。

注意

此示例需要在 Windows Vista 上运行的管理员特权。

示例

// 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;
}

从剪贴板中检索文本

下面的代码示例使用 GetDataObject 成员函数返回指向 IDataObject 接口的指针。 然后,可在此接口中查询数据格式,并用它来检索实际数据。

示例

// 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;
}

检索当前用户名

下面的代码示例演示了检索当前用户名(登录到 Windows 的用户名)的情况。 名称存储在 UserName 字符串中,该字符串在 Environment 命名空间中定义。

示例

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

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

检索 .NET Framework 的版本

以下代码示例演示如何使用 Version 属性确定当前安装的 .NET Framework 的版本,该属性是指向包含版本信息的 Version 对象的指针。

示例

// 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;
}

检索本地计算机名称

以下代码示例演示检索本地计算机名称(显示在网络上的计算机名称)的情况。 可以通过获取在 MachineName 命名空间中定义的 Environment 字符串来完成此操作。

示例

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

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

检索 Windows 版本

以下代码示例演示如何检索当前操作系统的平台和版本信息。 此信息存储在 System.Environment.OSVersion 属性中,由概括地描述 Windows 版本的枚举和包含操作系统的确切版本的 Version 对象组成。

示例

// 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;
}

检索自启动以来经过的时间

以下代码示例演示如何确定滴答计数或自 Windows 启动以来经过的毫秒数。 此值存储在 System.Environment.TickCount 成员中,因为它是一个 32 位值,大约每 24.9 天重置为零。

示例

// 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;
}

将文本存储在剪贴板中

以下代码示例使用 Clipboard 命名空间中定义的 System.Windows.Forms 对象来存储字符串。 此对象提供两个成员函数:SetDataObject 和 GetDataObject。 通过将派生自 Object 的任何对象发送到 SetDataObject,将数据存储在剪贴板中。

示例

// 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;
}

将数据写入 Windows 注册表

以下代码示例使用 CurrentUser 键创建与 Software 键对应的 RegistryKey 类的可写实例。 然后使用 CreateSubKey 方法创建新键并将其添加到键/值对。

示例

// 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;
}

备注

可以使用 .NET Framework 通过 Registry 和 RegistryKey 类访问注册表,这两个类都在 Microsoft.Win32 命名空间中定义。 Registry 类是 类的静态实例的容器RegistryKey。 每个实例表示根注册表节点。 实例为 ClassesRoot、CurrentConfig、CurrentUser、LocalMachine 和 Users。

Environment

另请参阅

使用 C++/CLI (Visual C++) 进行 .NET 编程