リンク/ジャンクション作成ツール

更新履歴

2012-03-17

Link Shell Extensionの対応について追記

2011-08-06 v1.06 ダウンロード

v1.05に同梱のドライバではリンク先が絶対パスで指定されたシンボリックリンクのサブディレクトリへ正常にアクセスできない(たとえば、C:\testへのリンクをD:\test2という名前で作成したとき、D:\test2\123へのアクセスがC:\test\123ではなくC:\testに読み替えられてしまう)問題を修正。Windows Vista/7ではこのドライバは不要なので関係ありません。また、アクセス時の問題なので旧バージョンで作成した絶対パスへのリンクを作成し直す必要はありません。

2006-09-10 v1.05

シンボリックリンクの作成時に、リンク先を相対パスで指定すると不正なリンクが作成されてしまう問題を修正。v1.04で作成されてしまった不正なリンクは、単にdelやrmdirで削除できます。v1.05で作り直してください。

ビルドで使うSDKをWindows Server 2003 R2 Platform SDKに更新。

2006-07-23 v1.04

Windows Vistaのシンボリックリンクに対応。Windows 2000/XP上で作成することもできます。必ず注意事項をご覧ください。

Windows 2000にはzip形式フォルダが標準で存在しないので、x86版の圧縮形式をcabに変更。

作成できるリンクはハードリンクだけではなくなったので「ハードリンク/ジャンクション作成ツール」から改名。

2006-06-17

Windows Vistaに関して説明を追記。

linkdコマンドの紹介としてWindows Server 2003 Resource Kit Toolsへのリンクを追加。

2006-01-07 v1.03

64bit版を作成。

どうせWindows 2000以降でしか動かないのでシフトJISにない文字を含むファイル名も扱えるようにUnicodeコンパイルに変更。

ビルド環境をWindows Server 2003 SP1 Platform SDK/Windows Server 2003 SP1 DDKに変更。

2004/08/18 v1.02

環境によってはntfs.sysの発見に失敗する問題を修正。この修正のためにファイルへのジャンクション作成では非公開APIを使うようになりました。

lzhだったので導入を断念したという声があるので圧縮形式をzipに変更してみた。ちなみに*.msiは「プログラムの追加と削除」を「別ユーザーで実行」すればAdministratorでログオンしなくてもインストールできます。

2003/08/30 v1.01

日本語のリンク先が表示されなかった問題を修正。

2003/01/01

Windows XPでも動作するようなので記述をいくつか追加・変更。ついでにリンク切れを修正。

これは何?

ハードリンクやジャンクションを作成するツールです(そのまんま)。v1.04から、Windows Vistaのシンボリックリンクにも対応しました。Windows 2000/XP上でシンボリックリンクを作成することもできます。

Windows 2000標準の付属品では、ハードリンクを作ることはできませんし、ジャンクションはドライブに対してしか張ることができません。

Windows XPではfsutilコマンドでハードリンクを作成できますが、Administrator権限のあるアカウントでしか使えません。実際にはWindows XPでもハードリンクを作成するためにAdministrator権限は必要ありません。おそらくfsutilコマンドの機能の中にAdministrator権限を必要とするものがあるためだと思われますが、一部の機能のためにコマンド全体を使用禁止にするとはなんとも手抜きな設計です。

そこで作成用のツールを作りました。

なお、Windows Vistaではmklinkコマンドで、カーネルがサポートしているあらゆる種類のリンクを作れるようです。

ハードリンク

UNIXにはハードリンクというものがあって、1つのファイルに複数の名前を付けることができます。ファイルの中身は共用して名前だけを増やすので、コピーした場合と比べて

などのメリットがあります。

ハードリンクは、Windows NTでは3.1の時代から使うことができました。

ジャンクション

これまたUNIXにはシンボリックリンクという機能があって、ファイルに別名をつけることができます(別名をつけることを「リンクを張る」と表現します)。ハードリンクとの違いは

