レジストリの小技


--- 準備編 ---

Windows3.1にもレジストリは存在しますが、実質的にはWindows95から始まったと言ってもいいでしょう。中にはレジストリという言葉だけで敬遠してしまう人もいるかも知れませんが、そんなに難しく考える必要はありません。レジストリとは簡単に言うとINIファイルを拡張したものです。拡張された点として

各ソフトウェアがばらばらに管理していたものを一元管理することで
・マルチユーザーに対応した
・一括してバックアップ・リストアが可能となった

エディターで簡単に変更できるINIファイル形式を独自の形式にすることで
・不慣れなユーザーによる誤操作の危険を回避した
・階層構造となった
・バイナリデータを扱えるようになった
・64キロバイトの制限がなくなった

リモート操作を可能にすることで
・ネットワークに対応した

などがあげられます。ただ現時点ではINIファイルと混在した状況にあり、ユーザーやソフトウェアがレジストリに慣れINIファイルとの区別を厳密に行えるまでには、まだ時間がかかりそうです。レジストリを操作するにはそれ相応の予備知識と覚悟が必要です。

レジストリ操作の鉄則

バックアップを細めに取る
レジストリエディターの画面上の操作はやり直しは効かないものと思った方がいいでしょう。またレジストリの変更後かなりの時間が経ってから思わぬ副作用を起こすことがあります。誤って変更・消去した場合に備えてバックアップは細めに取りましょう。
書籍等の記述はレジストリの変更は考慮していません。自分の環境が標準の状態とどこがどう違うかは常に認識しておく必要があります。また、なんらかの理由でWindows95を再インストールした場合、レジストリの変更をもう一度最初から行う必要があります。このようなことを考慮して、いつ何をどう変更したかの履歴を取っておくことをお勧めします。

バックアップ方法は一つではない
バックアップ作業は通常レジストリエディターを使いますが、これは必要な項目を拡張子REGのテキスト形式のファイルに保存するものです。全部の項目を保存することも可能ですが、これには落とし穴があります。ある時点で全項目を保存し、その後項目の追加があったたとします。追加した項目に問題があり元の状態に戻したいとき、以前のものをリストアしても追加した項目は削除されません(私はこれで痛い目にあいました)。
レジストリデータは、実は\Windowsフォルダー内のSYSTEM.DAT及びUSER.DATの2つのファイルそのものです。レジストリを丸ごと保存するならこの2つのファイルを保管するほうが確実です。ただし、通常モードではOSが頻繁にこのファイルにアクセスするため、この作業はセーフモードで起動し直してから行う必要があります。
また、Windows95にはCfgBackというツールが付いています。詳細は省略しますが、レジストリのツボがわかってきたら充分利用価値があります。

Windows95が起動しなくなる恐れもある
場合によってはWindows95が起動しなくなることもあります。Windows95さえ起動しないならこれで終わりだと判断するのは早すぎます。実は、MS-DOSモードのコマンドラインからでも、レジストリの一括バックアップ・リストアは可能です。正常に動作していたときのデータをリストアすることで復活するかも知れません。

最悪の場合Windows95を最初から再インストールする
最後はここに行き着きますが、これはジョークではありません。いつ壊れても構わないテスト的な環境があれば理想ですが、そうでない場合は、これくらいの覚悟で臨みましょう。「虎穴に入らずんば虎子を得ず」です。



--- 実践編 ---

レジストリの実践編です。前回の準備編を読破して頂いた有り難い方々を対象に、あくまで私が実際に試した範囲で、実際にレジストリをエデットしてどの様な効果が得られるかという話をします。あまりにも危険なものや動作未確認のものは割愛させて頂きました。また、フリーウェア等でこれらの情報を簡単に変更出来るようにしたものがありますが、原理的には同じです。

エクスプローラで表示されるアイコンを実イメージに     難易度‥1 便利度‥1
キーHKEY_CLASSES_ROOT\Paint.Picture\DefaultIcon
"C:\WINDOWS\SYSTEM\cool.dll,41" → "%1"
これで固定だったビットマップのアイコンが、実際のイメージを縮小したものになります。ただしビットマップファイルの多いフォルダーへのアクセス速度が遅くなります。特にFDの場合は待ち切れないほど遅くなりますので注意して下さい。
 
