batファイルでフォルダ監視を作った話

2020年6月4日

こんにちわークリレアです。

今回は仕事の都合でbatファイル作ったのでその話をば

今回作ったbatファイル は、違うPCのフォルダを監視をして、そのフォルダ内にPDFファイルが入ったら、PDFファイルをbatファイルのあるPCのフォルダにコピーするというものです。 

今回のbatファイルに求める動作

違うPCに接続

・移動元のフォルダ内の1階層下のサブフォルダの中にPDFファイルがあるか確認
・あった場合は移動先のフォルダに移動
上を延々とループ

以上!

細かい動作

違うPCに接続

↓接続できなかった場合はbatファイル を終了
↓ログファイル作ればいいんだろうけどパス

接続できた場合
移動先フォルダ内にあるサブフォルダ名を順番に取得
サブフォルダ内にPDFファイルがあるか確認

↓なかった場合は1秒後に次のサブフォルダへ。
↓全サブフォルダを見たら一番上にループ

PDFファイルがあった場合
PDFファイル名順番に取得

ファイルサイズを変数1に
0.8秒スリープ
再度ファイルサイズを変数2に格納

ファイルサイズを照らし合わせて変数1と変数2で変更がなかった場合は移動先フォルダにPDFファイルを移動
変更があった場合は何もせず次のPDFファイルを処理

PDFファイルを全て移動したら次のサブフォルダ内にPDFファイルがあるか確認

全サブフォルダを確認したら
違うPC宛にpingを1回送り無事到達したら1秒待機しまた一番上からやり直し。

pingがタイムアウトしたら接続が解除されたと判断してbatファイルを終了

具体的なコード

@echo off

rem 最小化で起動
if not "%CLIREA%"=="clirea" (
	set CLIREA=hoge
	start /min cmd /c, "%~0" %*
	exit
)

rem 文字色を緑に
color 0A
rem 遅延環境変数
setlocal enabledelayedexpansion


set setuzokusaki1="接続先のPCの親フォルダのアドレス"
set idousaki1="移動先の親フォルダのアドレス"
rem ダブルクォーテーションの削除
set setuzokusaki=%setuzokusaki1:"=%
set idousaki=%idousaki1:"=%

rem 接続先のPCが起動しているか確認起動していなかったら終了
ping -n 1 -w 50 接続先PCのIPアドレス | Find "受信 = 1" > nul
if %ERRORLEVEL% equ 1 (
	echo 接続先PCとの接続が切れました。プログラムを終了します
	echo 何かボタンを押してください
	pause > nul
	exit
)

rem 接続先のPCに移動
pushd %setuzokusaki%

echo このプログラムは
echo %setuzokusaki%
echo 内にあるPDFファイルを
echo %idousaki%
echo 内に移動するプログラムです。
rem echo 不具合が発生した場合は○○○○までお願いします。
Echo;
Echo;
Echo ┏━━━━━━━━━━━━━━━━━━━━┓
Echo ┃ ファイル監視中              ┃
Echo ┃ 中断する際はCtrl+Cを押してください   ┃
Echo ┗━━━━━━━━━━━━━━━━━━━━┛
Echo;
Echo;

rem ループ回数記録
set count=0
rem 移動したファイルの数記録
set count2=0

rem 全サブフォルダ確認後戻ってくるラベル
:DO_WHILE

rem 接続先のフォルダの中のサブフォルダを順番に取り込み
for /d %%a in (%setuzokusaki%¥*) do (
	set aaa=%%a
	rem 接続先のフォルダの中のサブフォルダの中にPDFがあるか確認
	if exist %%a¥*.pdf (
		rem あった場合、PDFファイル名を順番に取得
		for /f "delims=" %%b in ('dir /b !aaa!¥*.pdf') do (
			rem 接続先に同じ名前のファイルがあるか確認
			rem あった場合は無視。なかった場合は処理開始
			if not exist !idousaki!¥%%~na¥%%b (
				rem 800ミリ秒の間にファイルサイズに増減がないか確認
				set pdffile="%%a¥%%b"
				rem ファイルサイズの取得
				for %%s in (!pdffile!) do set size1=%%~zs
				rem echo !size1!
				rem 0.8秒間スリープ
				powershell rshell -Command "sleep -m 800"
				rem 再度ファイルサイズの取得
				for %%s in (!pdffile!) do set size2=%%~zs
				rem echo !size2!
				rem サイズが0以外で800ミリ秒前と後でファイルサイズが同じ場合移動
				if !size2! neq 0 (
					if !size1! equ !size2! (
						echo ファイル移動中:%%b
						move "%%a¥%%b" "!idousaki!¥%%~na¥%%b" > nul
					
						set /a count2=!count2!+1
						timeout 1 >nul

					)
				)
			)
		)
	)
timeout 1 >nul


)
rem 全サブフォルダ確認終了
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
Echo;
echo このプログラムは
echo %setuzokusaki%
echo 内にあるPDFファイルを
echo %idousaki%
echo 内に移動するプログラムです。
rem echo 不具合が発生した場合は○○○○までお願いします。
Echo;
Echo;
Echo ┏━━━━━━━━━━━━━━━━━━━━┓
Echo ┃ ファイル監視中              ┃
Echo ┃ 中断する際はCtrl+Cを押してください   ┃
Echo ┗━━━━━━━━━━━━━━━━━━━━┛

Echo;
Echo;
Echo;
rem ループ回数+1
set /a count=%count%+1
echo ループ%count%回目
echo 合計%count2%個のアイテムを移動しました
timeout 1 >nul

rem 接続先PCにpingを送って起動しているか確認消えてたら終了
ping -n 1 -w 50 接続先PCのIPアドレス | Find "受信 = 1" > nul
if %ERRORLEVEL% equ 1 (
	echo 接続先PCとの接続が切れました。プログラムを終了します
	echo 何かボタンを押してください
	pause > nul
	exit
)


rem 最初に戻る
GoTo DO_WHILE





rem おあそび
echo なぜぬけた??
echo もう一回起動してね
echo 何かボタンを押したらこのウィンドウは消えます。
pause >nul

完成までの道のり

まず違うPCに接続は問題なく、接続できなかった場合のエラー処理も必要だったので追加。

接続先のフォルダの階層に半角空白があったため、ダブルクォーテーションで囲む必要があったのだけれど、囲んでしまうとその後のforに代入するときにエラーが出てしまったのでダブルクォーテーションの削除も追加

PDFファイル名の取得は、フォルダの取得と同じ書き方で最初やったのだけれど、PDFファイル名に空白があったときにうまく動かなかったのでdir式に変更。

これで完成かと思われたのだけれど、コピー中のファイルとかも容赦無く移動しちゃってファイルが壊れてしまったので、ファイルが移動中かどうか判定するためのコードも追加。
0.5秒で作ったんだけどなんかうまく動かなかったので0.8秒にして見たら今の所問題なさそう

4時間くらいで完成!!
サビ残ですけどねー(泣)
もっとさくさく作れるようになりたいけどなー
コード量的に考えると30分くらいで作れそうだし人によっては10分くらいでしょ?
どんだけロスしてるのかと。。。
まあがんばるしかないですね。

 

いまこのコードで問題ないか検証中なり。
問題なさそうなら業務に組み込んで使うべよー

ではではさよならー

-batファイル, パソコン関連, 雑記・日記

© 2021 クリレアさんの記録