Wine:DLL の置き換え

DLL の置き換え
Wine では、Windows システムの各 dll ファイルは、独自に作成されています。
それらは通常の Windows と同じように、Wine prefix 上の c:/windows/system32(syswow64) に相当する場所にコピーされています。

通常の動作においては、これらの、Wine が作成した dll を使えば問題はありません。
ただし、実行するソフトによっては、実際に Windows で使われる dll ファイルを用意して、それを使わなければならない場合があります。
特にゲームにおいては、DirectX の dll ファイルが必要になる場合があります。

Wine prefix 上に dll ファイルが存在しているので、そのファイルを置き換えれば良いと思うかもしれませんが、それだけでは不十分です。
Wine において、dll の置き換え設定を行う必要があります。
dll を置き換えなくても良い場合
場合によっては、ソフトの exe と同じ場所に、対象となる dll ファイルを置くだけで、動作するケースがあります。

実行された exe と同じディレクトリに、対象の dll ファイルがある場合は、それが優先的に読み込まれ、見つからなかった場合は、システムの .../windows/system32 などから検索されます。

そのため、一般的な dll では、exe と同じ場所に置いておけば、dll の置き換え処理は必要ありませんが、DirectX などの dll では適用されない場合があるので、その時は、Wine prefix 内の dll を置き換える必要があります。
Wine prefix の更新時
Wine のバージョン変更などによって、Wine prefix が更新される時は、各 dll ファイルが、現在の Wine のバージョンのもので上書きされます。

ただし、Wine の方で dll 置き換えの設定があり、「n (native)」が設定されている dll ファイルは、上書きされず、そのまま残ります。

そういったことから、Wine prefix の更新時に dll を上書きされないためにも、dll 置き換え設定は必要になります。

逆に言うと、dll 置き換えの設定をしていない場合は、dll ファイルを別のものに変えても、Wine prefix 更新時に、ファイルが元に戻ってしまいます。
これを利用すると、dll の置き換え設定を削除して、Wine prefix を更新すれば、上書きしてしまった dll を元のファイルに戻すことができます。
dll ファイルを置く場所
置き換えたい dll ファイルは、Wine prefix 内の指定ディレクトリにコピーする必要があります。

# 32bit 環境時

[wine prefix]/drive_c/windows/system32

# 64bit 環境時

64bit dll : [wine prefix]/drive_c/windows/system32
32bit dll : [wine prefix]/drive_c/windows/syswow64

32bit/64bit どちらの環境でも、そのビット版の dll ファイルは、system32 に置きます。
64bit 環境で 32bit 版の dll を使う場合は、syswow64 に置きます。

64bit 環境の場合、ディレクトリ名の数字が、dll のビット数と合っていないため、紛らわしいので、注意してください。
ファイル名の注意点
Windows 上では、ファイル名の大文字小文字は区別されないため、D3D9.dll と d3d9.dll は同じファイルとして扱われますが、Linux 上ではファイル名の大文字小文字は区別されるため、D3D9.dll と d3d9.dll は別のファイルとなります。

Wine prefix 上では、d3d9.dll のように、dll のファイル名はすべて小文字になっていますが、ここに D3D9.dll というファイルをコピーすると、2つのファイルが存在してしまうことになるので、注意してください。

置き換えたい dll ファイルの名前は、Wine prefix 上に存在する dll ファイル名と全く同じにしてから、コピーしてください。
dll の置き換え設定: 環境変数
Wine 上の dll 置き換え設定を、環境変数で行いたい場合は、WINEDLLOVERRIDES で指定します。
主に、特定のコマンドで一時的に変更したい場合に使います。

例えば、d3d9.dll を、Wine prefix にコピーした dll に置き換えたい場合、以下のようにします。

$ env WINEDLLOVERRIDES='d3d9=n' wine ...
指定方法
WINEDLLOVERRIDES='name[,name2...]=[var,[var-failed]];...'

まず、name は、ファイル名 (dll の場合、拡張子の .dll は省略可) です。
カンマ (',') で区切って複数指定すると、複数のファイルで同じ値を指定することができます。

'=' の後には、値を指定します。

なし(省略)dll を無効にする
b(buildin) Wine 内臓の dll を使う
n(native) Wine prefix 内の dll を使う

値をカンマで区切って複数指定すると、前の値が失敗した時に使われる値となります。
"n,b" なら、Wine prefix 内の dll を優先して使うが、失敗したときは Wine 内臓の dll を使う、ということになります。

';' で区切ると、新しい name=val の設定となります。
Wine prefix の更新時は、mono や gecko をインストールするかどうかを聞かれますが、これを無効にしたい場合は、以下のようにします。

WINEDLLOVERRIDES='mscoree,mshtml='

mscoree.dll と mshtml.dll を値なしに設定することで、無効化します。
dll の置き換え設定: winecfg
GUI で dll の置き換え設定を行いたい場合は、winecfg で設定します。

まず、「ライブラリ」タブを選択してください。

「ライブラリの新規オーバーライド」の部分に、置き換えたいファイル名 (.dll は省略可) を入力し、「追加」ボタンを押します。

デフォルトで、「ネイティブ、内蔵版 (n,b)」 の値が設定されて、追加されます。
この場合、Wine prefix 内の dll を優先して使い、失敗した場合は Wine 内蔵版を使う、ということです。