使用者名の変更     難易度‥1 便利度‥2
キーHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
"RegisteredOwner"="旧名" → "RegisteredOwner"="新名"
コントロールパネル・システム・情報・使用者名がこれで変更されます。
 
プロダクトIDを調べる     難易度‥1 便利度‥2
キーHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
"ProductId"="????????????"
使用者名の変更とほぼ同じですが、プロダクトIDを変更する必然性はなく、書類にプロダクトIDを記入する場合などにCDがなくてもここを見ればわかる、ということです。もっとも、それだけのことならコントロールパネル・システム・情報・システムを見ても同じですが・・・。なお、PLUSがインストールされていれば "Plus! ProductId" にPLUSのプロダクトIDが保持されています。
 
デスクトップのアイコン非表示     難易度‥3 便利度‥1
キーHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer
"NoDesktop" 1(DWORD)を追加
これによりデスクトップのアイコンを非表示にできます。綺麗な壁紙を邪魔ものなしで見たい場合にはいいかも知れません。一部の書面には、これは危険なので行わないようにと注意書きがあります。私が試した限りでは何ら問題はありませんでしたが、危険を冒してまで行うほどの効果はありません。余談ですが、デスクトップのアイコンを非表示にしたら、パワートーイのデスクトップアイコンを常駐させておくと便利です。
 
タイムラグを無くす     難易度‥3 便利度‥2
キーHKEY_CURRENT_USER\ControlPanel\Desktop
"MenuShowDelay" 数値(DWORD) デフォルト400を追加
実はWindowsはこの数値によりスタートメニュー等の動きをただ遅らせているのです。ただあまり速くすると返って使い辛くなるので程良い数値を探して見て下さい。もちろん数値が小さいほど速くなります。
 
ペイントブラシの使用ファイルの履歴消去     難易度‥2 便利度‥1
キーHKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Applets\Paint\Recent File List
履歴ファイルの名前を削除
アプリケーションファイルの多くは履歴を残します。普段は便利ですが、何らかの理由により消したい場合もあります。ほとんどはINIファイルに書かれるのですが、ペイントブラシはレジストリに書かれます。従って、履歴の消去をするにはレジストリをさわる必要があります。
 
起動時の自動実行     難易度‥2 便利度‥3
キーHKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\run
自動実行するプログラム名
スタートアップにもなくWIN.INIにもないのに起動時に自動実行されるプログラムが95にはあります。ここに自動実行するプログラム名が書かれている場合です。スタートアップを利用しても同様の結果が得られますが、ショートカットが不要であることと、レジストリをさわらない限り変更されないといった利点があります。似たものに、次回起動時1回のみ実行される [KEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\RunOnce] があり、インストーラーなどはしばしばここを利用しています。



--- 応用編 ---

Windows95では、レジストリを自在に操作できれば大抵のことはできてしまいます。レジストリはわかってしまえばそれほど難しいものではないのですが、操作するのは大変面倒です。例えば「ペイントブラシの使用ファイルの履歴消去」の場合、まずレジストリエディタを起動し「HKEY_CURRENT_USER」の左側にある+の記号をクリックしてサブキーの一覧を出し、以下同様に「Software」,「Microsoft」,「Windows」,「CurrentVersion」,「Applets」,「Paint」,「Recent File List」と順番に辿って行き、ここで表示された項目の内のFILE1〜FILE4を選択し、Delキーを押して、確認のYを押す、これだけの作業をしたら、レジストリエディタを終了して完了です(読んでるだけでも疲れそうですね)。ここまでやって得られる結果が、ペイントブラシのメニューから履歴が消えるだけなら、「まあ履歴ぐらい残っていてもいいや」なんてことになりかねません。そこで今回は、お決まりの作業を実行ファイル化して、アイコンを1クリックするだけで済むようにする例を紹介します。ただし、これにはプログラミングの知識が必要になってきます。中には「難しい話はどうでもいいから御利益だけ欲しい」という方もいるかも知れません。そんな人のために、ここで紹介するものは、フリーウェアのコーナーで実行ファイルがダウンロードできるようにしておきます。
レジストリの操作は、基本的にレジストリエディタで行いますが、これは全て手動となります。自動で操作するには、レジストリ関連のAPIをコールすることになります。他にも、稼動中のレジストリエディタにメッセージを送る方法や\Windowsフォルダー内のSYSTEM.DAT及びUSER.DATの2つのファイルを直接書き換える方法も考えられなくはないですが、大変危険であり、また汎用性にも欠けるため、一般的ではありません。レジストリ関連APIの詳細については専門書に譲るとして、実際に利用するのは数種類です。Windows95になってレジストリが拡張されているため、作成と参照はデータの種類の指定に気を付ける必要があります。これらのAPIの使用方法を理解すれば、レジストリも思いのままです。
今回は、VC++4.0を使用します。コンパイルに関しては、Windows95用のCコンパイラであれば何でも構わないと思いますが、他のコンパイラでの確認はしていません。言語に関しても、特にC言語である必要はありません。バッチファイルで連続的に実行するならVCが、画面上で作業の設定をして実行するならVBがいいかと思います。

