Windows の操作 (C++/CLI)

Windows SDK を使用した Windows 固有のさまざまなタスクを紹介します。

以降のトピックでは、Windows SDK で Visual C++ を使用して実行される 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 の静的インスタンスの単なるコンテナーです。 各インスタンスは、ルート レジストリ ノードを表します。 インスタンスは、ClassesRootCurrentConfigCurrentUserLocalMachine、および Users です。

Registry クラスのオブジェクトは、静的オブジェクトであるだけでなく、読み取り専用です。 さらに、レジストリ オブジェクトのコンテンツにアクセスするために作成される RegistryKey クラスのインスタンスも読み取り専用です。 この動作をオーバーライドする方法の例については、Windows レジストリにデータを書き込む方法 (C++/CLI) に関する記事を参照してください。

Registry クラスには、さらに DynDataPerformanceData の 2 つのオブジェクトがあります。 この 2 つのオブジェクトは両方とも RegistryKey クラスのインスタンスです。 DynData オブジェクトには動的レジストリ情報が含まれています。動的レジストリ情報は、Windows 98 および Windows Me でのみサポートされています。 PerformanceData オブジェクトを使用すると、Windows パフォーマンス モニター システムを使用するアプリケーションのパフォーマンス カウンター情報にアクセスできます。 PerformanceData ノードは、実際にはレジストリに格納されていない情報を表しているため、Regedit.exe を使って表示することはできません。

Windows パフォーマンス カウンターを読み取る

一部のアプリケーションと Windows サブシステムでは、Windows パフォーマンス システムを介してパフォーマンス データを公開します。 これらのカウンターにアクセスするには、System.Diagnostics 名前空間にある PerformanceCounterCategory および PerformanceCounter クラスを使用します。

次のコード例は、これらのクラスを使用して、Windows によって更新されたカウンターを取得して表示することで、プロセッサがビジー状態である時間の割合を示します。

Note

この例では、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 にログインしているユーザーの名前) を取得する方法を示します。 名前は、Environment 名前空間で定義されている UserName 文字列に格納されています。

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

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

.NET Framework のバージョンを取得する

次のコード例は、バージョン情報が格納されている Version オブジェクトへのポインターである、Version プロパティを使用して、現在インストールされている .NET Framework のバージョンを確認する方法を示します。

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

ローカル マシン名を取得する

次のコード例は、ローカル コンピューター名 (ネットワーク上に表示されるコンピューターの名前) を取得する方法を示します。 これは、Environment 名前空間で定義されている MachineName 文字列を取得することで実現します。

// 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 日ごとに 0 にリセットされます。

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

クリップボード内にテキストを格納する

次のコード例では、System.Windows.Forms 名前空間で定義されている Clipboard オブジェクトを使用して、文字列を格納します。 このオブジェクトによって、SetDataObjectGetDataObject の 2 つのメンバー関数が提供されます。 データは、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 クラスの静的インスタンスのコンテナーです。 各インスタンスは、ルート レジストリ ノードを表します。 インスタンスは、ClassesRootCurrentConfigCurrentUserLocalMachine、および Users です。

Environment

関連項目

C++/CLI (Visual C++) による .NET プログラミング