【JP1/AJS3】Windows 環境でバッチ処理のエラーを検出する

## 実行ファイルの設計方針

※[実行ファイルを設計する][], [実行できるコマンド][] を参考

------

### JP1/AJS3 で使用できる形式とする

- 実行形式ファイル (`.exe`, `.com`, `.cmd`)
- バッチファイル (`.bat`)
- JP1/Script で作成したスクリプトファイル (`.spt`)
  - ※ただし，`.spt` ファイルが実行できるよう関連づけが設定されていること
- 自動アクションで実行できるアプリケーションに関連づけられているファイルタイプ (拡張子) を持つデータファイル (`.vbs` 等)

------

#### 実行できないコマンド

- 対話操作を必要とするコマンド
- 画面を表示するコマンド
- エスケープシーケンスや制御コードを伴うコマンド
- デーモンなどの，終了しないコマンド
- Windows メッセージ機構や DDE など，デスクトップとの対話が必要なコマンド (Windowsの場合)
- `shutdown` や `halt` など，OSをシャットダウンするコマンド

------

### 画面やメッセージによる応答が発生しない処理にする

- JP1/AJS3 のジョブで実行されるファイルはバックグラウンドで実行されるため、画面やメッセージが表示されて応答待ちの状態にならない処理する。
  - MsgBox や WScript.Echo でメッセージ表示をしているバッチは「実行中」のステータスのままジョブが終了しない。

------

### リターンコードを出力する処理にする

- JP1/AJS3 では処理の結果を、実行ファイルのリターンコードによって判定する。したがって、処理結果に応じたリターンコードが出力されるように実行ファイルを作成する。
  - システムエラー発生時にジョブのステータスが「実行中」のままになる。
  - システムエラー発生時に処理を続行しエラーナンバーをリターンコードとして返すようにする。
- 出力されるリターンコードの数値がどの範囲で警告終了、異常終了とするのかという**しきい値**を決めておいく。

------

### バッチファイルによる処理の場合 (Windows 限定)

- Windows バッチファイルによる処理の場合、jp1exec, jp1exit コマンドをセットで使用してバッチファイル内の実行プログラムの処理結果に応じたリターンコードが出力されるようにする。
- また、コマンドが異常終了した場合に原因を分析できるように、要因となったリターンコードがそのまま出力されるようにしてください。

※ jp1exit, jp1exec コマンドの詳細は [jp1exec（Windows限定）][], [jp1exit（Windows限定）][] を参照。

------

## 実装方法詳細

以下に実行バッチの種類ごとの詳細を記載する。

------

### VBScript (.vbs)

- システムエラー発生時にエラー番号をリターンコードとして返す。
- Windows バッチファイルで jp1exec, jp1exit コマンドを使用してファイルを呼出す。

------

###### .vbs ファイル

```vb

'' エラー発生時にも処理を続行するように設定
On Error Resume Next

'' ~~~ 処理 ~~~

'' エラーが発生したか判別
If Err.Number > 0 Then
    '' リターンコードにエラー番号を指定
    Wscript.Quit(Err.Number)
End If

'' リターンコードに 0 を指定
WScript.Quit(0)
```

------

###### .bat ファイル 

```shell
jp1exec CMD.EXE /C ".\XXXXXX.vbs"
jp1exit -ec %ERRORLEVEL%
```

------

### WSH (.wsf)

- システムエラー発生時にエラー番号をリターンコードとして返す。
- Windows バッチファイルで jp1exec, jp1exit コマンドを使用してファイルを呼出す。

------

###### .wsf ファイル

```xml
<?XML version="1.0" encoding="shift_jis" standalone="yes" ?>
<package>
  <job>
    <script language="vbscript">
'' エラー発生時にも処理を続行するように設定
On Error Resume Next

'' ~~~ 処理 ~~~

'' エラーが発生したか判別
If Err.Number > 0 Then
    '' リターンコードにエラー番号を指定
    Wscript.Quit(Err.Number)
End If

'' リターンコードに 0 を指定
WScript.Quit(0)
    </script>
  </job>
</package>
```

------

###### .bat ファイル 

```shell
jp1exec CMD.EXE /C ".\XXXXXX.wsf"
jp1exit -ec %ERRORLEVEL%
```

------

## Powershell (.ps1)

※[実行できるコマンド][] より抜粋
Windows PowerShell スクリプトをコマンド、または自動アクションから実行した場合、powershell.exe が終了しない状態となり、実行中のままになることがあります。
Windows PowerShell スクリプトを実行する場合は、次のようにコマンドラインの標準入力で「nul」をリダイレクトして、実行できる状態にしてください。

```shell
powershell.exe xxx.ps1 < nul
```

------

###### .ps1 ファイル

```powershell
# エラー発生時に処理を中断するように設定
$ErrorActionPreference = "Stop"

try {
	# ~~~ 処理 ~~~

	# リターンに 0 を指定
  	return 0
} catch {
    # リターンにエラー番号を指定
    return $_.Exception.HResult
}
```

------

###### .bat ファイル 

```shell
jp1exec powershell "exit .\XXXXXX.ps1" < nul
jp1exit -ec %ERRORLEVEL%
```

------

# 参考サイト

- JP1/Integrated Management - Manager 導入・設計ガイド
  - [実行できるコマンド][]
- JP1/Automatic Job Management System 3 設計ガイド
  - [実行ファイルを設計する][]
- JP1/Automatic Job Management System 2 コマンドリファレンス
  - [jp1exec（Windows限定）][]
  - [jp1exit（Windows限定）][]
- [呼び出し元のバッチに戻り値を返す方法][]

------

[実行ファイルを設計する]: http://itdoc.hitachi.co.jp/manuals/3020/30203S0433/AJSG0013.HTM
[実行できるコマンド]: http://itdoc.hitachi.co.jp/manuals/3021/30213A0730/IMDS0185.HTM
[jp1exec（Windows限定）]: http://itdoc.hitachi.co.jp/manuals/3020/30203K2543/AJSO0099.HTM
[jp1exit（Windows限定）]: http://itdoc.hitachi.co.jp/manuals/3020/30203K2543/AJSO0100.HTM
[呼び出し元のバッチに戻り値を返す方法]: https://bayashita.com/p/entry/show/132
[バッチファイルを終了するときは exit ではなく exit /B を使おう]: http://piyopiyocs.blog115.fc2.com/blog-entry-884.html
[Pythonでプログラムの終了コードを指定する]: https://tokibito.hatenablog.com/entry/20151002/1443793867
[JP1からだとバッチが実行できない！？]: https://www.ashisuto.co.jp/jp1blog/article/201801_ajs3_desktop.html