Windows 2000/XPではファイルシステム(NTFS)にリパースポイントという機能が追加され、このリパースポイントを利用してジャンクションというシンボリックリンクに非常によく似た機能がサポートされています。

シンボリックリンク

ジャンクションは、UNIXのシンボリックリンクと比べると

のような制限がありましたが、Windows Vistaではこれらの制限をすべて解消した本物のシンボリックリンクが新たに導入されました。Windows Vistaのシンボリックリンクもリパースポイントによって実装されていますが、ジャンクションとはリパースタグ(リパースポイントの種類を識別する数値)が異なるため互換性がありません。

なお、このツールでアクセスした場合、ネットワークドライブやUNCパス上のリンクをたどれないという制限があります。Windows Vistaのシンボリックリンクにネットワーク経由でアクセスするには、SMB2を実装する必要がありますが、Windows XPはSMB2に対応していないためです。ただし、リンク先がネットワークドライブやUNCパスであるようなリンクでもリンク自体がローカルドライブにあればアクセスは可能です。

このツールとは関係ありませんが、Windows Vista/7でも既定では共有フォルダ上のシンボリックリンクは無効にされており、fsutilコマンドかグループポリシーの設定で有効にしない限り、ネットワーク越しのシンボリックリンクへのアクセスは「シンボリック リンクの種類が無効なため、リンク先に接続できません。」というエラーメッセージで失敗します。

ショートカット

Windowsのショートカットはリンク先が中に書かれた単なるファイルです。そのためハードリンクやジャンクションと比べると、

などの制約があります。

使い方

UNIXのlnコマンドとほぼ同じで、

>ln foo bar

でfooに対してbarという名前のハードリンクを作成します。

>ln -s foo bar

でfooに対してbarという名前のシンボリックリンクを作成します(v1.03以前と異なるので注意してください)。ジャンクションを作成するためのオプションは -j に変更されました。

注意事項

シンボリックリンクへのアクセス

Windows 2000/XPの標準でもWindows Vistaのシンボリックリンクを作成はできますが、作成したリンクをたどれません。そこでシンボリックリンクへのアクセスを提供するドライバ(symlink.sys)と、ドライバをロードするためのツール(senable.exe)を作成して同梱しました。v1.03以前の同名のドライバおよびツールとは全く別物です。

senable.exeは管理者権限を持ったユーザで実行する必要がありますが、ドライバをロードしてしまえば通常ユーザの権限でもシンボリックリンクにアクセスできます。

Windows Vistaでは当然ながらドライバは不要です。動作確認もしていませんし後述のようにドライバのロードは危険を伴うので、Windows Vistaではsenable.exeは使用しないでください。

Windows XP x64 Editionでは64bit版をご利用ください。32bit版のsenable.exeは正常に動作しません。

v1.03以前のドライバはntfs.sysにパッチを当てるとすぐにアンロードしていたので、パッチを当て間違えない限りそれほど危険はありませんが、v1.04からは常駐してNTFSボリューム上のすべてのファイルアクセスに割り込むようになったので、はるかに危険が増しています。ちょっとしたドライバのバグであっさりブルースクリーンが出てクラッシュしたり、最悪の場合書き込むファイルが片っ端から壊されていく可能性すらあります。どのような不具合が生じても当方は一切関知しませんので、symlink.sysドライバは自己責任でご利用ください。

すべてのファイルアクセスをフックするというドライバの性質上、ドライバをロードすると振る舞い検知するセキュリティソフトに警告される場合があるようです。

ハードリンクやジャンクションはドキュメントされた機能でドライバは使用しないので、全く問題なく利用できます。またWindows Vistaではシンボリックリンクの使用にドライバは不要なので、これも全く危険はありません。作成するだけならWindows 2000/XPでもドライバは不要なので、危険はありません(アクセスできなくてはあまり意味がないと思いますが)。