「ペイントブラシの使用ファイルの履歴消去」
#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) {
    HKEY hKeyResult = 0;
    long lRtn;
    char ErrMsg[64];
    
    lRtn = RegOpenKeyEx(HKEY_CURRENT_USER,
    "Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Paint\\Recent File List",
    0, KEY_ALL_ACCESS, &hKeyResult);
    if (lRtn != ERROR_SUCCESS) {
        sprintf(ErrMsg, "エラーが発生しました\n戻り値は%ld\n", lRtn);
        MessageBox( (HWND)NULL , ErrMsg, "RegOpenKeyEx" , MB_OK ) ;
        return 1;
    }
    RegDeleteValue(hKeyResult, "File1");
    RegDeleteValue(hKeyResult, "File2");
    RegDeleteValue(hKeyResult, "File3");
    RegDeleteValue(hKeyResult, "File4");
    RegCloseKey(hKeyResult);
    return 0;
}
プログラムの内容としては、指定サブキー内のFILE1〜FILE4を消去しているだけです。消去したい内容が元から存在しない場合はエラーが発生しますが、敢えて通知する必要もないため無視しています。注意すべき点は、ペイントブラシが起動時にレジストリの内容を読み込み、終了時に書き込んでいるため、ペイントブラシ稼動中にこのプログラムを実行しても意味がありません。ペイントブラシが稼動中でないことを確認の上実行して下さい。Windows95インストール後、ペイントブラシを一度も実行していない環境では、レジストリが存在しないためエラーになりますが、それ以外は、意図的にレジストリを壊さない限りエラーは起きないはずです。実はFILE1のみを消してもメニューから履歴が消えますが、これは一時的で、何か1つファイルを参照すると隠れていた履歴が再び表示されてしまうので、やはり4つ全てを消去すべきでしょう。
ワードパッド・EXCEL・パワーポイント・FTPエクスプローラなどもほぼ同様な方法で履歴を消去できます。



「Windows95のバグ修正」
#include <windows.h>
#include <stdio.h>

