Blog

  • 新型コロナウィルスワクチン5回目

     接種した日の夜には接種証明書アプリで更新できた。データの打ち込みが終われば、即時で取得できるのだろう。

     以前の接種証明書は残るので手動で削除しないといけない。

    5回目接種1日目

    10:00 体温36.2℃
    14:00 体温36.2℃
    16:00 体温36.1℃
    22:00 体温36.4℃ 少し注射跡が痛い
    24:00 体温36.1℃

    2日目
    09:00 体温35.7℃ 腕を動かすと注射あとが少し痛む
    14:00 体温36.1℃
    16:00 体温36.5℃
    19:00 体温36.3℃

    3日目
    09:00 体温35.7 もう痛みはほとんどない
    18:00 体温36.6℃

    4日目
    21:00 体温36.5℃

  • Alexaでパソコンの起動/終了

     Alexaで「おはよう」「おやすみ」で日常の動作は自動化しているが、パソコンの立ち上げ、終了もできないかと試してみた。

    2023/11/01追記

    Amazon AlexaとIFTTTの連携が終了したため、IFTTT経由での操作は不可能となったらしい。

    起動方法

    ・アレクサのスキルでAlexa.WakeOnLANControllerを使うスキルを作っ/使ってEchoデバイスからマジックパケットを送出する

     既存のスキルがあるらしいが、外部サイトにAmazonアカウントでログインしてPCを登録しないとならないようだ
     Wake on Lan Alexa Skill

    スキルを自作する
     Amazon Echo (Alexa) でPCの電源を付ける

    ・スマートプラグでPCの外部電源をon/off

    実行中に切ると、ファイルシステムが破損し、OSが立ち上がらなくなる可能性があるので、やってはいけない。
    外部電源が切れていると、CMOS&時計のバックアップ用電池が早く消耗する。

    ・ローカルエリアのUNIXパソコン内のNode-RED(アレクサから見える仮想デバイス)経由でマジックパケットを送出する

    アレクサでWindows PCをOn / Off

    ・IFTTTからPushbullet経由で一旦スマホにSMSで情報を渡して起動させる

    Androidの自動化アプリ(Automagic,Taskerなど)で、スマホからマジックパケットを送出する

    ・IFTTTから共有フォルダー(OneDriveなど)経由で中継マシンにEventGhost経由で情報を渡す

     俺のパソコン起動して! Wake On LAN を Alexa で実現する

    終了方法

    ・IFTTTから共有フォルダー(OneDriveなど)経由で中継マシンに情報を渡す

    中継マシンではAssistant Computer Controlを実行

    【プログラミング不要】スマートスピーカーでパソコンをシャットダウン&スリープモードにする方法

    本題:Alexaでパソコンの起動/終了

    ・IFTTTから共有フォルダー(OneDriveなど)経由で中継マシンに情報を渡し、中継マシンはOneDriveのファイルを監視するスクリプトを実行する

    事前準備としてIFTTTでAlexaの「パソコン起動」「シャットダウン」に応答するアプレットを作成する

    アプレットの作り方は以下などを参考にしてください

    【プログラミング不要】スマートスピーカーでパソコンをシャットダウン&スリープモードにする方法

    IFTTTのサイトでアプレットを作成する

    スマホのIFTTTアプリでも可能

      Googleアカウントなどでログイン
      My Apletts
      Create
      if then:Amazon Alexa
      Choose a trigger:Say a specific phrase
        What phrase?:パソコン起動
        Create trigger
      Then That:Add
      Choose a service:OneDrive
      Choose an action:Create text file
      Connect service:Connect
        Microsoftアカウントでサインインする
      Create text file
        Filename:computerAction
        OneDrive folder path:Amazon Alexa/
        Contenet:Wakeup
        Create action
      Finish
    
      Create
      if then:Amazon Alexa
      Choose a trigger:Say a specific phrase
        What phrase?:シャットダウン
        Create trigger
      Then That:Add
      Choose a service:OneDrive
      Choose an action:Create text file
      Connect service:Connect
      Create text file
        Filename:computerAction
        OneDrive folder path:Amazon Alexa/
        Contenet:Shutdown
        Create action
      Finish

    ちなみに、アプレットの削除はHelpから”Can I delete an Applet”を選ぶと行えるらしい。

    Can I delete an Applet?

    スクリプトファイルを作成する

    “%OneDrive%\Amazon Alexa”に以下のファイルを作成する。

      computerAssistant.bat ファイルを監視して対応するバッチファイルを実行する
      Wakeup.bat  実際にパソコンを起動させるバッチファイル
      Shutdown.bat 実際にパソコンを終了させるバッチファイル

    computerAction.bat
     ”%OneDrive%\Amazon Alexa\computerAction”ファイルがあれば、その内容に従ってバッチファイルを実行する。

    @echo off
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    
    setlocal enabledelayedexpansion
    cd /D %~dp0
    
    rem 画面制御のエスケープシーケンスを環境変数に作成する
    call SetEscVar.bat
    
    set ALEXA=%OneDrive%\Amazon Alexa
    set COMPUTER_ACTION=%ALEXA%\%~n0
    echo COMPUTER_ACTION=%COMPUTER_ACTION%
    
    set /a WAIT=10
    
    set WAITING=Waiting...
    set /a MSG_CNT=0
    :CHAR_COUNT
    call set w=%%WAITING:~%MSG_CNT%,1%%
    if not "%w%" == "" (
      set /a MSG_CNT+=1
      goto :CHAR_COUNT
    )
    
    @echo|set /p=%ESC_BLINK%
    
    set /a COUNT=0
    :LOOP
    
    if exist "%COMPUTER_ACTION%" (
      for /f "usebackq delims=" %%f in ("%COMPUTER_ACTION%") do (
        echo.
        @echo|set /p=%ESC_LINEUP%
        if exist "%ALEXA%\%%f.bat" (
          @echo|set /p=%DATE%-%TIME: =0% : start %%f.bat
            start %%f.bat
        )
      )
      del "%COMPUTER_ACTION%"
    
      set /a COUNT=0
      timeout /T %WAIT% > nul
      goto :LOOP
    )
    
    set /a MSG_POS=%COUNT% %% (%MSG_CNT% + 1) - 1
    if %MSG_POS% equ -1 (
      echo.
      @echo|set /p=%ESC_LINEUP%
    
      @echo|set /p=%DATE%-%TIME: =0% : 
    ) else (
      @echo|call set /p=%%WAITING:~%MSG_POS%,1%%
    )
    
    set /a COUNT+=1
    timeout /T %WAIT% > nul
    goto :LOOP
    
    endlocal
    exit 0

    SetEscVar.bat
     画面制御用のエスケープシーケンスを環境変数に作成する

    @echo off
    :TEMP_NAME
    set ESC_FILE=%TEMP%\%~n0_%RANDOM%
    set ESC_HEX_FILE=%ESC_FILE%_hex.tmp
    set ESC_BIN_FILE=%ESC_FILE%_bin.tmp
    if exist %ESC_HEX_FILE% goto :TEMP_NAME
    if exist %ESC_BIN_FILE% goto :TEMP_NAME
    
    echo 1B 5B>%ESC_HEX_FILE%
    certutil.exe -decodehex %ESC_HEX_FILE% %ESC_BIN_FILE% >NUL 2>&1
    set /P ESC=<%ESC_BIN_FILE%
    del %ESC_HEX_FILE% >NUL 2>&1
    del %ESC_BIN_FILE% >NUL 2>&1
    
    rem The code to go to first column and n lines up is ESC[nF
    rem The code to delete to the end of the line is ESC[0J
    set   ESC_LINEUP=%ESC%1F%ESC%0J
    set  ESC_LINETOP=%ESC%999D
    set ESC_CLRRIGHT=%ESC%0K
    set  ESC_CLRLEFT=%ESC%1K
    set  ESC_CLRLINE=%ESC%2L
    set   ESC_NORMAL=%ESC%39m
    set    ESC_BLINK=%ESC%5m
    
    exit /b 0

    Wakeup.bat (Windowsの機能だけを使う場合)
     PowerShellを使ってマジックパケットを送出する。forの行は改行なしの1行です。

    @echo off
    echo.
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    
    setlocal enabledelayedexpansion
    
    set PC1=192.168.0.11,XX:XX:XX:XX:XX:XX
    set PC2=192.168.0.12,XX:XX:XX:XX:XX:YY
    set PC3=192.168.0.13,XX:XX:XX:XX:XX:ZZ
    set PCs=192.168.0.14,%PC1% %PC2% %PC3%
    
    rem ping.exe で応答しないもののみマジックパケットを送出する
    for %%p in (%PCs%) do (
      for /f "tokens=1,2 delims=," %%q in ("%%~p") do (
        echo ping.exe %%q
        set WAKE=
        for /f "usebackq skip=2 tokens=1,2" %%i in (`ping -n 1 %%q`) do (
          if "%%j" == "からの応答:" if not "%%i" == "%%q" set WAKE=1
          if "%%i" == "要求がタイムアウトしました。" set WAKE=1
        )
        if "!WAKE!" == "1" (
            PowerShell.exe "$macAddr=[byte[]]("""%%r""".split(""":""") | ForEach-Object{[Convert]::ToInt32($_, 16)}); $magicPacket=([byte[]](@(0xFF)*6)) + $macAddr * 16; $udpClient=new-object System.Net.Sockets.UdpClient; $WakeUpTarget=[System.Net.IPAddress]::Broadcast; $udpClient.Connect($WakeUpTarget, 9); $udpClient.Send($magicPacket, $magicPacket.Length) | out-null; $udpClient.Close();"
            echo %%qを起動しました。
          )
        )
      )
    )
    @rem for %%p in (%PCs%) do C:\Winapp\WinWol_v303\WinWol.exe /C /H %%p
    
    endlocal
    
    timeout /T 60
    
    exit 0

    Wakeup.bat (WinWolを使う場合)
    あらかじめインストールしたWinWolにパソコンのホスト名やMACアドレスなどを登録しておく。バッチファイルではC:\Winapp\WinWol_v303にあるWinWol.exeを利用して他のPCを起動する。

    @echo off
    echo.
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    
    setlocal
    
    set PCs=PC1 PC2 PC3
    
    set WOL_CMD=C:\Winapp\WinWol_v303\WinWol.exe /C /H
    
    for %%p in (%PCs%) do %WOL_CMD% %%p
    
    endlocal
    
    echo PCを起動しました。
    
    timeout /T 60
    
    exit 0

    ちなみに、WinWolでは一台のPCでクライアントリストを作成した後、WinWol.iniファイルをOneDriveに移動した後、以下のコマンドでリンクを作成してすべてのPCから同じクライアントリストを使用している

    del WinWol.ini
    mklink WinWol.ini %OneDrive%\Backup\WinWol.ini

    Shutdown.bat
    Shutdown.exeを利用して、他のPCを終了させる。自分自身も終了させることはできるか、立ち上げるには手動で電源を入れるしかなくなる。

    @echo off
    echo.
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    
    setlocal
    
    set PCs=PC1 PC2 PC3
    
    for %%p in (%PCs%) do start shutdown.exe /s /f /m \\%%p
    
    echo.
    @echo シャットダウンが進行中です。
    @echo シャットダウンをキャンセルするには、何かキーを押してください
    timeout /T 120
    for %%p in (%PCs%) do start shutdown.exe /a /m \\%%p
    
    echo.
    @echo シャットダウンをキャンセルしました
    
    endlocal
    exit 0

    Windows起動時にスクリプトを実行させる

    スクリプトは表示しない、または最小化させた状態で実行させたい。

    タスクスケジューラーにタスクとして登録する方法(表示しない)
    全般
      名前:Amazon Alexa computerAction
      説明:Amazon AlexaからIFTTT経由で作成されたコマンドファイルを読み取り、対応する処理を実行します。
      セキュリティオプション:ユーザがログオンしているかどうかにかかわらず実行する
    トリガー
      システム起動時、遅延時間を指定する:1分間
    操作
      プログラムの実行
        プログラム/スクリプト:"C:\Users\xxxxx\OneDrive\Amazon Alexa\computerAction.bat"
    設定
      タスクを停止するまでの時間;オフ

    OKを押すとパスワードの入力を求められるので、入力する。この設定だとタスクバーにも表示されない。

    start /minや、Wscript.Shell.runを使って最小化する方法はあるが、別プロセスとなるためタスクマネージャーで実行状態を管理できない。

    セキュリティオプションで、「ユーザーがログオンしているときのみ実行する」にすると、通常の窓で表示されてしまう。

    スタートアップフォルダーにショートカットを入れて実行させる方法(最小化)

    “%OneDrive%\Amazon Alexa\computerAction.bat”ファイルのショートカットをスタートアップフォルダー(“%ProgramData%\Microsoft\Windows\Start Menu\Programs\StartUp”)に作成し、プロパティの実行時の大きさを最小化に変更する。

    サービスとして実行させる方法(表示しない)

    いくつかツールがあるらしいが、sexeを利用してみた。以下からダウンロードして適当なフォルダーに展開する。

    https://www.nanshiki.co.jp/software/sexe.html

    sexe64.exeを実行し、以下の設定で、テスト起動して開始・終了した後OKボタンでサービスとして登録する。

      プログラム
        ファイル:C:\WINDOWS\System32\cmd.exe
        起動時オプション:/c "C:\Users\[ユーザー名]\OneDrive\Amazon Alexa\computerAction.bat"
        優先度:通常
      サービス
        名前:Amazon Alexa computerAction
        説明:Amazon AlexaからIFTTT経由で作成されたコマンドファイルを読み取り、対応する処理を実行します。
        自動起動:on
      起動・終了
        終了方法:WM_SYSCOMMAND→WM_CLOSE
        シャットダウン以外でプログラムが終了したら再起動:on

    このままでは実行するアカウントの権限が問題で外部バッチファイルが実行できない。サービスマネージャーで一旦Amazon Alexa computerActionサービスを停止し、ログオンタブでOneDrive所有者のアカウント情報を入力して再度開始すると、実際の起動・終了処理を実行できるようになる。

    設定を削除したときなどは再起動しないと、サービスが削除予定で残ることがある。

    Alexaの定型アクションに追加する

    現状でも”アレクサ、トリガー パソコン起動”と発話すれば、パソコンを起動できる。Alexaアプリで定型アクションに「パソコン起動」として、IFTTTのアクションを追加すると簡単な発話で実行できるようになる。

    さらに「おはよう」「おやすみ」「ただいま」などの定型アクションにも追加すると一連の動作と一緒にパソコンも一緒に操作できるようになる。また、アレクサアプリを使えば、外出先からでもパソコンを起動できる。

    なぜか、IFTTTのアクションは元のアプレットを削除してもそのままの名前で残っている、何とか消せないのだろうか。似たような名前なので間違えて登録しても実行されないことがあった。

  • WordPress バックアップ その3

     その2でログファイルなどを一定数以上のを削除するようにしたが、cmd.exeの変数を使っているため長いファイル名や個数が多くなるとエラーが出て実行できなくなる。

     変数ではなく最初からファイルに書き出すことで制限を実質上無くする。

     ソート用ファイルにファイルサイズも出力した。PrintNum3.batファイルがあれば3桁区切りで,を追加する。

    Backup.bat

    @echo off
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    @rem DATEの出力で、先頭に曜日が漢字一文字で表示されることがある。
    @rem その場合は設定-時計と言語-日付と時刻-日付と時刻の形式を変更するで、
    @rem 日付(短い形式)でyyyy/MM/ddを選ぶと曜日が出力されなくなるようだ。
    @rem OSのバージョンによっては、設定-時刻と言語-日付と時刻-日付、時刻、地域の書式設定-データ形式を変更する
    
    setlocal
    
    cd /D %~dp0
    if not exist %~dp0log mkdir %~dp0log
    
    set LOGFILE=%~dp0log\%COMPUTERNAME%_Backup_%date:~-10,4%-%date:~-5,2%-%date:~-2,2%.log
    
    if "%WORDPRESS_BACKUP%" == "" (
        echo no backup placement >> %LOGFILE% 2>&1
        echo set WORDPRESS_BACKUP=xxx >> %LOGFILE% 2>&1
        endlocal
    
        EXIT /B
    )
    
    if not exist %LOGFILE% (
        if exist "\ProgramData\Win-acme" (
          echo robocopy  "\ProgramData\Win-acme" "%WORDPRESS_BACKUP%\ProgramData\Win-acme" /MIR /NP /XD log >> %LOGFILE% 2>&1
               robocopy  "\ProgramData\Win-acme" "%WORDPRESS_BACKUP%\ProgramData\Win-acme" /MIR /NP /XD log >> %LOGFILE% 2>&1
        )
    
        for %%f in (Squid xampp) do call %0 %%f
          if exist \%%f (
            echo robocopy  \%%f %WORDPRESS_BACKUP%\%%f /S /XJ /XO /XX /XL /NP
            robocopy  \%%f %WORDPRESS_BACKUP%\%%f /S /XJ /XO /XX /XL /NP
          )
        ) >> %LOGFILE% 2>&1
    
        call BackupMySQL.bat 30d >> %LOGFILE% 2>&1
    
        call DeleteOldFile.bat %~dp0log %COMPUTERNAME%_backup_*.log 30d >> %LOGFILE% 2>&1
    
        call DeleteOldFile.bat C:\ProgramData\win-acme\acme-staging-v02.api.letsencrypt.org\Log log-*.txt 90d >> %LOGFILE% 2>&1
        call DeleteOldFile.bat C:\ProgramData\win-acme\acme-v02.api.letsencrypt.org\Log         log-*.txt 90d >> %LOGFILE% 2>&1
    
        call DeleteOldFile.bat C:\Temp\sakura   *.* 30d >> %LOGFILE% 2>&1
        call DeleteOldFile.bat C:\Temp\WinMerge *.* 30d >> %LOGFILE% 2>&1
    )
    
    endlocal
    
    EXIT /B

    BackupMySQL.bat

    @echo off
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    rem MAX_FILES 残す個数
    
    
    setlocal
    
    for %%i in (wp-01 wp-02) do call :MYSQLDUMP %%i %1
    
    endlocal
    
    EXIT /B
    
    
    :MYSQLDUMP
    
    setlocal
    
    if not exist %~dp0MySQL mkdir %~dp0MySQL
    set SQL_FILE=%~dp0MySQL\%COMPUTERNAME%_%1_%date:~-10,4%-%date:~-5,2%-%date:~-2,2%.sql
    
    if not exist %SQL_FILE% (
        echo C:\xampp\mysql\bin\mysqldump -u -p %1
        C:\xampp\mysql\bin\mysqldump -u ユーザー名 -pパスワード %1 > %SQL_FILE%
        if errorlevel 1 goto :NO_FILE
        
        for %%f in (%SQL_FILE%) do (
            if %%~zf == 0 goto :NO_FILE
            if "%%~zf" == "" goto :NO_FILE
        )
    
        if not "%WORDPRESS_BACKUP%" == "" (
            if not exist %WORDPRESS_BACKUP%\xampp\Tools\MySQL mkdir %WORDPRESS_BACKUP%\xampp\Tools\MySQL
            echo copy /Y %SQL_FILE% %WORDPRESS_BACKUP%\xampp\Tools\MySQL\
            copy /Y %SQL_FILE% %WORDPRESS_BACKUP%\xampp\Tools\MySQL\
        )
    
        call DeleteOldFile.bat %~dp0MySQL %COMPUTERNAME%_%1_*.sql %2
    )
    
    endlocal
    
    EXIT /B
    
    :NO_FILE
    
    echo SQL output fail.
    
    endlocal
    
    EXIT /B 1
    

     DeleteOldFile.bat

    @echo off
    @rem echo %0 %1 $2 %3 %4
    if not "%4" == "" goto :FORMAT
    echo %DATE%-%TIME: =0% : Excecuting ... %0 %*
    @rem FOLDER フォルダー
    @rem PATERN ファイルパターン
    @rem        最後の文字が"\"ならフォルダーパターン
    @rem LAST_DAYS 残す日数d or MAX_FILES 残す個数n デフォルトは日数
    
    setlocal enabledelayedexpansion
    
    set FOLDER=%~1
    set PATERN=%~2
    set PARAM3=%3
    set /a MAX_FILES=0
    set /a LAST_DAYS=0
    set DIRECTORY=
    if "%PATERN:~-1%" == "\" set DIRECTORY=/d
    if "%PATERN:~-1%" == "\" set PATERN=%PATERN:~0,-1%
    echo DIRECTORY="%DIRECTORY%" PATERN="%PATERN%"
    
    @rem forfilesに*.*を指定すると拡張子無しが検索できないので*に変える
    if "%PATERN%" == "*.*" set PATERN=*
    
    @rem 日付(d)、個数(n)指定の処理、指定されていないときは日付指定にする
    if not "%PARAM3%" == "" (
      if /I "%PARAM3:~-1%" == "d" (
        set /a LAST_DAYS=%PARAM3:~0,-1%
      ) else if /I "%PARAM3:~-1%" == "n" (
          set /a MAX_FILES=%PARAM3:~0,-1%
      ) else (
         set /a LAST_DAYS=%PARAM3%
      )
    )
    
    if not exist %FOLDER% (
      echo not exist %FOLDER%
      endlocal
      echo.
      EXIT /B 1
    )
    
    if %MAX_FILES% LEQ 0 IF %LAST_DAYS% LEQ 0 (
      echo bad option
      echo usage: [folder] [pattern] [daysD or countN]
      endlocal
      echo.
      EXIT /B 1
    )
    
    :TEMP_NAME
    set TEMPI_FILE=%TEMP%\%~n0_I%RANDOM%.tmp
    set TEMPO_FILE=%TEMP%\%~n0_O%RANDOM%.tmp
    if exist %TEMPI_FILE% goto :TEMP_NAME
    if exist %TEMPO_FILE% goto :TEMP_NAME
    
    
    set TARGET_TIME=
    @rem 環境によっては「'FileSystem' プロバイダーで InitializeDefaultDrives 操作を実行しようとして失敗しました。」とエラー表示されるので、エラー出力を無視する
    if %LAST_DAYS% GTR 0 FOR /F "usebackq delims=" %%a in (`powershell "(get-date).AddDays(-%LAST_DAYS%).ToString(\"yyyy-MM-ddTHH:mm:ss\")"2^>nul`) do Set TARGET_TIME=%%a
    
    @rem if exist *.*は常にTRUEになるので、ファイルの数を数える
    @rem if not exist %FOLDER%\%PATERN% goto :DONE
    set /a COUNT=0
    for %DIRECTORY% %%a in ("%FOLDER%\%PATERN%") do set /a COUNT+=1 > NUL
    
    echo MAX_FILES=%MAX_FILES% LAST_DAYS=%LAST_DAYS% TARGET_TIME=%TARGET_TIME% COUNT=%COUNT%
    
    
    if %COUNT% equ 0 goto :DONE
    
    @rem ファイルのタイムスタンプを秒まで欲しいため、firfilesで出力させる
    @rem firfilesがUNCに対応していないので、一旦カレントディレクトリに変える
    @rem %0がパスを含んでいないこともあるので%~f0と記述
    pushd "%FOLDER%" && (
        forfiles /M "%PATERN%" /C "cmd /c %~f0 \"@fdateT@ftime\" @file @fsize %TEMPI_FILE%"
      popd
    )
    
    @rem 日数指定の場合は日時だけの行を追加しておく
    if not "%TARGET_TIME%" == "" echo "%TARGET_TIME%">> %TEMPI_FILE%
    
    @rem 逆順にソートする
    sort.exe /R %TEMPI_FILE% /O %TEMPO_FILE%
    if ERRORLEVEL 1 goto :SORT_ERR
    for %%f in (%TEMPO_FILE%) do (
      if %%~zf == 0 goto :SORT_ERR
      if "%%~zf" == "" goto :SORT_ERR
    )
    
    echo type %TEMPO_FILE%
    type %TEMPO_FILE%
    
    
    if not "%TARGET_TIME%" == "" goto :DAYS
    
    @rem 個数指定での削除
    set /a FILE_COUNT=0
    for /F "delims=" %%g in (%TEMPO_FILE%) do (
      set /a FILE_COUNT=!FILE_COUNT! + 1
      if !FILE_COUNT! GTR %MAX_FILES% (
        CALL :SUB_DELETE %%g
      )
    )
    goto :DONE
    
    :DAYS
    @rem 日付指定での削除
    @rem 日付のみのがあればそれ以降を削除する
    set DELETE=
    for /F "delims=" %%g in (%TEMPO_FILE%) do (
      if not "!DELETE!" == "" (
        CALL :SUB_DELETE %%g
      ) else (
        set FILE_TIME=%%g
        if "!FILE_TIME!" == ""%TARGET_TIME%"" (
    rem      echo delete point !FILE_TIME!
          set DELETE=1
        )
      )
    )
    goto :DONE
    
    
    :SUB_DELETE
      setlocal enabledelayedexpansion
      for /F "tokens=2 delims=+" %%b in (%1) do (
        set FILE=%%b
        set FILE=!FILE:"=!
    rem   echo dir "%FOLDER%\!FILE!"
    rem        dir "%FOLDER%\!FILE!"
        if "%DIRECTORY%" == "" (
          echo del "%FOLDER%\!FILE!"
               del "%FOLDER%\!FILE!"
        ) else (
          echo rd /S /Q "%FOLDER%\!FILE!"
               rd /S /Q "%FOLDER%\!FILE!"
        )
      )
      endlocal
    exit /b
    
    :SORT_ERR
    echo sort error
    if exist %TEMPI_FILE% del %TEMPI_FILE%
    if exist %TEMPO_FILE% del %TEMPO_FILE%
    endlocal
    echo.
    exit /b 1
    
    @rem 日付のフォーマットを/から-に変える。ファイルサイズを3桁区切りにする。
    @rem %4は無くてもいいが、同じバッチファイルを再利用するため4番目のパラメーターを使用する。
    :FORMAT
    setlocal enabledelayedexpansion
    
    @rem echo %0 %1 %2 %3 %4
    set fdatetime=%1
    set file=%2
    set len=%3
    set fdatetime=!fdatetime:/=-!
    if exist %~dp0PrintNum3.bat (
      for /F "usebackq" %%n in (`%~dp0PrintNum3.bat !len!`) do set len=%%n
    )
    rem echo !fdatetime!+!file!+"!len!"
    echo !fdatetime!+!file!+"!len!">> %4
    
    endlocal
    exit /b 0
    
    
    :DONE
    if exist %TEMPI_FILE% del %TEMPI_FILE%
    if exist %TEMPO_FILE% del %TEMPO_FILE%
    endlocal
    echo.
    
    EXIT /B 0
    
    :DONE
    if exist %TEMPI_FILE% del %TEMPI_FILE%
    if exist %TEMPO_FILE% del %TEMPO_FILE%
    endlocal
    echo.
    
    EXIT /B 0
    

    PrintNum3.bat

    @echo off
    if "%1" == "" (
      echo 0
      exit /b
    )
    
    setlocal enabledelayedexpansion
    set num=%1
    
    set /a len=0
    set num_t=%num%
    :LEN_LOOP
    if not "%num_t%" == "" (
      set num_t=%num_t:~1%
      set /a len=%len%+1
      goto :LEN_LOOP
    )
    
    set /a top_len=%len%%%3
    
    set num3=%num:~-3,3%
    
    if %len% gtr 3 (
      FOR /L %%i IN (6,3,%len%) DO call set num3=%%num:~-%%i,3%%,!num3!
      if %top_len% gtr 0 ( 
        call set num3=%%num:~0,%top_len%%%,!num3!
      )
    )
    
    echo %num3%
    
    endlocal
    exit /b

    qsort.bat、qsort2.bat

    DeleteOldFile.bat内でsort.exeを呼ぶようにしたので削除