あざらし Windows2000 Tips
|
Site Index
|
このページは、あざらしがWindows2000やWindowsXPを使用している時にハマったトラブルやその対処方法、いざという時の裏技などを(自分自身の為のメモという役目も兼ねて) 記録、公開していこうと思い、オープンしました。
情報の内容はかなりマニアックになると思いますので初心者向けではありませんが、今までWindowsNT4.0-WSを使っていてこれから Windows2000に乗り換える時や、Windows2000からWindowsXPに乗り換える時などには役に立つかもしれません。 ご注意
情報は今後、随時追加していく予定です。
|
Windows XP上にインストールしたVisual Studio 6.0を使ってプログラムのコンパイル〜リンクを行うと、Windows 2000上でコンパイル〜リンクした時とは異なったバイナリーコードが生成されてしまう
2002/5/25掲載
Windows 2000 のTIPのページですが、今回からはWindows XPの話題が出てきます。 あざらしも、先日から主な作業環境をWindows 2000から Windows XPへと、徐々に移行しております。 いきなりすべての環境をXPに切り替えてしまうと様々な問題が起きるであろうという事が、過去のマイクロソフトの仕事ぶりから容易に想像できますので、しばらくの間はデュアルブートで両方のWindowsをすぐに使えるようにしておくつもりです。
そうこう言っているうちに、早速イヤな問題が起こりました。
ここで述べる Visual Studio 6.0 (VC++)の生成結果が変わってしまう 件と、
次項で述べる Visual Studio 6.0 (VC++)のデバッガが長時間応答しなくなってしまう といった問題です。
まず、Visual Studio 6.0 の生成コードが以前と異なってしまう問題。
Windows NT4.0 から Windows 2000 にアップグレードした時にはこのような事は起きていませんでした。 しかし Windows XP に移行し、そこでコンパイル〜リンクを実行すると、まったく同じ設定のプロジェクトから生成した.EXEファイルや.DLLファイルのバイナリーコードが、NT,Win2000で行った時とは異なったバイナリーとなってしまうのです。
もちろん、生成された実行ファイルのヘッダ部分に含まれているコンパイル日時などは変わって当然ですが、そういった事では無く、関数のアドレスや格納される順番が両者で異なってしまいます。
まったく同じバージョンのコンパイラやリンカが、それをインストールして開発を行ったシステムのバージョンによって異なる結果(プログラム)を生成してしまうという事は、プログラマにとっては、とても困った問題です。 プログラマ自身がどんなに緻密にソースコードのバージョン管理を行っていたとしても、過去に顧客などに納品したプログラムコードと同じ結果を手元に再現できなくなってしまいます。
もうマイクロソフトの悪口は皆さんも聞き飽きていると思いますし、私も言い飽きましたので、
「マイクロソフト製品の品質はその程度のもの・・・」
と考え、当面は Windows2000とWindowsXPのデュアルブートでやっていくしかないな・・・と思っていたところだったのですが、ふと、WindowsXPでアップデートされた沢山のシステムDLLのうちのいずれかが悪さをしているのではないかと思いました(・・・・って、原因はそれしか無いのですけれど・・・・)。
そこで調査してみたところ、Visual Studio 6.0 に含まれている
LINK.EXE は、システムにインストールされている MSVCRT.DLL のバージョンによって、異なった結果を生成してしまう
という、イヤ〜〜〜な事実を発見しました。
当初はもっと奥深いところで互換性の問題を起こしているのだろうと想像していたのですが、意外にも(というか、やっぱり・・・)マイクロソフトお得意の「DLL地獄」の一種だったんですね。
「じゃぁ話は簡単! 古いMSVCRT.DLLをシステムディレクトリにコピーすれば良いのでは?」って思いがちですけれど、そうは問屋が卸しません。 WindowsXPにわざわざ新しいバージョンのMSVCRT.DLLを含めているという事は、当然、WindowsXPそのものが内部的に新しい方のMSVCRT.DLLに依存しているという事です。 もし古いもので置きかえてしまうと、きっとWindowsXPのあらゆる部分で動作がおかしくなってしまうでしょう。
参考: マイクロソフト曰く、DLL Hell は終焉したんだそうな・・・なんだかなぁ・・・ (@_@)
マイクロソフト純正のWindowsアプリ開発ツール自体がこのざまですから、それを使ってどんどんバージョンアップされているWindowsの部品やマイクロソフト製のアプリケーションは、作っているマイクロソフトの社員達がどうがんばったところで、正確なバージョン管理は望めません。 Windowsがバージョンアップの度にバグを大量に増やし続けている事への原因の一旦はここにあるのでしょう。
自分達の製品のバージョン管理とバグコントロールが思うように行えなくなってしまった彼らが最初にとった行動は、「 DLLCache なるディレクトリにマイクロソフト製の全DLLファイル数百個をあらかじめ準備しておき、もし誰かがシステムディレクトリなどのDLLファイルを新しいものや古いものに置きかえてしまったら、すぐにオリジナルのDLLで上書きコピーしてその更新をつぶしてしまう・・・」 などという、本来のDLLの発想と恩恵(メモリとディスクの節約、バージョンアップの単純化)から考えれば本末転倒な機能をWindowsに標準装備してしまった訳です。 もう素晴らしいとしか言いようがありません・・・(あぁ、またグチっぽくなってしまった・・すみません・・・)
どちらにしても、古いバージョンのMSVCRT.DLLをシステムディレクトリにコピーしていしまう事は問題があります。 しかし今回のLINK.EXEの件ならば、Side-By-Side DLL と呼ばれている(・・・これまた彼らが発明したもう一つの本末転倒な・・・)対処療法で解決できます。
対処方法:
Windows 2000時代 の MSVCRT.DLL (Windows2000-directory\system32\msvcrt.dll) を、 LINK.EXE と同じディレクトリ (Visual-Studio-directory\vc98\bin) にコピーし、更にそのディレクトリ内に LINK.EXE.local という名前の空の(ゼロバイトの)ファイルを作成する。
これだけでOKでした。 Visual Studio 6.0 (VC++) は、Windows 2000時代とまったく同じ結果を生成してくれるようになりました。 めでたしめでたし。
ちなみ、各OS で利用していた MSVCRT.DLL のバージョンを調べてみますと以下のようになっていました。
恐らくこの Version 7.0 は Visual Studio .NET 上で作成されたアプリケーションに対応しているバージョンだと思われます。 従って、例え Windows 2000上であっても、あるいは Windows 98/Me 上であっても、Visual Studio 6.0 と Visual Studio .NET を同時にインストールしてしまうと、Visual Studio 6.0 側の LINK.EXE の結果に影響が出てしまうという事なのでしょう。 Windows9Xシリーズでは、Windows 98 Second Edition から Side-By-Side-DLL 機能がサポートされているらしいです。
拝啓マイクロソフト様。 ちゃんとDLLのバージョン管理しましょうね。Visual Studio.NETが出たからって、世界中の開発者全員が一斉に開発環境を切り替えられる訳ではないのですよ。
Windows XP 上の Visual Studio 6.0 の VC++ でアプリケーションのデバッグを行っている時、ブレークポイントヒット時やデバッグ実行の終了時に、数十秒間にわったてデバッガが無反応になる
2002/5/25掲載
プログラム開発を行われている方ならばおわかり頂けると思いますが、デバッグ途中、頻数にデバッガが数十秒間も無応答になってしまうといった状態は、開発者やデバッグ者にとって、とてつもなく大きなストレスとなります。 修正→コンパイル→実行→修正・・・のサイクルを繰り返していると、5〜6サイクルに1回くらいは、この現象が起きていました。
最初はインストールしてあるWindowsのどこかが腐ってしまっているのかとも思い、何度かWindows XP のクリーンインストールや Visual Studio のインストールをやり直したり、あるいは色々なデバイスを無効化してみたりもしましたが、まったく治まりませんでした。 そして最後に疑ったのはIME関係。 XPでは新しく 「言語バー」 が導入されており、どうもこの言語バーとVisual Studio のデバッガの相性が良くないような気がしてきました。
言語バーの状態は、コントロールパネルの「地域と言語のオプション」から非表示にする事ができますが、言語バーのプログラム実体である CTFMON.EXE は、依然ログイン時に必ずプロセスとして自動的にロードされてしまいます。
この自動ロードを指定しているレジストリ ( HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run ) で CTFMON.EXEのロードを指定している部分を手で削除しても、次回Windows起動時には自動的に設定が復活してしまうところなど、 「このプログラム、ますます怪しい!」 と思いました。
私はATOKを使っており、MS-IMEも言語バーもまったく不要ですので、いっそのこと、この煩わしい CTFMON.EXE を、system32ディレクトリ と dllcacheディレクトリから削除してしまいました。 SFPが文句を言ってきますが、お構いなしにキャンセルしましたところ、デバッガの無反応はウソのように治まってしまいました。
まだこの状態で利用した時間はそれほど長くありませんので、本当にこれが原因だったかどうかははっきりとはわかりませんが、今のところは、デバッガもATOKによる日本語入力も安定して行えています。 同じ症状で悩まれている方は試してみて下さい。
[Ctrl]キーと [Caps Lock]キーを入れ替える
2001/1/24掲載
あざらしの左手には、[Ctrl]キーが[A]キーのすぐ左側にあるという事を前提にしたダイヤモンドキー操作やCtrl+Qシーケンスが完全にしみついてしまっており、現在の106/101キーボードの[Ctrl]キーの位置を、どうしても受け入れてくれません。 NEC PC-9801を長く使っていた方々の多くも、同じ意見をお持ちだと思います。
Win2Kを利用し始めてから現在までの一年余り、あざらしは [Ctrl]キーと[Caps Lock]キーを入れ替えるためだけに KeyLay2K というユーティリティを利用したり、あるいは i8042prt.sys にパッチを当てたりして対処を行ってきました。
しかしつい先ほど、Win2K自身 (実際には標準添付のキーボードドライバか、あるいはその周辺のドライバ) が、最初からキー配置の入れ替え機能を持っている事に初めて気付きました。 どうやら、WinNT4.0で既に対応していたみたいです。
#i8042prt.sysのパッチ当てに使った時間を返して欲しい・・・(;_;)
実際には、レジストリキー
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
の中に、値 Scancode Map を作成し、変更したい物理キーのスキャンコードと、変更後のスキャンコードを並べて書き込む事で、OSレベル(あるいはドライバレベル)でキー配置の交換を行ってくれます。
Windows 2000 Resource Kit には、この設定をGUIで行える remapkey.exe が含まれていますので、Resource Kit をお持ちの方は remapkey.exe を利用して下さい。
remapkey.exe がすぐに利用出来ない方は、以下の小さなレジストリファイルをダウンロードして実行し、Win2Kを再起動すると 左[Ctrl]キーと[Caps Lock]キーが入れ替わります。 (Administrator権限で実行して下さい)
左CtrlキーとCaps Lockキーを入れ替えるレジストリ設定ファイルをダウンロード (182バイト)
まぁこのくらいの事はOSレベルで対応していて当然ですよね。
9x系のWindowsではまったく対応していませんので、今後は是非対応して下さい。>マイクロソフトさん
2001/1/24追記: Windows 2000 サービスパック1 を適用する事で、この不具合は解決されます。
下記で述べている対策を既に実行済みで、かつサービスパックを適用されている場合には、対策で行った変更を元に戻しておく事をお奨めいたします。
( HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices
キー内に AUX="\DosDevices\COM1" を作成し直す )また、まだ下記の対策を行っていない場合でも、既にサービスパックを適用されている場合、あるいはこれから適用する予定がある場合には、下記の対策を実行する必要はありません。
症状:
WaveやMIDI、ビデオなど、マルチメディアを扱うアプリケーションは、起動時にWin2Kに含まれているWINMM.DLL というマルチメディアモジュールをロードしますが、どうもこの中にバグがあるようです。 WINMM.DLL を使用するアプリケーションに限り、NT4.0や9Xで実行した時に比べて2〜3秒ほど起動時間が長くなってしまっています。 (Win2K導入当初、一日に何百回も起動させる「秀丸エディタ」の起動時間が遅くてかなりイライラさせられました。現在は秀丸側に対処を入れたバージョンが上がっています。)
調査結果:
デバッガで追ってみると、WINMM.DLL は 起動するとなぜか必ず AUX.DLL という名前のファイルをロードしようとします(実際にはそんなものは存在しない)が、"AUX" は 組み込みデバイス名 "COM1" のエリアス名として定義されているため、Windowsは COM1 、つまり RS-232C をオープンして何やら行おうとしてしまいます。 COM1 ポートに何も接続されていなければ、その処理が完了するまで2〜3秒かかり、結果、アプリケーションの起動を遅らせているようです。
対策:
REGEDIT で
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices
キー内の AUX="\DosDevices\COM1" を削除し、Windowsを再起動します。 再起動後、"AUX"エリアスは効かなくなりますので、WINMM.DLLによるサーチ時間が短くなり、アプリケーションの起動も速くなります。
ただし、(まず存在しないとは思いますが)デバイス名"AUX" をハードコーディングしてしまっているような通信アプリ等は正常に動作しなくなるかもしれません。
Promise社のFastTrak66のドライブ上に
Win2Kをクリーンインストールできない
2001/1/24追記: 最新版のFastTrakのドライバーでは、この不具合が解決されています。
最新版のFastTrakのドライバーをフロッピーディスクにコピーしてWin2Kのインストール時に追加ドライバとして指定すれば、下記の対策は必要ありません。
症状:
Win2Kのインストールの最初の画面で追加SCSIドライバとしてFastTrak66の最新版ドライバを指定しているにもかかわらず、Win2Kインストール終盤では「ハードディスクにアクセスできない」というメッセージのブルースクリーンで止まってしまう。 以後は何度再起動しても同じ。
調査結果:
Win2KのCD-ROMにはFastTrak66のドライバは含まれていませんが、同Promise社のUltra66-IDEインターフェース用ドライバが含まれています。 Win2Kインストールの最初の画面で追加SCSIドライバとしてFastTrak66のドライバを組み込むと、インストール作業中はそのドライバが動作しますが、終盤のPnP検出で、
FastTrak66がUltra66と勘違いされUltra66用のドライバが組み込まれてしまい、以後Win2Kは一切RAIDにアクセスできなく
なってしまうようです。
対策:
次の手順でWin2Kをクリーンインストールします。
なお、FastTrak66を使用していると、Win2Kはスタンバイ・休止状態に入れなくなります。
Promiseのサポートに問い合わせましたが、そういう仕様だそうです。 理由は「RAIDはサーバー用だから・・・」ですって・・・今後に期待
FastTrak66とは・・・・Ultra-ATA66対応のIDEハードディスクを最大4台までRAID接続できるIDEインターフェースです。 値段は1万5千円前後と大変お買い得です。 カード側のハードウェアを最低限に絞り、RAID処理のほとんどをBIOS-ROM上とドライバ上のソフトウェアで実行するためこの値段が実現できているようです。(モノホンのSCSI-RAIDアダプタは十数万円〜数十万円します)
機能やRAID種類などは限定されていますが、ストライピングをPentium-IIIなど高速なマシンで使った場合、ハードディスクの読み書きが驚くほど高速になります。 素のIDEやSCSI-RAIDに比べると多少読み書き時のCPU負担が増えますが、付属のソフトウェアで負荷の微調整も行えます。
あざらしのパソコンでは、IBM製の7200回転のIDEハードディスクを4台つないで使っています。このハードディスク単体の平均読み書き速度は 20MB/Sec ほどですが、4台ストライピングすると、リード 66MB/Sec、ライト 33MB/Sec くらいにまで高速化されます。 「あれ、論理値(20x4=80)より遅いじゃん!」 とおっしゃられるかもしれませんが、実際のRAID処理には様々なオーバーヘッドが課せられますので、このくらいの速度がコンスタントに出るという事はストライピングとしては非常に性能が高いんです。 (NT/Win2Kのソフトウェアのストライピングなんて全然速くなりません)
ハードディスクを2台、3台、4台と増やしていくと、リードは台数に比例して速くなっていきましたが、ライトは2台から4台までずっと 33MB/Sec で変わりませんでしたので、どうもこの数値がPCIバス速度の限界のようです。(理論値は133MB/Sec)
ハードディスクの追加やWin2Kのバックアップ〜リストア等で
Windowsディレクトリのドライブ名がリセットされてしまい、
Win2Kが起動しなくなってしまった場合
状況:
前々から気になってはいるのですが、NT/Win2Kは カーネル部分は特定のファイルを示すのにドライブ名(C:とかD:)に依存しないように作られている(boot.iniで指定しているパーティション番号だけに依存)のに対し、ユーザーモード部分やサービスモジュールなどの多くがドライブ名に依存して組み込まれているという、中途半端な設計になっています。 ドライブ名は「コンピュータの管理」→「ディスクの管理」、あるいは「ディスクアドミニストレータ」で変更できるようになってはいますが、Win2Kでは起動ドライブ (C:) や Windows ディレクトリが存在しているドライブ名の変更はできなくなってしまいました。
もしドライブの交換やパーティションの切り直しでWindowsディレクトリのドライブ名が変わってしまった場合、boot.ini の編集だけ行っても、Win2K はログオン画面以降に進まなくなくなってしまいます。(ユーザープロファイルの場所がドライブ名付きの絶対パスでレジストリ内に保存されているのでログオンできないようです) このような場合、最悪、Win2Kを素からインストールしなおさなければならないのですが、次の裏技で正常な状態に戻せる可能性があります。
条件:
あらかじめWin2Kにネットワークカードがインストールされている事
必要なもの:
ネットワーク接続が可能なもう一台のNT4.0かWin2Kマシン
手順:
ここでは、ログオン画面で止まってしまっているWin2Kマシンの名前を "SICK" 、 健全に動作している側のマシンの名前を "HEALTHY" と仮定します。
SICKの「ログオン画面」の状態で、双方のマシンがネットワークで接続できている事をHEALTHY側から確認
(NET USE コマンドや「マイネットワーク」で確認可能)
HEALTHY側のコマンドプロンプトで
NET USE \\SICK\IPC$ /user:administrator PASSWORD
を実行し、HEALTHYからSICKのリソースにadministrator権限でアクセスできるようにしておく
HEALTHY側で REGEDIT を起動し、「レジストリ(R)」メニューから「ネットワークレジストリへの接続」で SICK を指定する
SICKのレジストリキー SICK\HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices を開く
このキー内にドライブ名割り当て一覧が
\DosDevices\X: = "パーティション情報 " (X:ドライブは"パーティション情報"で示されるパーティションに割り当てられますよ・・・)
という形式で格納されているので、ドライブ名部分(X:の部分)のリネーム、もしくは"パーティション情報"内容の交換等で、Windowsディレクトリのあるドライブ名が元通りになるよう、編集する
例えば、以前Windowsディレクトリのあったドライブ名が "D:" で、現在Windowsディレクトリのあるドライブ名が "E:" になってしまっていて、これらを交換したい場合は、
一旦 \DosDevices\E: を \DosDevices\EE: などにリネーム
\DosDevices\D: を \DosDevices\E: にリネーム
\DosDevices\EE: を \DosDevices\D: にリネーム
という手順で行います。 (「名前の変更」では、既存の値の名前を新しい名前に指定できませんので、上の様な手順を踏む必要があります)
SICKのログオン画面でWin2Kを再起動させる (権限の関係で再起動が行えない場合はパソコンをリセットするしかありませんが、その際、レジストリを変更してからある程度(1〜2分)待ってからリセットして下さい。でないと、レジストリキャッシュがディスクにフラッシュされず、変更結果が再起動後に反映されない場合があります)
ご意見ご要望は aza@wg7.com まで