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,這是指向包含版本資訊的物件的指標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 登錄

下列程式碼範例會使用金鑰來建立對應於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 來使用定義在 Microsoft.Win32 命名空間中的 Registry 和 RegistryKey 類別來存取登錄。 Registry 類別是包含RegistryKey類別靜態實例的容器。 每個實例都代表根登錄節點。 實體為 ClassesRoot、 CurrentConfig、 CurrentUser、 LocalMachine和 Users。

Environment

另請參閱

以 C++/CLI 進行 .NET 程式設計 (Visual C++)