標準では、ドライバはWindowsを起動するたびにロードし直す必要があります。「senable install」でブート時にドライバがロードされるように登録することができますが、ドライバにバグがあってクラッシュしたらセーフモードでも起動できなくなります。最低でも、ふつうにロードして一通り動作を確かめてから登録するようにしてください。登録直後の再起動でクラッシュした場合は、電源投入時にF8を押して「前回正常起動時の構成」を選ぶことで復旧できるかもしれません。一度でも正常に起動した後でクラッシュするようになった場合は、当然この手は使えません。回復コンソールから復旧を試みるか、素直にリカバリしてください。

登録したドライバを削除するには、コマンドラインから「senable delete」と入力してください。ドライバがすでにロードされている場合は、Windowsを再起動するまで削除は完了しません。

ファイルに対するジャンクション

ジャンクションはフォルダに対してしか張ることができません。ファイルに対して張ろうとするとエラーになります。v1.03まではメモリ上のntfs.sysにパッチを当ててファイルへのジャンクションを作成する機能がありましたが、シンボリックリンクへの対応に伴いこの機能は廃止されました。

新規に作成はできませんが、ファイルへのジャンクションへアクセスするのにntfs.sysへのパッチは不要なので、作成済みのジャンクションへのアクセスは(Microsoftがntfs.sysの動作を変更していない限り)問題ないはずです。

その他

ジャンクションはWindows 2000からの新機能なので、Windows 2000/XP以降専用です。ハードリンクも、Windows 2000から追加された新関数を使って作成しているのでWindows 2000/XP以降でしか動作しません(この新関数を使わなくてもハードリンクは作成できるのですが、どうせWindows 2000/XP以降専用なので手を抜きました)。

シンボリックリンクはWindows Vistaからの新機能ですが、作成だけならWindows 2000以降で可能です。Windows 2000/XPでのアクセスには専用のドライバが必要です(シンボリックリンクへのアクセス参照)。

Windows Vistaでは標準でmklinkコマンドが存在するので必要ないと思いますが、いちおう動作します。蛇足ですが、mklinkコマンドの引数の順番はlnコマンドと逆なので注意してください。

コマンドライン用のツールです。コマンドプロンプトを見たことのないという方にはおすすめできませんというか使えないでしょう。ちなみにこれは単なる私の手抜きのせいなので、まともなGUIツールを誰かが作ってくれれば使えます。(2012-03-17追記)なんと、Link Shell Extensionの作者が対応してくださいました! 後述のWindows 2000/XPでの削除問題などもあるため、Link Shell Extensionをインストールしての運用を強くおすすめします。

Windows 2000では、異なるドライブに対してジャンクションを張ると、そのジャンクションの下にあるファイルやフォルダはエクスプローラから削除できません(ジャンクションを張った先の本来のパス経由なら削除できます)。これは実際には異なるドライブにあるものをごみ箱に入れようとして失敗するためです。ようするにエクスプローラのバグです。その証拠にWindows 2000純正の「ディスクの管理」を使って作成したマウントポイントでも同じ現象が発生しますし、コマンドプロンプトからは問題なく削除できます。(2003/01/01追記)Windows XPではこのバグは修正されましたが、ごみ箱へ入れるためにドライブ間でコピーを行うというかなり本末転倒な動作を行うようです。さらにドライブ間のごみ箱の容量の違いのために、削除に失敗することがある模様です。

Windows 2000/XPのエクスプローラはリンクの存在を認識しないので、ジャンクションやシンボリックリンクのフォルダを削除してごみ箱を空にすると、リンク先のファイルがすべて消え去ります。削除はコマンドラインからrmdirコマンドで行ってください。Windows 2000/XPでジャンクションを使用する場合には、リンク作成シェル拡張Link Shell Extensionなど、この問題に対策したツールのインストールをお勧めします。Windows Vista以降でこの問題は修正されました。

Windows NT/2000/XPでシンボリックリンクが利用できるという誤解

