[サイトTop] [As/R Top] [ヘルプTop] [戻る]

スクリプトをもっと詳しく

選択ファイルをFTPで転送/二つのフォルダを比較


 Ver.5.0から実装されたスクリプトの制御構文についてです。

 作者が言ってはならん気がするのですが、このあたりのレベルになってくると作者も全然使いこなせてないんで(使い方を知ってるだけであって応用力がありません)、不適切な説明をしちゃってたらごめんなさい。
 だって必要なら本体機能に埋め込みで載せちゃいますから、作者の本人は、柔軟性も、拡張性も、自由度も、そもそも全ての設定項目すら本当は必要ありませんからね。
 応用力が育まれないんですよ。

 というわけで、自由度の高いスクリプトの提供と言う形にして、ユーザーさんの自由な発想でAs/Rと外部ソフトと連携可能にしています。
 具体的には、連続コマンド発行や、条件によって処理の分岐、定型のお仕事の自動化などなど、使いこなせたら超絶便利になるモノなので、将来的に使いこなせば良いかも程度で良いと思います。
 時間がない人は、例によって先進んでください。

 今回の題材は、外部コマンドとしてWinSCPという、オープンソースのファイル転送ツールを使用します。
本家(執筆時点では日本語サイトに飛ばされます)
窓の杜さんのダウンロードページ

 まぁその、説明下手なんで、いきなりサンプル書いちゃいますがこんな感じです。

//選択したファイルをWinSCPで送信するスクリプトサンプル
//ディレクトリが指定された場合、再帰的に下位階層も処理されるようです。
//もちろん、コマンドラインオプションを変更することでSFTP/FTPS/FTP/SCP・・・といったWinSCPが対応しているプロトコルに対応させることができます
//なお、平文でスクリプトは記述されなければならないので、FTPアカウントの管理は慎重に行ってください
//WinSCPのファイル名はUTF8として転送されますので、FTPクライアントの文字コードの設定などを確認してください

//簡単な文法チェックを行う
CheckGrammar = 1

//バーにスクリプトを置いた時のアイコン画像を明示的に指定、iconは静的なコマンドなので変数展開できない
icon = D:\TOOLS\FileTool\WinSCP\WinSCP.exe

//WinSCPのフルパス(コマンド版を使用)
var $WinSCPPath$ = D:\TOOLS\FileTool\WinSCP\WinSCP.com

//FTPユーザーID
var $UserID$ = hoge

//FTPパスワード
var $PassWord$ = hogehoge

//ホスト名
var $HostName$ = 192.168.10.50

//ファイルをアップロードするディレクトリ、inputなどを使用して手入力可にしたり、外部から渡すようにしても良いでしょう
var $TargetDir$ = /home/hoge/test

//ループの中で変数を定義すると、繰り返し時に再定義エラーになるのでループの外で定義
var $TargetUrl$ = ftp://$UserID$:$PassWord$@$HostName$
var $Command$
var $Result$
For
	$Command$ = $WinSCPPath$ /command "option batch on" "option confirm off" "option transfer binary" "open $TargetUrl$ -passive" "cd $TargetDir$" "put ""?selfile?""" "exit"
	$Result$ = Call,$Command$

	if $Result$ != 0
		MessageBoxOK=エラーコード($Result$)が返りました $Command$
		break
	endif
Next

 キモな部分は、主に以下の2点です。

1.For/Nextによるループは、選択ファイルの数だけ繰り返されるものです。
 つまり、選択ファイル名の置換マクロである?selfile?が、順々に値を渡されて1個ずつ処理されていくという流れになります。

2.外部コマンドを実行するコマンドでCallを使用しています。
 これは、呼び出したコマンドが終了するのを待って、その終了コードを受け取ります。
 つまりWinSCP.comは、何かエラーになったら1を返してくるので、次のif文でエラーが起きたので処理を中断・・・と分岐しているわけです。

 あと、ぐちゃぐちゃと「option batch on・・・」って書いてある部分は、WinSCPのコマンドラインオプションです。
 もしかしたら、ポート番号くらい設定部分の記述にした方が良かったかもしれませんね。
 意味を知りたければWinSCPの方のヘルプを参照してください。
 (パッシブモードで、同じものがあっても上書きするとか、応答しないで処理しろとか、そんな意味のオプション類です)

 まぁ、実際動かしてみるとウィンドウがパラパラ開いてウザイので、このスクリプトを非表示で動かすようにしたり、ディレクトリだったら別の処理にするとか、ディレクトリ監視や同期を取るようなコマンドに変えてみるとか、色んな応用が広がるってぇ事を理解していただけたらと思います。
 他にも一個ずつコマンドを渡すのではなく、一括で渡すようにすると処理速度も速くなるでしょう。
 なお最近のOSでも、コマンドラインで渡せる文字数は約8000文字(正確には8KB-1文字)くらいまでなので、その辺りは工夫する必要があります。

 ちなみにこのスクリプトですが、仕事でWinSCPの調査をする時に使ったモノです。
 参考までにどうぞ。



 あと、2画面ファイラー風あれこれ編で書いてるWinMerge用のスクリプトを、ちょいと高度なものにしてみます。
 WinMerge日本語版サイト

//現在、画面分割して開いている二つのディレクトリをWinMergeを用いて比較するスクリプト

CheckGrammar=1

//アイコン画像を明示的に指定、iconは静的なコマンドなので変数展開できない
icon = %ProgramFiles%\WinMerge\WinMergeU.exe

//WinMergeのインストールパス
var $WinMergePath$=%ProgramFiles%\WinMerge\WinMergeU.exe

OpenMode=0
MultiCommandMode=0
ShiftSilentMode=0
BootDir=
BootMode=0
SendInfoMode=0

//画面分割していない場合は1個だけ渡す
if ?State:DivisionWindow? == 0
	CommandLineOption=?NowDir?
	Shell=$WinMergePath$
	exit
endif

//画面分割している場合はパスを2個渡す
CommandlineOption="?TargetDir?" ?NowDir?
Shell=$WinMergePath$
EOF

//環境変数「%ProgramFiles%」はx64環境でx86版なら「C:\Program Files (x86)」
//x86環境か、x64環境でx64版なら「C:\Program Files」と展開されることにご注意ください
 こちらのキモは、?State:DivisionWindow?の使い方でしょうか。
 内部情報を取得する置換マクロで、1画面用か、2画面用で呼び出すコマンドの引き数を切り替えてます。
 Ver.5.10以降であれば、else文を使った方がカッコ良くなります。