Kitsune Gadget

気になったことをつらつらと

ChromeのCacheフォルダをシンボリックリンクで参照設定をバッチ化(したけどできなくなった)

別のディスクにキャッシュ置いたほうが、処理軽くならないかなぐらいの理由でChromeのキャッシュをたまに手動で変更していたのだけれど。 アップデートされるたびにどうやら元のフォルダに置き換わってしまうため、そろそろ設定を自動化できるようにしたかった。 ついでにバッチファイルがどんな感じで構成されてるのかも見てみたかったのでバッチファイルを作ることにしました。

追記: Chromeを起動すると新しくフォルダが作成されてシンボリックリンクが切れることが判明したので、 この記事はバッチファイル作成の参考として残しておきます。

代わりとして、Chrome には起動オプションとして、Cacheディレクトリを指定できる機能が元から?ありました。 コマンドからオプションをつけて起動してもよいですが、 Chromeのショートカットを作成(もしくはスタートメニューにあるショートカットを利用)すると楽です。

こちらを参考。

chrome.half-moon.org

--disk-cache-dir="<ディスクキャッシュフォルダ作成先>" としてリンクの後ろにつけてあげると、そのフォルダにDefaultフォルダが作成されその中にCacheフォルダが作成されます。

そもそもなんでシンボリックリンク

結論はアプリケーションで場所を指定できないから。の理由だけです。

この方法は他のアプリケーションでも可能なので別のフォルダやドライブにしたいとかで有効です。 例えばリムーバブルドライブを指定できないときとかとか…? シンボリックリンクはあくまでフォルダまでは同じアドレスなのに参照先は別という見せかけのフォルダを作ります。

基本的な部分

バッチファイルを実行したフォルダと同じ場所にキャッシュフォルダを作り、実際はそちら側に保存させます。

if exist "C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\Cache\" (
    del "C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\Cache\" /q
    call :setErrorLevel 0
    rem シンボリックリンク先が無い場合には中のファイルが存在しないのでエラーが出ても進める
    rmdir "C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\Cache\"
    if errorlevel 1 GOTO:error
)
mkdir "%CD%\Cache\"
mklink /d "C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\Cache\" "%CD%\Cache\"
GOTO:EOF

rem エラーレベルリセット用関数っぽいの
:setErrorLevel
EXIT /b %1

:error
echo Error
pause
GOTO:EOF

元のCacheフォルダを削除してから、シンボリックリンクを作ります。 同じフォルダがある場合シンボリックリンクの名前は既にあるフォルダと同じ名前で作成できないので、元のフォルダは削除する必要があります。

このままでもよかったのだけど、ちょっと冗長的だったのでディレクトリ名を変数化しました。

set cacheDir="C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\Cache\"
if exist %cacheDir% (
    del %cacheDir% /q
    call :setErrorLevel 0
    rmdir %cacheDir%
    if errorlevel 1 GOTO:error
)
mkdir "%CD%\Cache\"
mklink /d %cacheDir% "%CD%\Cache\"

すこしスッキリしました。

Media Cache も追加することにした

最近ではMedia Cacheなるフォルダも作られていて、一応見てみるとそこにもキャッシュが存在しているようで。 こちらはHTML5の動画や音楽ファイルのキャッシュが保存されるそうです。 (ちなみにYouTubeの動画キャッシュは分割されて動画として扱われてないためかCacheのほうです。)

そのまま追加して書いてみたものの、同じことを2回してるためfor文かでまとめて書けないかと思いまして。 ループ変数をうまく使ってフォルダの名前を順に参照できないかどうかで少し詰まりました。

set cacheDir="C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\%%S\"
for %%S in ("Cache","Media Cache") do (
    rem 処理
)

このままだと、"Media Cache"が文字列内の空白で分割されてしまいました。 "delims=,"とか調べると出てくるのだけど、それは /f オプション時の設定なので求めているものとは違う。

ここで空白の処理に変数で%~を利用すると出力文字列の""が外せるということを見つけて、 もしかしたらと思ってfor文の変数に試してみたら見事に空白含む文字列もちゃんと処理することができました。

作成したバッチファイルは最後に載せておきます。おそらく他の環境でもそのまま使えるはずです。

起動したらシンボリックリンク作るバッチファイルの完成

組み込みたい要素は実現できたので、最初に実行のキー待ちを追加してダブルクリックで突然実行することがないようにもしてみました。 ちなみに、forの変数対象部分を弄るだけで別フォルダのシンボリックリンクを追加したりもしもの変更にも対応できます。

今後はこのバッチファイルでChromeのアップデート後に手動でやる必要がなくなったので快適ライフですね。

作成したバッチファイル

@echo off
setlocal

echo Change Chrome cache directory as symbolic link in current directory.
echo Note: Run this batch after exit Google Chrome. To can be safe execution.
echo Warning: Cache files are deleted when application create symbolic link.
echo Please execution with 'Run as administrator'. 
echo.
echo Chromeのキャッシュディレクトリを現在のフォルダにシンボリックリンクとして変更します。
echo Note: Chromeを閉じてから実行すると、安全に行えます。
echo Warning: リンク作成の際にキャッシュは消去されます。
echo シンボリックリンク作成の際は管理者権限が必要になります。「管理者として実行」から起動してください。
echo.

set /p ANSWER="実行しますか? YES:[y] NO:[n] : "
if "%ANSWER%"=="y" (GOTO:main)
GOTO:EOF

:main
echo.
set cacheDir="C:\Users\%USERNAME%\AppData\Local\Google\Chrome\User Data\Default\%%~S\"
for %%S in ("Cache","Media Cache") do (
    if exist %cacheDir% (
        rem directory exist
        del %cacheDir% /q
        call :setErrorLevel 0
        rem シンボリックリンク先が無い場合には中のファイルが存在しないのでエラーが出ても進める
        rmdir %cacheDir%
        if errorlevel 1 GOTO:error
    )
    mkdir "%CD%\%%~S\"
    mklink /d %cacheDir% "%CD%\%%~S\"
)
GOTO:END

rem エラーレベルリセット用関数っぽいの
:setErrorLevel
EXIT /b %1

:error
echo Error
pause
GOTO:EOF

:END
echo.
echo #####キャッシュリンク作成完了#####
echo.
pause