これまでの解説として「Windows にメッセージを送るには ? (1)」 と
「Windows にメッセージを送るには ? (2)」 で目的が完結したかというと実はそうではない。
私達の目的はあくまでも System i から Windows にメッセージを送ることなのであるが
STRPCCMD を使うことは 5250エミュレータによって System i と接続中であることを前提と
しているのである。
読者に最初に紹介したように Webアプリケーションの場合はブラウザのみの接続であるので
PCOMM や C/A による 5250エミュレータの接続はないものとして考えなければいけないのである。
それではどのようにして Windows の NET SEND コマンドを起動するばよいのであろうか ?
読者は System i の NetServer (ネット・サーバー) をご存知だろうか ?
これは System i の IFS などを共有フォルダーとして Windowsエクスプローラに公開を許可するものである。
つまり NetServer 自身が NetBios を使用しているのである。
さらに NetServer 自身のいくつかの API が IBM によって公開されている。
そして、この利用方法が QUSRTOOL に収められているのである。
筆者は QUSRTOOL に収録されているソースにいくつかの改訂を加えたので結果をここに紹介する。
0001.00 CMD PROMPT('WINDOWS メッセージの送信 ')
0002.00 PARM KWD(MSG) TYPE(*CHAR) LEN(128) +
0003.00 PROMPT(' メッセージ・テキスト ')
0004.00 PARM KWD(TONETID) TYPE(E1) MIN(0) MAX(20) +
0005.00 PROMPT('Network ID')
0006.00 E1: ELEM TYPE(*CHAR) LEN(15) DFT('192.168.1.1') +
0007.00 MIN(0) MAX(1) PROMPT(' 宛先 IP アドレス ')
0008.00 ELEM TYPE(*CHAR) LEN(15) MIN(0) MAX(1) DFT(*NONE) +
0009.00 SPCVAL((*NONE)) +
0010.00 PROMPT(' システム名 ')
0001.00 PGM PARM(&MSGTXT &TONETID)
0002.00 /*---------------------------------------------------------*/
0003.00 /* SNDWINMSG : WINDOWS へのメッセージの送信 */
0004.00 /*---------------------------------------------------------*/
0005.00 /*--------------------------------------------------------
0006.00 /* Declares needed for this program
0007.00 /*--------------------------------------------------------
0008.00 DCL VAR(&MSGTXT) TYPE(*CHAR) LEN(128)
0009.00 DCL VAR(&TONETID) TYPE(*CHAR) LEN(700)
0010.00 DCL VAR(&NETSYSNAME) TYPE(*CHAR) LEN(30)
0011.00 DCL VAR(&NETWORK) TYPE(*CHAR) LEN(15)
0012.00 DCL VAR(&SYSTEM) TYPE(*CHAR) LEN(15)
0013.00 DCL VAR(&INDEX1) TYPE(*DEC) LEN(4) VALUE(1)
0014.00 DCL VAR(&INDEX2) TYPE(*DEC) LEN(4) VALUE(1)
0015.00 DCL VAR(&NBRTOSEND) TYPE(*DEC) LEN(4)
0016.00 DCL VAR(&NEXTOFFLOC) TYPE(*DEC) LEN(4)
0017.00 DCL VAR(&NEXTOFFSET) TYPE(*DEC) LEN(4)
0018.00 DCL VAR(&IPADR) TYPE(*CHAR) LEN(15)
0019.00 DCL VAR(&OS400) TYPE(*CHAR) LEN(6)
0020.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1)
0021.00 DCL VAR(&RTNVALUE) TYPE(*CHAR) LEN(256)
0022.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(80)
0023.00
0024.00 /*--------------------------------------------------------
0025.00 /* Constants needed for this program
0026.00 /*--------------------------------------------------------
0027.00 DCL VAR(&BLANK) TYPE(*CHAR) LEN(1) VALUE(' ')
0028.00 DCL VAR(&HEXZERO) TYPE(*CHAR) LEN(1) VALUE(X'00')
0029.00
0030.00
0031.00 /*--------------------------------------------------------
0032.00 /* Start of the executable code for the program.
0033.00 /*--------------------------------------------------------
0034.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
0035.00
0036.00 RTVJOBA TYPE(&TYPE)
0037.00 RTVDTAARA DTAARA(QGPL/QSS1MRI (1 6)) RTNVAR(&OS400)
0038.00 IF COND(&OS400 *LT 'V5R1M0') THEN(DO)
0039.00 CHGVAR VAR(&MSG) +
0040.00 VALUE('SNDWINMSG の実行は V5R1M0 以上が必 +
0041.00 要です。 ')
0042.00 IF COND(&TYPE *EQ '0') THEN(DO)
0043.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)
0044.00 ENDDO
0045.00 ELSE CMD(DO)
0046.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*TOPGMQ) MSGTYPE(*DIAG)
0047.00 ENDDO
0048.00 RETURN
0049.00 ENDDO
0050.00 /*--------------------------------------------------------
0051.00 /* Break the TOUSER parameter into the network name and
0052.00 /* system name parts. Only move the non-blank part of
0053.00 /* the network and system names.
0054.00 /*--------------------------------------------------------
0055.00 CHGVAR &NBRTOSEND %BINARY(&TONETID 1 2)
0056.00 IF (&NBRTOSEND = 0) THEN(GOTO SENDALL)
0057.00 CHGVAR &NEXTOFFLOC 3
0058.00 LOOP1: IF (&INDEX1 > &NBRTOSEND) THEN(GOTO SENDDONE)
0059.00 CHGVAR &NEXTOFFSET %BINARY(&TONETID &NEXTOFFLOC 2)
0060.00 CHGVAR &NEXTOFFSET (&NEXTOFFSET+3)
0061.00 CHGVAR &NETSYSNAME %SST(&TONETID &NEXTOFFSET 30)
0062.00 CHGVAR &INDEX2 1
0063.00 LOOP2: IF (&INDEX2 > 30) THEN(GOTO ENDLOOP)
0064.00 IF (%SST(&NETSYSNAME &INDEX2 1) = &BLANK) +
0065.00 THEN(CHGVAR %SST(&NETSYSNAME &INDEX2 1) &HEXZERO)
0066.00 CHGVAR &INDEX2 (&INDEX2+1)
0067.00 GOTO LOOP2
0068.00 ENDLOOP: CHGVAR &IPADR %SST(&NETSYSNAME 1 15)
0069.00 CHGVAR &SYSTEM %SST(&NETSYSNAME 16 15)
0070.00
0071.00 IF COND(&IPADR *EQ '*IPADR') THEN(DO)
0072.00 ASNET.COM/GETENV ENV(REMOTE_ADDR) VALUE(&RTNVALUE)
0073.00 CHGVAR VAR(&IPADR) VALUE(%SST(&RTNVALUE 1 15))
0074.00 ENDDO
0075.00 ADDENVVAR ENVVAR(REMOTE_ADDR) VALUE(&IPADR)
0076.00 MONMSG MSGID(CPFA980) EXEC(DO)
0077.00 CHGENVVAR ENVVAR(REMOTE_ADDR) VALUE(&IPADR)
0078.00 ENDDO
0079.00 CHGVAR VAR(&NETWORK) VALUE(&IPADR)
0080.00 CALL PGM(ASNET.COM/RTVWSID) PARM(&NETWORK)
0081.00 IF COND(%SST(&NETWORK 1 5) *EQ '*NONE') THEN(DO)
0082.00 SNDPGMMSG MSG('SNDWINMSG [' *CAT &IPADR *TCAT '] ' +
0083.00 *CAT &MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)
0084.00 RETURN
0085.00 ENDDO
0086.00 IF (%SST(&SYSTEM 1 5) = '*NONE') +
0087.00 THEN(CALL PGM(QZLSMAINT) PARM('30' &NETWORK &MSGTXT))
0088.00 ELSE (CALL PGM(QZLSMAINT) PARM('37' &NETWORK &SYSTEM
0089.00 CHGVAR &NEXTOFFLOC (&NEXTOFFLOC+2)
0090.00 CHGVAR &INDEX1 (&INDEX1+1)
0091.00 GOTO LOOP1
0092.00 SENDDONE:
0093.00 IF COND(&TYPE *EQ '1') THEN(DO) /* 対話式 */
0094.00 CHGVAR VAR(&MSG) VALUE(' メッセージを ' *CAT +
0095.00 &IPADR *TCAT ' に送信しました。 ')
0096.00 GOTO SNDMSG
0097.00 ENDDO /* 対話式 */
0098.00 RETURN
0099.00
0100.00 SENDALL: CALL PGM(QZLSMAINT) PARM('30' *ALL &MSGTXT)
0101.00 RETURN
0102.00
0103.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG)
0104.00 SNDMSG:
0105.00 IF COND(&TYPE *EQ '0') THEN(DO)
0106.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*SYSOPR) MSGTYPE(*COMP)
0107.00 ENDDO
0108.00 ELSE CMD(DO)
0109.00 SNDPGMMSG MSG(&MSG) TOMSGQ(*TOPGMQ) MSGTYPE(*DIAG)
0110.00 ENDDO
0111.00 ENDPGM
EnterpriseServer Ver5.0 では、このSNDWINMSG を使ってサーバー側の障害が発生したときは
直ちにクライアントへエラー・メッセージが表示される仕組みとなっている。
またユーザーでも、このSNDWINMSG をユーザーの適用業務へ組み込むことができるように
公開もされている。