int WINAPI WinMain(HINSTANCE hThisInst, HINSTANCE hPrevInst, LPSTR lpszArgs, int nWinMode) {
    HKEY hKeyResult = 0;
    long lRtn;
    char ErrMsg[64];
    char PathCacheData[4] = {(char)0x40, (char)0x00, (char)0x00, (char)0x00};
    char NameCacheData[4] = {(char)0xA9, (char)0x0A, (char)0x00, (char)0x00};
    
    long PType, NType;
    long PReadSize = 64L, NReadSize = 64L;
    char PathCacheBuff[64];
    char NameCacheBuff[64];
    
    int Hantei;
    char *Tytle = "初期Win95 レジストリ情報修正ツール(サーバー)";
    lRtn = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
    "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\FS Templates\\Server",
    0, KEY_ALL_ACCESS, &hKeyResult);
    if (lRtn != ERROR_SUCCESS) {
        sprintf(ErrMsg, "エラーが発生しました\n戻り値は%ld\n", lRtn);
        MessageBox( (HWND)NULL , ErrMsg, "RegOpenKeyEx" , MB_OK ) ;
        return 1;
    }
    
    lRtn = RegQueryValueEx(hKeyResult, "PathCache", 0, &PType,
    (char *)PathCacheBuff, &PReadSize);
    if (lRtn != ERROR_SUCCESS) {
        sprintf(ErrMsg, "エラーが発生しました\n戻り値は%ld\n", lRtn);
        MessageBox( (HWND)NULL , ErrMsg, "RegQueryValue" , MB_OK ) ;
        return 1;
    }
    lRtn = RegQueryValueEx(hKeyResult, "NameCache", 0, &NType,
    (char *)NameCacheBuff, &NReadSize);
    if (lRtn != ERROR_SUCCESS) {
        sprintf(ErrMsg, "エラーが発生しました\n戻り値は%ld\n", lRtn);
        MessageBox( (HWND)NULL , ErrMsg, "RegQueryValue" , MB_OK ) ;
        return 1;
    }
    
    if (PReadSize != 4L || NReadSize != 4L || PType != REG_BINARY || NType != REG_BINARY) {
        Hantei = 0;
    } else if (!(memcmp((char *)PathCacheData, PathCacheBuff, 4)) &&
    !(memcmp((char *)NameCacheData, NameCacheBuff, 4))) {
        Hantei = 1;
    } else if (!(memcmp((char *)PathCacheData, NameCacheBuff, 4)) &&
    !(memcmp((char *)NameCacheData, PathCacheBuff, 4))) {
        Hantei = 2;
    } else {
        Hantei = 0;
    }
    if (Hantei == 0) {
        if (IDOK == MessageBox( (HWND)NULL , "ユーザー独自の設定になっています\n変更しますか",
        Tytle , MB_OKCANCEL ))
        Hantei = 2;
    }
    if (Hantei == 1) {
        MessageBox( (HWND)NULL , "既に修正済みです", Tytle , MB_OK ) ;
    }
    if (Hantei == 2) {
        lRtn = RegSetValueEx(hKeyResult, "PathCache", 0, REG_BINARY, (char *)PathCacheData, 4L);
        if (lRtn != ERROR_SUCCESS) {
            sprintf(ErrMsg, "エラーが発生しました\n戻り値は%ld\n", lRtn);
            MessageBox( (HWND)NULL , ErrMsg, "RegSetValue" , MB_OK ) ;
            return 1;
        }
        lRtn = RegSetValueEx(hKeyResult, "NameCache", 0, REG_BINARY, (char *)NameCacheData, 4L);
        if (lRtn != ERROR_SUCCESS) {
            sprintf(ErrMsg, "エラーが発生しました\n戻り値は%ld\n", lRtn);
            MessageBox( (HWND)NULL , ErrMsg, "RegSetValue" , MB_OK ) ;
            return 1;
        }
        MessageBox( (HWND)NULL , "レジストリ情報を修正しました", Tytle, MB_OK ) ;
    }
    
    RegCloseKey(hKeyResult);
    return 0;
}
Windows95の初期バージョンには、幾つかのバグがあり、その中に、レジストリの内容が逆になっているというものがあります。バグに対しては、マイクロソフト社が修正モジュールを無償配布するという形で対処していますが、私が知る限りでは、このバグに対する修正モジュールはありません。キャッシュメモリの設定がデフォルトなら何の問題もないため、あまり問題視されていません。ただ、バグが存在することを知りつつ放置するのは嫌なので、私はWindows95初期バージョンをインストールした後にはこの部分を修正するようにしています。そこで、これを自動で修正するプログラムを作ることにしました。
プログラムの内容としては、レジストリの内容をチェックし、未修整なら無条件に修正、修正済みならその旨を通知、それ以外の内容なら修正するかどうかの確認を取るようにしました。この例はサーバーですがモバイルにも同様のバグがあります。履歴消去などと違い、滅多に実行することは無いものですので、結果の表示に対する確認のクリックをするようにしています。ちなみに、このバグはOSR2では修正されています。


戻る