Photoshop UXPからExtendScriptを無理矢理実行する

UXP

Photoshop UXPが導入されて巷ではどちらかというと今までCEPやExtendScriptで出来たことが出来なくなって悲鳴の方が大きい気がします。なのでUXPで出来ない事(ダイアログを呼び出さずにファイルを指定のパスに保存、特定のファイルを開く等)をやるためにどうにかExtendScriptを実行できないかみたいな話題も出てきています。そして結論から言うと通常の機能ではできません。そして今回それを無理矢理やろうという話です。

*5月31日storageに関する記述を修正。secureStorageは今回使用する必要がありませんでした。

そもそもUXPで出来ない事とは

あまり公式ドキュメントでも大きく触れられていないのでよく混乱している方もいますがUXPのシステムはセキュリティ関係に関してかなり厳しく制限されています。つまりUXPプラグインから簡単にローカルのファイルにアクセスしたりデータを取得するといった事ができません。なので保存パスに関してはEntry型の独自のオブジェクトを扱わないといけなかったり(参照)Node.jsのコアモジュールも大半が使えません。つまり保存関係以外にも外部プログラムをUXPから実行もできなければファイルの移動、読み込みもダイアログ無しに実行できません。つまりこのダイアログからファイル、もしくはフォルダーを選ぶという行動はユーザーからローカルにアクセスする許可を与えてもらうと言う意味をあるわけですね。そしてこの一連のシステムはNode.jsでできない代わりにUXP独自のシステムから操作できます。それがlocalFileSystemであったりEntryオブジェクトであったりします。公式参照。

外部のNode.jsを使ってExtendScriptを実行

結局このuxpモジュールを使ったところでExtendScriptの実行もできなければ外部ファイルの操作もダイアログ抜きにできません。しかしダイアログを一度だけ開いてその後に特定のファイルの中身を書き込んだりアクセスすることはできます。今回この書き込みの機能と外部Node.jsのfs.watchメソッドを使ってUXPとExtendScriptを繋げます。前置きが長くなりましたがここから実際に具体的な方法について言及します。
Node.jsのfs.watchメソッドを使ってファイルの更新の監視ができます。公式参照 uxpのEntry fileオブジェクトはwriteメソッドがあります。つまりダイアログでファイルを呼び出して呼び出したファイルの中身をNodeでいうとことのfs.writeメソッドのように書き込むことが出来ます。(この辺の詳しい話は過去記事参照)。
writeメソッドは具体的には以下のようになります。

*storageにはsecureStorageというセキュリティの強化されたUXP独自のstorageもありますが今回は使用しません。

ダイアログを必ず一回は呼び出す必要がありますが一度監視対象のファイルを選べば後はuxpのアクセスTokenを発行してそのTokenから再度Entry型ファイルパスにアクセスできます。UXPではブラウザーと同じlocalStorageをサポートしているのでこれを使用します。Entry型のファイルを保存するときはcreatePersistentTokenメソッドで保存の用のtokenを発行します。詳しくはこちらの記事参照。

その後必要に応じてこの保存されたファイルパスを呼び出します。
保存されたtokenはgetEntryForPersistentTokenメソッドでEntry型のファイルパスを取得し直す必要があります。

ファイルパスをstorageに格納する事で何度もダイアログを呼び出す必要がなくなりました。後は監視対象のjsonファイルにExtendScriptに送りたい値を書き込む必要があります。それでwriteメソッドですがこれはEntry型のファイル、それ自身が所持するメソッドです。つまりjsonファイルをgetEntriesメソッドとfindメソッドで見つけて見つかったEntry型のファイルにwriteメソッドを実行させれば良いわけです。

ざっくばらんですがUXP側の仕組みです。次にjsonDataを監視するNodeの方です。こちらではExtendScriptを実行させるためにjsxkを使用しています。ExtendScriptの実行は勿論ターゲットとなるアプリケーションの指定、値を渡すことも可能で。なのでjsonに書き込まれた値をそのままExtendScriptに渡せます。

全体としての以下のようになります。

  • UXPからjsonに渡したい値と実行したいExtendScriptのパスを書き込む。

  • jsonを監視するNode.jsがjsonデータの書き込みを感知する。

  • jsonデータを読み込む。

  • jsonデータの内容を元にExtendScriptを実行して値も渡す。

かなり無理矢理なやり方ですがこれでExtendScriptをボタンひとつで実行できます。
正直配布するようなpluginには向いてませんがとりあえず自分のみ、もしくは社内だけで使うようなpluginなら使えるかもしれません。
また実際このプラグインの使い方は以下のようになっています。

  • watchフォルダー内にターミナルのcdを移動してnode watchで監視scriptを動かす。

  • UXP pluginを立ち上げてset watch folderボタンを押してpluginフォルダー内のwatchフォルダーを選択。

  • set jsxボタンを押してwatchフォルダー、jsxes内のjsxファイルをセレクターに登録。

  • send msgフォームにメッセージを書き込んでセレクターから実行したいjsxファイルを選択。excute jsxボタンを押して実行。

jsxesフォルダー内にjsxファイルを入れればパネルに登録できるscriptも増やせます。何かの参考になれば幸いです。
実際の完成されたコードはこちらから確認できます。

Beer 寄付してサイトを応援する。