.NET TIPS

レジストリの値のデータ型を明示的に識別・設定するには?[2.0のみ、C#、VB]

デジタルアドバンテージ 一色 政彦
2006/07/28

 .NET Framework 1.xでは、レジストリから取得した値のデータ型を明確に識別したり、データ型を明示的に指定して値をレジストリに格納したりすることはできなかった。これらを実現するには、例えば「TIPS:レジストリの値のデータ型を判別するには?」や「TIPS:レジストリの値を設定するには?」で示されているように、

  • レジストリがREG_SZ型なら.NET FrameworkのSystem.String型を使う
  • レジストリがREG_DWORD型なら.NET FrameworkのSystem.Int32型を使う
  • レジストリがREG_BINARY型なら.NET FrameworkのSystem.Byte[]型を使う

のようにして、レジストリのデータ型を.NET Frameworkのデータ型に置き換えて考えなければならなかったため、とても分かりにくかった。

■レジストリ・データ型を明確に取り扱えるメソッド

 しかし、.NET Framework 2.0ではRegistryValueKind列挙体(Microsoft.Win32名前空間)が追加され、この列挙体をパラメータに取る次のようなメソッドが追加された(RegistryKeyはMicrosoft.Win32名前空間に所属するクラスであり、以下で示すメソッド名の右側のカッコ内はパラメータのデータ型を表す)。

  • RegistryKey.GetValueKindメソッド(String)
  • RegistryKey.SetValueメソッド(String, Object, RegistryValueKind)

 GetValueKindメソッドは、そのパラメータにレジストリ値の名前を指定して呼び出すと、その値のレジストリ・データ型(=RegistryValueKind列挙体のオブジェクト)を戻り値として返す。

 SetValueメソッドは、第1パラメータにレジストリ値の名前を、第2パラメータにその値のデータを、第3パラメータにその値のデータ型を指定して呼び出すと、指定したデータ型でそのレジストリ値をレジストリに設定できる。戻り値はない。

■RegistryValueKind列挙体が対応しているレジストリ・データ型

 RegistryValueKind列挙体では、次の表に示すデータ型に対応している。

データ型 レジストリ RegistryValueKind列挙体のメンバ 説明
文字列値 REG_SZ String ullで終わる Unicode文字列値
DWORD値(数値) REG_DWORD DWord 4bytes(32bit)長の数値。数値の範囲は「0(0x00000000)」〜「4294967295(0xffffffff)」(説明欄を参照)
バイナリ値 REG_BINARY Binary 未加工のバイナリ・データ
複数行文字列値 REG_MULTI_SZ MultiString nullで終わる Unicode文字列の配列
展開可能な文字列値 REG_EXPAND_SZ ExpandString 環境変数(例えば「%USERNAME%」や「%SystemRoot%」など)を含むnullで終わるUnicode文字列
QWORD値 REG_QWORD QWord 8bytes(64bit)長の数値。数値の範囲は「0(0x0000000000000000)」〜「18446744073709551615(0xffffffffffffffff)」(説明欄を参照)。Windows 2000以降で利用可能
不明 - Unknown サポート外のレジストリ・データ型(説明欄を参照)
RegistryValueKind列挙体で定義されているレジストリ・データ型の一覧表
DWORD値は.NET FrameworkではInt32型で表現される。そのため、Int32型の最大値「2147483647(0x7fffffff)」を超える数値を指定するにはUInt32型の数値をInt32型にキャストする必要がある(その際C#では、uncheckedキーワードを使用して数値のオーバーフローのチェックを外す必要がある)。また同様に、QWORD値は.NET FrameworkではInt64型で表現されるので、その最大値を超える数値を指定するにはUInt64型の数値をInt64型にキャストする必要がある。

RegistryValueKind列挙体がサポートしていないレジストリ・データ型には次のようなものがある。

なし(REG_NONE):特定の型を持たないデータ。
リンク(REG_LINK):シンボリック・リンクを指定するUnicode文字列値。
バイナリ値(REG_RESOURCE_LIST、REG_RESOURCE_REQUIREMENTS_LIST、REG_FULL_RESOURCE_DESCRIPTOR):ネストされた一連の配列で、デバイス・ドライバが活用するリソースの一覧データなどで使われる。

 注意が必要なのは、REG_EXPAND_SZ型(=RegistryValueKind.ExpandString)である。この型のレジストリ値を取得する際、そのデータ内に実際に環境変数(例えば、「%SystemRoot%」など)を含んでいる場合は、その環境変数を「C:\Windows」などの本来の文字列に自分で展開する必要がある(環境変数の展開を行うには、Environmentクラス(System名前空間)のExpandEnvironmentVariablesメソッドを呼び出せばよい)。ただ、筆者が試した環境では、REG_EXPAND_SZ型のデータを取得した段階ですでに環境変数が文字列に展開されて取得でき、展開を行う必要はなかった。

 なお、これらのデータ型の中で最も使われるのはREG_SZで、その次がDWORD値である。それ以外のデータ型はほとんど使われることがないだろう。

■レジストリ値のデータ型の識別

 ここでは、RegistryValueKind列挙体を活用して、レジストリ値のデータ型の識別を行うサンプル・プログラムを示しておく。

 このサンプル・プログラムは、「TIPS:レジストリの値のデータ型を判別するには?」で提示したサンプル・プログラムのレジストリ・データ型を判定する部分のコードを少し書き換えたものだ。コードの内容についてはコード中のコメントを参照するとともに、より詳しくはそのTIPSを参照してほしい。

using System;
using Microsoft.Win32;

namespace ConsoleApplication1
{
  class Program
  {
    static void Main(string[] args)
    {
      // 操作するレジストリ・キーの名前
      string regKeyName = @"SOFTWARE\Microsoft\.NETFramework";
      // 取得処理を行う対象となるレジストリの値の名前
      string regValueName = "DbgJITDebugLaunchSetting";

      // レジストリの取得
      try
      {
        // レジストリ・キーのパスを指定してレジストリを開く
        RegistryKey regKey =
          Registry.LocalMachine.OpenSubKey(regKeyName);

        // レジストリ値のデータ型を調べる
        RegistryValueKind regDataType =
          regKey.GetValueKind(regValueName);

        // レジストリ値を取得
        object regData = regKey.GetValue(regValueName);

        // 開いたレジストリを閉じる
        regKey.Close();

        // コンソールに取得したレジストリ値を表示
        Console.WriteLine(
          regDataType.ToString() + ":" + regData.ToString());
        // ▼出力例▼
        // DWord:2
      }
      catch (NullReferenceException)
      {
        // レジストリ・キーまたは値が存在しない
        Console.WriteLine("レジストリ[" + regKeyName
          + "]の[" + regValueName + "]がありません!");
      }
    }
  }
}
Imports Microsoft.Win32

Module Module1

  Sub Main()
    ' 操作するレジストリ・キーの名前
    Dim regKeyName As String = "SOFTWARE\Microsoft\.NETFramework"
    ' 取得処理を行う対象となるレジストリの値の名前
    Dim regValueName As String = "DbgJITDebugLaunchSetting"

    ' レジストリの取得
    Try
      ' レジストリ・キーのパスを指定してレジストリを開く
      Dim regKey As RegistryKey = _
        Registry.LocalMachine.OpenSubKey(regKeyName)

      ' レジストリ値のデータ型を調べる
      Dim regDataType As RegistryValueKind = _
        regKey.GetValueKind(regValueName)

      ' レジストリ値を取得
      Dim regData As Object = regKey.GetValue(regValueName)

      ' 開いたレジストリを閉じる
      regKey.Close()

      ' コンソールに取得したレジストリ値を表示
      Console.WriteLine( _
        regDataType.ToString() & ":" & regData.ToString())

    Catch ex As NullReferenceException
      ' レジストリ・キーまたは値が存在しない
      Console.WriteLine("レジストリ[" & regKeyName _
        & "]の[" & regValueName & "]がありません!")
    End Try
  End Sub

End Module
レジストリ値のデータ型を明確に識別するサンプル・プログラム(上:C#、下:VB)

■明示的な型指定による値の設定

 次に、RegistryValueKind列挙体を活用して、明示的な型指定による値の設定を行うサンプル・プログラムを示す。

 このサンプル・プログラムは、「TIPS:レジストリの値を設定するには?」で提示したサンプル・プログラムのレジストリ値を設定する部分のコードを書き換えたものだ。

using System;
using Microsoft.Win32;

namespace ConsoleApplication1
{
  class Class1
  {
    [STAThread]
    static void Main(string[] args)
    {
      // 操作するレジストリ・キーの名前
      string regKeyName = @"SOFTWARE\Insider.NET\.NET TIPS";

      // 設定処理を行う対象となるレジストリの値の名前
      string regValueName = "TestValue";

      // 設定する値のデータ
      int regData = 100;

      // レジストリの設定
      try
      {
        // レジストリ・キーを新規作成して開く
        RegistryKey regKey =
          Registry.LocalMachine.CreateSubKey(regKeyName);

        // レジストリ値をデータ型を明示して設定
        regKey.SetValue(
          regValueName, regData, RegistryValueKind.DWord);

        // 開いたレジストリを閉じる
        regKey.Close();

        // 設定したレジストリ値をコンソールに表示
        Console.WriteLine(regData);
      }
      catch (Exception ex)
      {
        Console.WriteLine(ex.Message);
      }
    }
  }
}
Imports Microsoft.Win32

Module Module1

  Sub Main()

    ' 操作するレジストリ・キーの名前
    Dim regKeyName As String = "SOFTWARE\Insider.NET\.NET TIPS"

    ' 設定処理を行う対象となるレジストリの値の名前
    Dim regValueName As String = "TestValue"

    ' 設定する値のデータ
    Dim regData As Integer = 100

    ' レジストリの設定
    Try
      ' レジストリ・キーを新規作成して開く
      Dim regKey As RegistryKey = _
        Registry.LocalMachine.CreateSubKey(regKeyName)

      ' レジストリ値をデータ型を明示して設定
      regKey.SetValue( _
        regValueName, regData, RegistryValueKind.DWord)

      ' 開いたレジストリを閉じる
      regKey.Close()

      ' 設定したレジストリ値をコンソールに表示
      Console.WriteLine(regData)

    Catch ex As Exception
      Console.WriteLine(ex.Message)
    End Try

  End Sub

End Module
明示的に型指定してレジストリ値を設定するサンプル・プログラム(上:C#、下:VB)

 もちろん.NET Framework 2.0でも.NET Framework 1.xのような暗黙的な型指定も可能だ。しかし、RegistryValueKind列挙体を使えばコード内容がより明確になるので、.NET Framework 2.0の環境であればこちらを使用すべきだ。End of Article

カテゴリ:クラス・ライブラリ 処理対象:レジストリ
使用ライブラリ:RegistryValueKind列挙体(Microsoft.Win32名前空間)

この記事と関連性の高い別の.NET TIPS
レジストリの値のデータ型を判別するには?
レジストリの値を列挙するには?
レジストリの値を設定するには?
レジストリの値を取得するには?
数値のデータ型を明示的に指定するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間