外部コマンドをVZの子プロセスで実行するには,編集モードから一旦コマンドラインモードに降りる必要があります。コマンドラインに降りるコマンドは#E
(外部コマンドの実行=#78
)で,そのコマンドラインは純粋のDOSとは異なり,複数のコマンドをセミコロンで区切って順次実行できたり,ヒストリーが使えたり,色々と便利になっています。
次の例は,カレントディレクトリのファイルのリストをソートしてカーソル位置に挿入する例です。コマンドはDIRとSORTとSEDを使っています。
1 ^^ "" ?.
(mr==$80)?.
#E ;▼コマンドラインに降りる
"DIR >tmp0.tmp" #m
"SED -e $"/[0-9]+ [0-9]+-[0-9]+-[0-9]+/!d$" tmp0.tmp > tmp1.tmp" #m
"SORT <tmp1.tmp >tmp0.tmp" #m
#[ ;△エスケープコマンドで編集画面に戻る
#R "tmp0.tmp" #m
(s)?{ 'n' #[ }?{ #b #_ #y #C #i }
#E ;▼
"Del tmp?.tmp" #m ;作業ファイルの一括削除
#[ ;△
&d #] .
この例では,コマンドの先頭が大文字になっています。コマンドの先頭文字を大文字で記述すると,VZが使用しているメモリ領域を一時ファイルにスワップして基本メモリ領域を解放するため,比較的大きなコマンド/プログラムがメモリ不足で実行できないという問題を回避できます。
なお,スワップモードはオプションSWによって設定されます。初期値は上限値の3で,外部コマンドを極力実行できるようになっていますが,0〜2の値に変更している場合は外部コマンド実行時にメモリ不足に陥る可能性がありますので,初期値の3に戻すことをお奨めします。
コマンドラインで Dir [drv] すれば確認できます。…って,これじゃあんまりですよね。ファンクションコールを使うと編集モードにいながらにして,指定ドライブの使用済/空き容量を確認することができます。
= DskSpc = by H_ear
#if 0
int21_3600
ax:セクタ数/クラスタ
bx:空きクラスタ数
cx:バイト数/セクタ
dx:クラスタ数/ドライブ
#endif
* mad for vz!
1 ^\ "" ?.
&> i-, (3){ &Im(a+i,0) i+=4, }
!01 (r<0)?. d=dx=r, ;drive letter / current=@
ax=$3600, &i($21)
&Ia(a,ax) &Im(a,cx) &Im(a,dx) ;a ドライブ全容量
&Ia(b,ax) &Im(b,bx) &Im(b,cx) ;b 未使用
&Le(c,a) &Ls(c,b) ;c 使用済み
&m("%c: %,lu−%,lu=%,lu [ax=%u,bx=%u,cx=%u,dx=%u]",
d+$40,a..0,a..1,c..0,c..1,b..0,b..1,ax,bx,cx,dx)
0: c4 +b4 +a3+$,."aaaabbbbcccc"
* pmenu
1 "Drive",8,5
"current" "A Drive" "B Drive" "C Drive" "D drive"
*
2ギガを超えるドライブである場合は,Windowsで拡張されたファンクションコールを使用します。
= DrvSpc2.def v0.20 = by H_ear
#if 0
拡張ファンクションコールint21_7303を利用した2GBを超えるドライブ情報取得
#endif
* mad for vz!
1 ^\ "" ?. &> i-, (16){ &Im(a+i,0) i+=4, }
!01 (r<0)?. ;drive
dx=pm, ;ds:dx / ds==gz (Vzのマクロバッファ)
di=e, ;es:di / es==gz 同上
cx=44, ;buf size
ax=$7303, &i($21) ;拡張ファンクションコール
(ax==-1)?{ &m(41) . } ;ドライブが準備できていないと終了
f=e..2*e..4/1024, ;4GBで32ビットを溢れるため単位をKBにする
&Le(a,e+16) &Im(a,f) ;a ドライブ全容量
&Le(b,e+12) &Im(b,f) ;b 未使用
&Le(c,a) &Ls(c,b) ;c 使用済み
&m("[%s] 全容量:%,luKB / 使用済:%,luKB / 未使用:%,luKB",
pm,a..0,a..1,c..0,c..1,b..0,b..1)
0: e4 +c4 +b4 +a3+$,."$[64]"
* pmenu
1 "Drive",5,7
"A:\" "B:\" "C:\" "D:\" "E:\" "F:\" "G:\"
*
[Variables]
a dword ドライブ全容量(KB)
b dword 未使用(KB)
c dword 使用済み(KB)
e 構造体先頭アドレス
f クラスタあたりのバイト数(KB)
i counter
[Buffers]
pm drive letter
0: {4*3}a,b,c,{44}e,{8}
[History]
2000/12/18 0.10 int21_3600を利用したdskspc.def初版
2000/12/25 0.20 int21_7303を利用した2GB超のドライブ情報取得 dskspc2.def
2003/02/01 drvspc2.defに改称
[Notes]
拡張ファンクションコールint21_7303
ds:dx ドライブを指定するASCIZ文字列アドレス
es:di 結果を返す構造体の番地
cx 結果を返す構造体のサイズ(bytes)
構造体:(指定したアドレスに用意したバッファに書き込まれる)
Offset Size Description
00h WORD 構造体のサイズ
02h WORD 構造体のバージョン?
04h DWORD セクタ数/クラスタ
08h DWORD バイト数/セクタ
0Ch DWORD 空きクラスタ数
10h DWORD 総クラスタ数
14h DWORD 空きセクタ数
18h DWORD 総セクタ数
1Ch DWORD 空きアロケーションユニット数(圧縮ドライブ?)
20h DWORD 総アロケーションユニット数(圧縮ドライブ?)
24h 8 oct. 予約領域
次のマクロは,和生師匠が高橋洋光先生の部品(nifty:fgalpk/mes/14/16703)を応用して作成したものです。出典は(nifty:fgaldc/mes/15/05823)です。
=T1.ドライブ接続状況 PK (13) #16703 【int24h のフック】 *m 80^\""?. &> p=r+17,a1, &01 v4*$24, dz[-,b=v..0,c=v..1,v..0=r,v..1=gz,dz], :a dx=a,ax$3600,&i($21) (x=r)?{p.a=a+'`',>b} (ax<0)?p.a='_',?p.a=a+'@', :b (a++<27)?>a dz[-,v..0=b,v..1=c,dz], &m("%s",p-17) 0: (3+$)."connected drive > $[26] CAP's ready !!" 1: ;------- by H.Takahashi (3+$)."$ $(8B,F4,36,80,4C,1C,01,58,58,58,58,5B,59,5A,5E,5F)$ $(5D,1F,07,CF)" *
以下のマクロはネットワークコマンドを使用するサンプルです。ネットワークの端末名称などは架空のものですので,このまま実行することはできません。(このマクロが実行できた環境は,Windows 2000 の時代のものです。新しい環境で実行できるかどうかは,実際にコマンドを実行して判断する必要があります。コマンドが実行できる場合は,マクロの &m() を #E &?() #m のように書き換えることで利用できます。)
= NetDrive v0.01 = by H_ear
* mad for vz!
1 ^\ "" ?.
!01
(r<0)?.
(r>10)?{ &m("Net use * /delete") >z }
(r)
?{ &m("Net use * \\%s",pm+2) }
?{ >02 }
:z &d #] .
2 "" ?.
&> p=r, i=p.4, ;[p]tr, [i]tems
p+=7+2+i*2, ;メニューヘッダのもろもろ
&Sc(pa,p) p+=1+r-pa, ;文字列長を測定 ;(*)と違ってここはタイトル
(i-2){ ;A,D を除外
&Sc(pa,p) p+=1+r-pa, ;(*) 0番アイテムはスキップ
&m("net use * \\%s",p+2) ;net cmd 発行
&w(60)
}
&m("Net use") ;接続状況を一覧表示
0: (2+$)
* p
1 "Network Drive",16,12
"A すべて割当"
"1 庶務課1\C" "2 庶務課2\C" "3 経理課1\C"
"4 資料一課1\C" "5 資料一課2\C" ;自分が"資料一課3"
"6 資料二課1\C" "7 資料二課2\D" "8 資料二課3\C"
"9 調査課1\C" "0 資料室1\C"
"D すべて切断"
*