値を変更する場合は、リストから名前を選択して、「編集」ボタンを押します。
dll の置き換え設定: レジストリ
Wine の dll 置き換え情報は、Wine prefix 内のファイル user.reg に、レジストリとして記録されています。
そのため、レジストリを編集することで、設定することもできます。

dll 置き換えの数が多い場合は、レジストリファイル (*.reg) を作ってレジストリ値を定義し、それを regedit で登録させると、便利です。
レジストリの場所と値
# dll 置き換えのレジストリキー
HKEY_CURRENT_USER\Software\Wine\DllOverrides

このキー内に、置き換える dll の値をそれぞれ設定します。

各項目の名前はファイル名 (.dll は省略可)。
データは文字列で、環境変数 WINEDLLOVERRIDES で設定するのと同じ値を指定します。
(n = native, b = builtin, 空 = 無効)
レジストリファイルを作る場合
例: dll.reg
REGEDIT4

[HKEY_CURRENT_USER\Software\Wine\DllOverrides]
"d3d8"="n"
"d3d9"="n"

このように記述して、regedit で登録します。

$ regedit -s dll.reg
DirectX の dll を抽出する
Wine でゲームを動かす場合、実際の DirectX の dll ファイルが必要になることがあります。

winetricks のスクリプトを使うと、各種ファイルを自動でダウンロードして、インストール、またはファイルをコピーして Wine 上の設定をしてくれます。

しかし、DirectX のランタイムの場合、95 MB くらいあるファイルをダウンロードして、そこから抽出することになるので、Wine prefix を何度か作って、その度に dll を適用させる必要がある場合、毎回 winetricks を実行するのでは、時間がかかります。

winetricks は、ダウンロードしたファイルをキャッシュ (~/.cache/winetricks) に保存するので、2回目以降は、そこにファイルがあれば、それを使います。

何度も使うようなファイルの場合は、自分でダウンロードして抽出しておけば後々楽になりますし、もしもランタイムがダウンロードできないような状態になっても、ファイルを残しておけば、手動で適用することができます。

ここでは、DirectX のランタイムから、ファイルを抽出する方法を説明します。
DirectX ランタイムのダウンロード
Microsoft のページから、DirectX ランタイムをダウンロードします。

必要なのは、「DirectX End-User Runtimes (June 2010)」です。
「directx 2010 june」で検索すれば、見つかります。

ここには、DirectX 11 までの dll ファイルなどが含まれています。
ファイルの展開
ダウンロードした exe を実行すると、自己解凍でファイルが展開されます。

中にはセットアップ用の DXSETUP.exe がありますが、今回はインストールせずに、各 cab ファイルから直接 dll を抽出します。
cabextract
cab ファイルを展開するために、cabextract が必要です。
7-zip でも展開はできますが、こちらの方が便利なので、パッケージをインストールしてください。

# パッケージ名
Arch Linux,Ubuntu: cabextract
cab ファイルから dll のみを展開
必要なのは dll ファイルだけなので、各 cab ファイルから dll だけを抽出します。

展開した先の cab ファイルがあるディレクトリ上で、以下のコマンドを実行します。

$ mkdir dll32 dll64
$ cabextract -L -F '*.dll' -d dll32 *_x86.cab
$ cabextract -L -F '*.dll' -d dll64 *_x64.cab

-L,--lowercaseファイル名を小文字にします
-F,--filter <pat>パターンにマッチするファイルのみ抽出
-d,--directory <dir>出力ディレクトリ

cab ファイル名は、32bit 版が x86、64bit 版が x64 となっています。
dll32, dll64 のディレクトリを作成して、各 cab ファイルから dll ファイルのみを抽出しています。

※ dll32 内の "microsoft.directx*.dll" のファイルは必要ないので、削除してください。
dll 置き換えの設定を行う
まずは、置き換えたい dll ファイルを、必要なファイルのみ Wine prefix 内にコピーしてください。
(dll32 にあるのが 32bit 用、dll64 が 64bit 用です)

その後、dll 置き換え設定を行う必要があります。

複数の dll ファイルの置き換えを自動で行いたい場合、以下のシェルスクリプトを使って set.reg ファイルを作成し、それを regedit で登録すると、便利です。

※カレントディレクトリに、置き換えを行いたい dll ファイルだけを置いた状態で、実行してください。
※拡張子は小文字の .dll になっていること。

<dllreg.sh>
#!/bin/sh

cat - << _TXT > set.reg
REGEDIT4

[HKEY_CURRENT_USER\\Software\\Wine\\DllOverrides]
_TXT

for f in *.dll;do
    echo "\"${f%.dll}\"=\"n\"" >> set.reg
done

## set.reg の生成
$ sh dllreg.sh
## set.reg の内容を登録
$ regedit -s set.reg
(備考) インストーラからファイルを抽出
7-zip を使うと、*.exe, *.msi などのインストーラファイルから、直接中身のファイルを抽出できる場合があります。

インストールせずに dll だけ取得したい場合は、試してみてください。

## ファイルリストを表示
$ 7z l <file>

## 展開
$ 7z x [-oDIR] <file>

-o: 出力ディレクトリ。-o と DIR の間に空白は置かない。