[661]
Re:外部コマンド実行
ああああ
2001年08月31日 10:58
ソースコードをいろいろチェックしてみました。 CEditView.cpp の8072 行目: > hFile = ::CreateFile( szTempFile, > GENERIC_WRITE | GENERIC_READ, > FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, > CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); 8091行目: > StartupInfo.hStdOutput = hFile; > StartupInfo.hStdError = hFile; これでは、同一ハンドルのとき、閉じられるときデータが失われる可能性があると思います。 DuplicateHandle を使って、ハンドルの継承を何とかするとか。 > またcommand.comの実行時に16ビットサブシステムより「NTVDMはシステムエラーを検出しました。ハンドルが無効です」というエラーが出ます。 調べてみると、dir は標準エラー出力を使うみたいです。次のMS-DOSコマンドで確認できます。 C:\>dir >& test.txt C:\>type test.txt ドライブ C: のボリュームラベルはありません. ボリュームシリアル番号は 0623-0AF5 ディレクトリは C:\ 53,575,680 バイトの空きがあります. 他にも気になる点がいくつかあります。リファレンスによると: >lpSecurityAttributes > If you want the console to be inherited, > the bInheritHandle member of the > SECURITY_ATTRIBUTES structure must be TRUE. > >dwCreationDistribution > The user should specify OPEN_EXISTING when > using CreateFile to open the console. >The CreateProcess function's >fInheritHandles parameter must >be set to TRUE for this to work properly. とあります。コードを書くときにはよくリファレンスやコード例を参照した方がよろしいですよ。 > SECURITY_ATTRIBUTES 構造体の lpSecurityDescriptor > メンバとかにきちんとなんか設定しとかんとダメなんで > しょうかね SECURITY_ATTRIBUTES の lpSecurityDescriptor 以外のメンバは Win95/98 でも参照されるはずです。おそらくリファレンスの間違いです。 同じく 8108 行目。Windows 2000 では、3 つの DOS 窓が開きました。おそらくこの行の辺りから起こっています。 バージョンと ProcessInfo.hProcess をチェックすることをお勧めします。<stdlib.h> の _osver, _win{ver,major,minor} を使えば素早くバージョンをチェックできます。 <stdlib.h> から: >#define _osver (*__p__osver()) >#define _winver (*__p__winver()) >#define _winmajor (*__p__winmajor()) >#define _winminor (*__p__winminor()) これで WinNT/2000 で command.com を実行することは避けられます。 Windows 版の Mule のソースコードと、MSDN のコードサンプル: [Platform SDK]-[Reference]-[Code Samples]-{ [WINBASE]-{ [IO]-[ASYNCIO], [IPC]-[INHERIT] }, [WINUI]-[CONGUI] } には非同期入出力の例などがあって役に立つと思います。