Windowsのレジストリについての概要とアプリケーションでの利用方針

#概要
Microsoft Windows OSのための設定や拡張情報を格納するデーターベースです。 ハードウェアの情報や、OSの情報、各種アプリケーションの情報が含まれています。 これはWindows3.1のINIファイルに代わる仕組みで、Windows95から導入されています。 

regedit32.exe または regedit.exeで、レジストリのデータベースを参照、変更することが可能です。

#構造
##キーと値
レジストリには２つの基本的要素　キーと値があります。 

![www37.atwiki.jp.png](https://qiita-image-store.s3.amazonaws.com/0/47856/6741f4e9-29b3-1398-c535-33b340446378.png)

###キー
レジストリのキーはフォルダに似ていて、この中に値を追加します。キーの中にサブキーを含むことができます。

```
 HKEY_LOCAL_MACHINE\Software\Microsoft\Windows
```

主なキーには以下のようなものがあります。

###HKEY_CLASSES_ROOT (HKCR)
HKEY_CLASSES_ROOTではアプリケーションの関連付けや、拡張子・アイコン等の情報ならびに、またOLE(Object Linking Embedding)に関する情報も格納されています。

なお、OLEとは、Windowsにおいて、アプリケーションソフト間でデータを転送・共有するための仕組みの事を指します。

###HKEY_CURRENT_USER (HKCU)
HKEY_CURRENT_USER では現在ログイン中のユーザの設定を格納しています。

HKEY_USER以下の一致するユーザのキーへのリンクになっています。このことにより、HKEY_CURRENT_USERキー以下の設定を変更すると、HKEY_USERの該当するユーザの設定も変更されます。

これらの設定は"Document And Setting"の各ユーザの下のNTUSER.DATとUSRCLASS.DATに格納されています。

Windows7の場合はフォルダオプションで「保護されたオペレーティングシステムをファイルを表示しない」のチェックをはずしてC:\Users\名前の直下にあります。

なお、サービスプログラムはHKEY_CURRENT_USER以下のレジストリに通常アクセスすることはできません。

（ImpersonateLoggedOnUserを使用してスレッドのユーザーを偽装すればアクセスが可能です。）

###HKEY_LOCAL_MACHINE (HKLM)
HKEY_LOCAL_MACHINE ではローカルのコンピュータの設定を保存します。

HKLMに含まれる４つのサブキー SAM,SECURITY,SOFTWARE,SYSTEMは%systemRoot%System32\configのフォルダ中に実際のファイルが存在します。

HARDWAREに関しては揮発性でファイルとして、その情報をファイルに保存していません。ハードウェアのドライバとサービスについての情報はSYSTEM以下に格納します。 

##値
 値は名前とデータをペアにしてキーに格納します。値の名前にバックスラッシュを含めることは可能ですが、辞めましょう。識別が困難になります。

値にはいくつかの型が存在します。

下記に主な型の例を示します。 

|Name|説明|
|:---|:---|
|REG_SZ|NULL で終わる文字列です。Unicode 版の関数を使っているときは Unicode 文字列、ANSI 版の関数を使っているときは ANSI 文字列が格納されます。|
|REG_BINARY|バイナリー値|
|REG_DWORD|32ビットの数値|
|REG_QWORD|64ビットの数値|
|REG_MULTI_SZ|複数行の文字値。NULL で終わる複数の文字列からなる 1 つの配列です。配列の最後にもう 1 つの NULL 文字が追加されます。|
|REG_EXPAND_SZ|環境変数の展開前の表記（"%PATH%" など）を保持している、NULL で終わる文字列です。Unicode 版の関数を使っているときは Unicode 文字列、ANSI 版の関数を使っているときは ANSI 文字列が格納されます。環境変数の表記を展開するには、ExpandEnvironmentStrings 関数を使ってください。|


レジストリのキーから値を含めた構成をハイブ(Hives)と呼びます。 

```
 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerNam\ComputerName
```

キー 	HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName
値 	ComputerName

#レジストリの編集方法
レジストリの修正は慎重におこなってください。

##手動
レジストリエディタで参照、編集が行えます。
コマンドラインからregeditを実行してください。
なお、使用には管理者権限が必要です。 

##regファイル
 regファイルをテキストエディタで作成することにより、レジストリの操作を対話なしで行うことができます。詳細は下記の記事を参考にしてください。

http://www.atmarkit.co.jp/fwin2k/win2ktips/1119wrtregfil/wrtregfil.html

#アプリケーション設計のヒント
##インストーラーの方針
インストーラーが書き込むレジストリはHKEY_LOCAL_MACHINEのみにするべきです。

なぜならば、Windowsのユーザーが追加される可能性があるからです。

アプリケーションの実装として、HKEY_LOCAL_MACHINEの値はHKEY_CURRENT_USER の値が存在しない場合に利用するようにします。

これにより、Windowsユーザの追加に対応できます。

##アプリケーションの方針
管理者権限のない場合、HKEY_LOCAL_MACHINEなどマシン全体に影響を与えるレジストリへの書き込みは制限されます。

このため、基本的に書き込みが必要な情報はHKEY_CURRENT_USER に行ってください。

また、USBに入れて持ち運ぶ等のインストール不要で動作することが目的の場合、レジストリを使用してはいけません。

##サイズ
レジストリエントリの長さは、利用可能なメモリによって制限を受けます。長いレジストリエントリ（2,048 バイトを超えるもの）はファイルに格納し、レジストリでそのファイル名を格納するべきです。
この結果、レジストリの効率を向上させるのに役立ちます。アイコンやビットマップなどアプリケーションの要素も同様にファイルに格納し、レジストリに直接格納することを避けてください。

##セキュリティの方針
パスワードやクレジットカードの番号などの機密情報の扱いを行う場合、他のユーザから見られないように暗号化を行うべきです。

CryptProtectData/CryptUnprotectDataを使用することにより、暗号化を行うことが可能になります。

このAPIで作成した暗号文は同じユーザーでなければ復号することができません。

 __CryptProtectData Function__ 
http://msdn.microsoft.com/en-us/library/aa380261.aspx
※Win2Kでも使えますがszDataDescrを指定してください。

 __CryptUnprotectData Function__ 
http://msdn2.microsoft.com/en-us/library/aa380882(VS.85).aspx 

#レジストリ操作のAPI
|Name|説明|
|:---|:---|
|RegCloseKey |指定されたレジストリキーのハンドルを閉じます。RegCloseKey関数が制御を返した時点で、必ずしもレジストリへの情報の書き込みが完了したとは限りません。キャッシュの内容をハードディスクへがフラッシュする（書き込む）まで、数秒かかることがあります。レジストリ情報をハードディスクに明示的に書き込むにはRegFlushKey関数を使います。ただし、この関数は多くのシステムリソースを消費するので、どうしても必要な場合にのみ呼び出してください。|
|RegConnectRegistry |ほかのコンピュータ上の定義済みレジストリハンドルとの接続を確立します。|
|RegOpenKeyEx |指定されたレジストリキーを開きます。|
|RegCreateKeyEx |指定されたレジストリキーを作成します。そのキーが既に存在している場合、そのキーを開きます|
|RegQueryInfoKey |指定されたレジストリキーに関する情報を取得します。|
|RegQueryMultipleValues |開いているレジストリキーに対応する値名のリストのタイプとデータを取得します。|
|RegDeleteKey |1 つのサブキーを削除します。<BR>キー名の途中でNULLがまざっているとこのAPIでは消せないようです。その場合は、下記のツールを使用して消してください。<BR>RegDelNull<BR>http://technet.microsoft.com/ja-jp/sysinternals/bb897448|
|RegDeleteValue |レジストリの指定されたキーから、指定されたレジストリエントリを削除します。|
|RegQueryValueEx |指定されたレジストリキーに所属している、指定されたレジストリエントリのデータ型とデータを取得します。|
|RegEnumKeyEx |指定された 1 つのレジストリキーのサブキーを列挙します。この関数を 1 回呼び出すたびに、1 つのサブキーに関する情報を取得します。|
|RegReplaceKey |指定されたレジストリキーとそのすべてのサブキーの裏付けとなっている 1 つのファイルを、他のファイルへを置き換えます。システムを次に再起動すると、キーとすべてのサブキーに、新しいファイルに格納されているレジストリエントリが割り当てられます。|
|RegRestoreKey |指定されたファイル内のレジストリ情報を読み取り、指定されたキーを上書きコピーします。このレジストリ情報で、キーとそのすべてのサブキーを指定します。|
|RegEnumValue |指定された 1 つのレジストリキーに所属するレジストリエントリを列挙します。この関数を 1 回呼び出すたびに、1 つのレジストリエントリの名前とそれに対応するデータ（レジストリエントリのデータ）を取得します。|
|RegSaveKey |指定されたキーと、そのキーに所属するすべてのサブキーとレジストリエントリを新しいファイルに保存します。|
|RegFlushKey |指定されたキーのすべての属性を、レジストリに書き込みます。キーに変更を加えた場合でも、RegFlushKey 関数を呼び出す必要はありません。レジストリに変更を加えた後、レジストリの遅延フラッシュ（遅延書き込み）機能がその変更結果をディスクへ書き込みます。また、システムのシャットダウン時にも、レジストリの変更結果がフラッシュされます。|
|RegSetKeySecurity |既に開いているレジストリキーのセキュリティを設定します。|
|RegGetKeySecurity |既に開いているレジストリキーを指定し、そのキーを保護するセキュリティ記述子のコピーを取得します。|
|RegSetValueEx |指定されたレジストリキーに所属する、指定された 1 つのレジストリエントリのデータとデータ型を設定します。|
|RegNotifyChangeKeyValue |指定されたレジストリキーの属性または内容が変更されようとしているときに、そのことを呼び出し側へ通知します。指定されたキーが削除されようとしているときは、呼び出し側への通知を行わないことに注意してください。|
|RegLoadKey |HKEY_USER または HKEY_LOCAL_MACHINE の下にサブキーを作成し、指定されたファイル内の登録情報をそのサブキーに格納します。この登録情報は、ハイブ形式で指定しておきます。ハイブとは、レジストリのツリー構造のルートのすぐ下にある HKEY_USER などの枝の総称であり、この中にキー、サブキー、レジストリエントリという個別のオブジェクトが存在しています。ハイブには、1 つの行と 1 個の .LOG ファイルが対応しています。呼び出し元のプロセスに、SE_RESTORE_NAME 特権を割り当てておかなければなりません。|
|RegUnLoadKey |指定されたキーとそのサブキーを、レジストリから削除します。呼び出し元のプロセスに、SE_RESTORE_NAME 特権を割り当てておかなければなりません。|

#監視用ツール
レジストリの読み書きの監視はProcess Monitorでリアルタイムに監視できます。
http://technet.microsoft.com/ja-jp/sysinternals/bb896645

#参考
 __インサイド MS WINDOWS 上 (マイクロソフト公式解説書)__ 
http://www.amazon.co.jp/exec/obidos/ASIN/4891004738