WindowsのPATHが長すぎる件

Windows環境でいろいろ開発ツールを入れてると Pathが長くて編集もしにくいし、
制限を超えてしまうとインストーラーが動かなかったりと結構困る事が多い。

PATHを短くするための工夫等をいくつか。

シンボリックリンクの利用

C:\Program FilesとC:\Program Files (x86)へのシンボリックリンクを作って
アプリケーションのインストールにはそちらを指定するようにします。

私は CMD.exeを起動して

C:\Users\USERNAME>CD /D C:\
C:\>mklink /D Apps "Program Files"
C:\>mklink /D Apps32 "Program Files (x86)"

としてC:\Apps と C:\Apps32 を代わりにインストール時に指定するようにします。

シンボリックリンクをわざわざ使って結局同じ場所にインストールする理由は C:\Program Files\をハードコードしちゃってるような ソフトもたまにあって、それらとの互換性を保てるからです。

バッチファイルを作る

コマンドライン用のツールを 普段自分は C:\tools\bin という場所に置くようにしています。

C:\tools\bin は Pathを通してありますので、単純に .exe だけといったツールは全部そこに置いています。

ただ、少し大きなアプリケーションになると、実行ファイルだけというわけにもいかないので、
そういう場合、C:\tools\binに バッチファイルを作る様にしてます。

たとえば、CMakeを入れたい場合、CMake.orgから
.ZIP形式を Downloadしてきて C:\tools\cmakeにファイルを全て展開します。
C:\tools\cmake\binを pathに通しても良いのですが、cmakeの実行ファイルは以下の5つだけです。

  • cmake-gui.exe
  • cmake.exe
  • cmcldeps.exe
  • cpack.exe
  • ctest.exe

対応するバッチファイルを C:\tools\bin以下に置いてやる事にします。
CMAKEを展開したパスは環境変数 CMAKEDIRに設定しておいて、

@SETLOCAL
@SET PATH=%CMAKEDIR%\bin;%PATH%
@%CMAKEDIR%\bin\%~n0.exe %*

これを それぞれ cmake.cmd cmake-gui.cmd cmcldeps.cmd cpack.cmd ctest.cmd としてパスの通った場所に保存しておけばOKです。

コマンドが多い場合は諦めてPATHに書くようにしますが、この様にコマンドが少ない場合は ちょっとしたバッチファイルを書く事で、
PATH設定が長くなるのを防ぐ事が出来ます。

msysGit portable版を使う場合の設定

gitは他のコマンドラインツールに大きく依存しています。

このため gitを Windows環境で動かすには かなりたくさんの.exeファイルが導入されている必要があります。

portable版のmsysgitは 必要になるexeを全て同梱する事で ノーマルなWindows環境でも gitを利用しやすくしています。

インストールにあたって単純にmsysgitのzipを展開して binをPATHに通してやっても良いのですが、この場合 他の多くのコマンド群も一緒にPATHの通った場所に置く事になってしまいます。
このために、gitが必要とする環境と、ユーザが使いたい環境でコンフリクトしてしまう事も多いかと思います。

msysgitの中に含まれる git-cmd.cmdというバッチファイルから、「gitが使えるコマンドプロンプト」を起動してやることも可能ですが、これだとコマンドプロンプト毎に環境が変わってしまうため、ミスオペの元になったりします。

この場合、msysgitの中の binではなく、cmd に PATHを通す事で gitと、gitk、start-ssh-agentコマンドだけを利用する事が可能になります。

更にPATHを新規に通す事を避けたい場合は msysgit/cmd/git.exe に対するバッチファイルをPATHの通った場所に置いてやる事で回避が可能です。

私の環境ではgitだけ使えれば十分なのでGITDIRをユーザ環境変数で設定して、以下のバッチファイルをgit.cmdとしてPATHの通った場所に置くようにしています。

@setlocal
@set PATH=%GITDIR%\bin;%GITDIR%\mingw\bin;%PATH%
@set HOME=%USERPROFILE%
@set PLINK_PROTOCOL=ssh
@set GIT_SSH=C:\tools\bin\plink.exe
@set TERM=msys
@%GITDIR%\cmd\%~n0.exe %*

Intelさんの所業

だいたい こんなにPATHが長いのも Microsoftと Intelがいけない。

と、力を込めて言いたい感じ。特に Intelさん。

うちは 所謂 Ultrabook を使っているのですが、設定されているSystem Pathを見てみましょう。

  • C:\Program Files (x86)\Intel\iCLS Client\
  • C:\Program Files\Intel\iCLS Client\
  • C:\WINDOWS\system32
  • C:\WINDOWS
  • C:\WINDOWS\System32\Wbem
  • C:\WINDOWS\System32\WindowsPowerShell\v1.0\
  • C:\Program Files (x86)\Windows Live\Shared
  • C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86
  • C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64
  • C:\Program Files\Intel\WiFi\bin\
  • C:\Program Files\Common Files\Intel\WirelessCommon\
  • C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\
  • C:\Program Files\Microsoft SQL Server\110\Tools\Binn\
  • C:\Program Files\Intel\Intel(R) Management Engine Components\DAL
  • C:\Program Files\Intel\Intel(R) Management Engine Components\IPT
  • C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL
  • C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT

Applicationを Installする場所は Program Filesね! なんて、長くて空白を含む名前に決めちゃった Microsoftが悪いって気もするけど、
Intel\Intel(R)とか、x86 と x64の両方をPATHに登録するとか、挙句の果てには 変更不可 って、そりゃないよIntelさん。
更に、うちの環境では User環境変数と System環境変数の両方に WiFiの同じPathが通してあって明らかに不要なので User環境変数側からは消しました、、、。

これについては現状、リミットの2048バイトまでは、だいぶ余裕ができたので諦める事にしています(^^;。シンボリックリンクでPATH環境変数だけは そちらを使うのもありなんですけど、
サポートしないだなんだと言われているのを無理矢理帰るのはどうかなと思ったのが、理由です。

ちなみに、通常、Windows Applicationは System環境変数を汚さずに Registryに(HKLMやHKCU\Software\Microsoft\Windows\CurrentVersion\App Paths)に実行ファイルとpathを登録しておけば、
Win+Rからの実行や CMDからstart filenameで起動できるわけで、そちらが推奨です。

ただ、「他のアプリケーションと共有する事を前提とした」DLLをアプリケーションと一緒にインストールしたい場合は問題になります。

共有が必要無ければ アプリケーション(.exe)と同じ場所に突っ込んでおけばいいです。これなら Versionの問題も回避できて DLL Hellを防ぎやすいです。

共有がどうしても必要な場合、DLLのロードは App Pathsも効かないので 通常は Windowsのシステムに突っ込むか、PATHに登録するかの二択になると思います。
システムに突っ込む場合、「誰がそのDLLを入れたのか?」「誰がそのDLLを使っているのか?」「誰がそのDLLを削除すべきか?」という問題と、細かな Version差異による所謂DLL Hellが発生しやすくなるので、
PATHを通しておくのも手なのですが、結局Pathによる検索順序でDLL Hell状態になるので Applicationと同じディレクトリに入れない限りは五十歩百歩って感じです。

「アプリケーションの実行ファイルと同じ場所に必要なDLLを置く」「システム全体で共有したいDLLは DLLをインストールするだけの インストーラで別途インストールをかける(MSVCのRunTimeのように)」をとるようにしてくれれば、
こういう問題もわりと楽に解決できるんですけどね、、、。

Leave a Reply

Your email address will not be published. Required fields are marked *