見に来てくださって、ありがとうございます。石川さんです。
たくさんあったWindowsのショートカットの参照先をスクリプトを使って一気に変えたくなったのですが、やり方がすぐに見つけられなかったので記録しておきます。サーバのリプレースやフォルダの整理等により、ショートカットの参照先が変わってしまって対応が必要になったときに使えます。どなたかのお役に立てば、うれしいです。
すぐに見つけられなかったのは、「ショートカット」という名称がよくなかったようです。キーボードショートカットが検索結果の上位に登場してきます。試行錯誤して探し出しましたが、まずは参考になったのがこちらです。ここでショートカットの拡張子は「.lnk」らしい、ということと、win32com.clientのDispatchで”WScript.Shell”を使えばショートカットが作成できるらしい、と、アタリをつけました。
今回は、ショートカットのプロパティの「リンク先(T)」「作業フォルダー(S)」を修正したかったのですが、上記で見つけたリンクでは「リンク先(T)」が「TargetPath」だ、ということしかわからなかったので、追加で「WScript.Shell」+「shortcut」+「property」で検索してこちらのページを見つけました。こちらで「作業フォルダー(S)」は「WorkingDirectory」ということがわかりました。
ソースコード
ここまでわかればなんとかなる、ということでスクリプトを作成しました。Pythonです。
#!python # -*- coding: cp932 -*- # このスクリプトは指定したフォルダの中をくまなく操作して、 # ショートカットを見つけたときに、「置き換え前」を「置き換え後」に置き換えるためにつくりました。 # 変数を変更することで他の用途にも対応可能です。 import os import win32com.client 指定フォルダ = "Z:" + os.sep + "テストフォルダ" 置き換え前 = r"\\old_server" + os.sep + "shared_folder$" 置き換え後 = r"\\new_server" + os.sep + "shared_folder$" shell = win32com.client.Dispatch("WScript.Shell") for root, dirs, files in os.walk(指定フォルダ): for file in files: if file[-4:] == ".lnk": shortcut = shell.CreateShortCut(root + os.sep + file) if shortcut.Targetpath[:len(置き換え前)].lower() == 置き換え前.lower(): changed_targetpath = 置き換え後 + shortcut.Targetpath[len(置き換え前):] shortcut.Targetpath = changed_targetpath shortcut.save() if shortcut.Workingdirectory[:len(置き換え前)].lower() == 置き換え前.lower(): changed_workingdirectory = 置き換え後 + shortcut.Workingdirectory[len(置き換え前):] shortcut.Workingdirectory = changed_workingdirectory shortcut.save()
まずは、一番のポイント、14行目のWScript.Shellですね。ここではCOMオブジェクトをディスパッチしています。これによりWindowsのWshShellオブジェクトの機能が利用可能になります。
次は16行目ですが、os.walkを利用して、「指定フォルダ」配下のファイルをすべてチェックします。ここのforループのrootに、現在処理対象のフォルダ名、filesにそのフォルダ内にあるファイルのリストが取得できます。この取得したファイルリストをすべて処理し始めるのが、17行目のforループです。
18行目では、ファイル名の最後の4文字を取り出して「.lnk」かどうかチェックしています。ショートカットは拡張子が「.lnk」になっています。そして、ショートカットの場合、19行目で「CreateShortCut」を使ってショートカットのオブジェクトを作成しています。作成する、と言っても元々がショートカットですので、ショートカットのショートカットが新しく作成されるわけではなく、現在の設定のショートカットを参照した形になります。ちなみに、os.sepは、セパレート文字列で、Windowsの場合「\」、Linuxの場合は「/」のように適切な区切り文字にセットされます。
20行目で置き換え対象かどうかチェックして、対象なら「Targetpath」をセットすることで「リンク先」を更新して23行目の「save」メソッドで変更を確定する、ということをやっています。24~27行は同様ですが、「WorkingDirectory」をセットすることで「作業フォルダー」を更新しています。
まとめ
やりたいことは難しいことでなかったのですが、既存のショートカットを更新したいのに「CreateShortCut」メソッドを使う、というところがちょっと馴染めない感じがしました。ま、慣れれば大丈夫ですね。