Windows NT/2000/XPでシンボリックリンクが利用できるという記述をよく見かけます。それはこのツールの説明かもしれませんし、上記のリパースポイント/ジャンクションについての説明である場合もありますが、単なる誤解に基づいたものもよく見かけます。そういう誤解について解説してみます。

なお、Windows Vistaでは本当にシンボリックリンクが使えます

ハードリンクとシンボリックリンクの区別がついていない

もっともよくあるパターンがこれです。なかには「シンボリックリンクをサポートしていないとPOSIX互換は名乗れないから」ともっともらしいことを書いているところもありますが、POSIXではハードリンクは規定されていてもシンボリックリンクは規定されていません。

たとえばシンボリックリンク作成シェル拡張メニューが作成するのは、実際にはハードリンクです(ただしWindows 2000/2003/XP版がディレクトリに対して張るのはジャンクションです。名前もリンク作成シェル拡張に変わっています)。

ジャンクションとシンボリックリンクを区別していない

Windows Vistaのシンボリックリンクが登場するまでは、ジャンクションのことをその類似性からあえてシンボリックリンクと呼ぶことがよくあったようですが、今となっては紛らわしいだけでしょう。

POSIX utilities

Windows NTのリソースキットに含まれるPOSIX utilitiesに付属のreadme.wriにはlnコマンドでシンボリックリンクを作成するための-sオプションが使えるかのようなことが書かれていますが、実際にはそんなオプションはありません。たぶんどこかのUNIXのマニュアルからコマンドの説明をろくにチェックもしないでパクっただけでしょう。

シンボリックリンクオブジェクト

Windows NT/2000のDDKを読んでいると、シンボリックリンクオブジェクトという言葉がしばしば出てきます。これはWindows NT/2000が内部で使用しているカーネルオブジェクトに対して張られるもので、デバイスドライバの開発者以外が目にすることはまずなく(だからDDKに書かれている)、UNIXのシンボリックリンクのようにファイルに対して張ることはできません。

IO_REPARSE_TAG_SYMBOLIC_LINK

Visual Studio 6.0のwinnt.hにはIO_REPARSE_TAG_SYMBOLIC_LINKといういかにもシンボリックリンクと関係ありそうな名前のマクロが出てきますが、これは実際には機能しません。Visual Studio 6.0が出た時点ではWindows 2000はまだNT 5.0と呼ばれていたβ2の段階だったので、その後削られたものと思われます。実際最新のプラットフォームSDKのwinnt.hからはこのマクロはなくなっています。

なお、Windows Vistaのシンボリックリンク用に新たに定義されたリパースタグ用のマクロの名前はIO_REPARSE_TAG_SYMLINKです。

逆リンク

Environments with Windows 2000 + Cygwin

Googleでこのページへのリンクを検索したら1件だけ引っかかった記念(ちなみに2005年12月17日現在11件)

(cmd.exe)
C:\>cd C:\Documents and Settings\All Users\スタート メニュー\Folder1 へのショートカット
C:\Documents and Settings\All Users\スタート メニュー\Folder1 へのショートカット>

(bash; Meadow shell-mode)
bash >cd "C:/Documents and Settings/All Users/スタート メニュー/Folder1 へのショートカット"
bash >pwd
c:/Documents and Settings/All Users/スタート メニュー/Folder1 へのショートカット
bash >

この場合はshortcutは完全にsymbolic linkとして機能しているように見える。 なぜすべての場所ではなくスタートメニューの中だけでこうなってるんだ? Windows shortcutは一体どういう仕様になってるんだ?さっぱりわからん。

そこでlsしてたらもう少しだけ謎が解けていたと思います。

Windows 2000ではhard linkの機能はない

ありますけど。Windows NT 3.1のころから。ていうかこのページを読んでるはずなのにどうしたらそういう摩訶不思議な結論に到達するのでしょうか。FAT32でフォーマットしてるとか?


Copyright© 1997-2011 M.Kimura(emk) 半角カナ使用者保護運動