by 7 » 2007年5月27日(日) 21:05
> 実行できているとばかり思っていました…(汗)
あ。よく分かんないんですけど、そっちのでも出来るみたいです...。
ネットに落ちてるサンプルコードを見てみるとtomoさんのコードになっているのもありました。
> さすがにエディットボックスに直に表示はできませんか…
> (出力垂れ流しなはずだし、そのまま表示くらい…と思っていたのですが。甘かったですな…)
コンソールアプリケーションが流すデータをパイプを通して奪い取り、それを変数に確保、そのデータをエディットボックスに出力、といった形になるようです。
いまはまだちゃんと実装できていないのですが、以下のサンプルを参考に一応頑張っています...。
誰かサクっと実装できる方いませんか?
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
//名前なしパイプ作成
SECURITY_ATTRIBUTES sa;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
HANDLE hRead, hWrite;
if(!CreatePipe(&hRead, &hWrite, &sa, 0))
return 0;
//プロセス作成
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOWDEFAULT;
si.hStdOutput = hWrite;
//ping 実行
if(CreateProcess(NULL, "ping localhost", NULL, NULL, TRUE, 0, NULL, NULL, &si, π)) {
WaitForInputIdle(pi.hProcess, INFINITE);
//プロセス待機
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
//パイプから結果を読み出す
DWORD dwAvail;
if(PeekNamedPipe(hRead, NULL, 0, NULL, &dwAvail, NULL) && dwAvail > 0) {
char szOut[1024];
ZeroMemory(szOut, sizeof(szOut));
DWORD dwRead;
if(ReadFile(hRead, szOut, sizeof(szOut) - 1, &dwRead, NULL)) {
MessageBox(NULL, szOut, NULL, 0);
}
}
}
CloseHandle(hRead);
CloseHandle(hWrite);
return 0;
}
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
BOOL ConsolExec( CHAR *strCom )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD dwExitCode;
DWORD dwRet;
HANDLE hProc;
CHAR strPath[ MAX_PATH ];
CHAR strCmd[ MAX_PATH ];
CHAR strExec[ MAX_PATH ];
BOOL bRet;
// 環境変数COMSPECの文字列を取得
GetEnvironmentVariable( "COMSPEC" , strCmd , sizeof(strCmd) );
// CreateProcessに渡せる"cmd.exe /c xxxxxx"or"command.com /c xxxxxx"の形を作成
wsprintf( strExec , "%s /c %s" , strCmd , strCom );
// SECURITY_ATTRIBUTES 構造体の設定
memset( &sa , 0 , sizeof( SECURITY_ATTRIBUTES ) );
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;// ハンドルを継承する
// STARTUPINFO 構造体の設定
memset( &si , 0 , sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = STARTF_USESHOWWINDOW;//STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = NULL;// ここを自前で指定すれば出力結果を得られる
si.hStdOutput = NULL;//
si.hStdError = NULL;//
// 現在のディレクトリパスを取得
GetCurrentDirectory( sizeof(strPath) , strPath );
// 別プロセスで実行させる
if( CreateProcess( NULL , strExec , NULL , NULL , FALSE , 0 , NULL , NULL , &si , π ) == FALSE ){
// エラー発生
LPVOID lpMsgBuf;
// エラー内容の表示
dwRet = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL , dwRet, LANG_USER_DEFAULT, (LPTSTR)&lpMsgBuf , 0, NULL );
MessageBox( NULL , (LPTSTR)lpMsgBuf , "Error" , MB_OK|MB_ICONINFORMATION );
bRet = FALSE;
}else{
// 正常
hProc = pi.hProcess;
// コマンド終了まで待つ、n秒以内に終了しないと強制終了させる。INFINITEはずっと待つ
if( WaitForSingleObject( hProc , INFINITE ) == WAIT_FAILED ){
GetExitCodeProcess( hProc , &dwExitCode );
}
bRet = TRUE;
}
// ハンドル開放
if( hProc ){
CloseHandle( hProc );
hProc = NULL;
}
return bRet;
}
[ここをクリックすると内容が表示されます] [ここをクリックすると非表示にします]コード: 全て選択
/* API登録 */
#uselib "kernel32.dll"
#func CreatePipe "CreatePipe" sptr,sptr,sptr,sptr
#func CloseHandle "CloseHandle" sptr
#func CreateProcessA "CreateProcessA" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#func ReadFile "ReadFile" sptr,sptr,sptr,sptr,sptr
/* 各種定数 */
#const TRUE 1
#const FALSE 0
#const NULL 0
#define NAME_CB_EXE "cb.exe"
#const SIZE_SEC_ATTR 12 // SECURITY_ATTRIBUTES構造体サイズ
// STARTUPINFO構造体パラメータ
#const SIZE_SUP_INFO 68 // STARTUPINFO構造体サイズ
#const STARTF_USESHOWWINDOW 0x00000001 // パラメータ使用フラグ(ウィンドウ表示状態)
#const STARTF_USESTDHANDLES 0x00000100 // パラメータ使用フラグ(標準出入力ハンドル)
#const SW_HIDE 0 // 起動時ウィンドウを表示しない
#const SIZE_BUF 1024 // ReadFile読み取りサイズ上限
/************/
/* 処理本体 */
/************/
mydir = dir_cur // このスクリプトの起動ディレクトリ
/* 名無しパイプ作成 */
secAttr = SIZE_SEC_ATTR, NULL, TRUE // SECURITY_ATTRIBUTES構造体
CreatePipe varptr(hRead),varptr(hWrite),varptr(secAttr),0
if stat=FALSE {
dialog "パイプの作成に失敗しました。スクリプトを終了します。", 1, "エラー"
end
}
/* パイプの書き込み側を標準出力につないでcb.exeを起動 */
cmdline = mydir + "\\" + NAME_CB_EXE
// STARTUPINFO構造体
supInfo = SIZE_SUP_INFO, NULL, NULL, NULL
supInfo(4) = 0, 0, 0, 0
supInfo(8) = 0, 0, NULL, STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES
supInfo(12) = SW_HIDE, NULL, NULL, hWrite, NULL
// PROCESS_INFOMATION構造体
dim procInfo,4
// cb.exeを起動
CreateProcessA NULL,cmdline,0,0,TRUE,NULL,NULL,NULL,varptr(supInfo),varptr(procInfo)
/* cb.exe起動のエラーチェック */
if stat=FALSE {
CloseHandle hWrite // パイプの書き込み側ハンドルを閉じる
dialog NAME_CB_EXE + "の起動に失敗しました。スクリプトを終了します。", 1, "エラー"
goto *@f
}
/* パイプの書き込み側ハンドルを閉じる(スクリプトでは使わない) */
CloseHandle hWrite
/* cb.exe関連のハンドルを閉じる(スクリプトでは使わない) */
CloseHandle procInfo(0)
CloseHandle procInfo(1)
/* パイプからcb.exeの出力を読み取る */
outbuf = "" // 出力受け取り用バッファ
size = 0 // ReadFile読み取りサイズ
repeat
sdim buf,SIZE_BUF+1 // ReadFile用バッファ
ReadFile hRead,varptr(buf),SIZE_BUF,varptr(size),NULL
if stat { // ReadFile成功
if size=0 { // 読み取り完了
break
}
outbuf += buf
}
else { // ReadFile失敗
break
}
loop
*@
/* パイプの読み取り側ハンドルを閉じる */
CloseHandle hRead
/* 結果表示 */
dialog "\""+outbuf+"\"",,"処理結果"
end
> 実行できているとばかり思っていました…(汗)
あ。よく分かんないんですけど、そっちのでも出来るみたいです...。
ネットに落ちてるサンプルコードを見てみるとtomoさんのコードになっているのもありました。
> さすがにエディットボックスに直に表示はできませんか…
> (出力垂れ流しなはずだし、そのまま表示くらい…と思っていたのですが。甘かったですな…)
コンソールアプリケーションが流すデータをパイプを通して奪い取り、それを変数に確保、そのデータをエディットボックスに出力、といった形になるようです。
いまはまだちゃんと実装できていないのですが、以下のサンプルを参考に一応頑張っています...。
誰かサクっと実装できる方いませんか?
[hide][code]int APIENTRY WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
//名前なしパイプ作成
SECURITY_ATTRIBUTES sa;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE;
HANDLE hRead, hWrite;
if(!CreatePipe(&hRead, &hWrite, &sa, 0))
return 0;
//プロセス作成
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOWDEFAULT;
si.hStdOutput = hWrite;
//ping 実行
if(CreateProcess(NULL, "ping localhost", NULL, NULL, TRUE, 0, NULL, NULL, &si, π)) {
WaitForInputIdle(pi.hProcess, INFINITE);
//プロセス待機
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
//パイプから結果を読み出す
DWORD dwAvail;
if(PeekNamedPipe(hRead, NULL, 0, NULL, &dwAvail, NULL) && dwAvail > 0) {
char szOut[1024];
ZeroMemory(szOut, sizeof(szOut));
DWORD dwRead;
if(ReadFile(hRead, szOut, sizeof(szOut) - 1, &dwRead, NULL)) {
MessageBox(NULL, szOut, NULL, 0);
}
}
}
CloseHandle(hRead);
CloseHandle(hWrite);
return 0;
}[/code][/hide][hide][code]BOOL ConsolExec( CHAR *strCom )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
SECURITY_ATTRIBUTES sa;
DWORD dwExitCode;
DWORD dwRet;
HANDLE hProc;
CHAR strPath[ MAX_PATH ];
CHAR strCmd[ MAX_PATH ];
CHAR strExec[ MAX_PATH ];
BOOL bRet;
// 環境変数COMSPECの文字列を取得
GetEnvironmentVariable( "COMSPEC" , strCmd , sizeof(strCmd) );
// CreateProcessに渡せる"cmd.exe /c xxxxxx"or"command.com /c xxxxxx"の形を作成
wsprintf( strExec , "%s /c %s" , strCmd , strCom );
// SECURITY_ATTRIBUTES 構造体の設定
memset( &sa , 0 , sizeof( SECURITY_ATTRIBUTES ) );
sa.nLength = sizeof( SECURITY_ATTRIBUTES );
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;// ハンドルを継承する
// STARTUPINFO 構造体の設定
memset( &si , 0 , sizeof( STARTUPINFO ) );
si.cb = sizeof( STARTUPINFO );
si.lpDesktop = NULL;
si.lpTitle = NULL;
si.dwFlags = STARTF_USESHOWWINDOW;//STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
si.hStdInput = NULL;// ここを自前で指定すれば出力結果を得られる
si.hStdOutput = NULL;//
si.hStdError = NULL;//
// 現在のディレクトリパスを取得
GetCurrentDirectory( sizeof(strPath) , strPath );
// 別プロセスで実行させる
if( CreateProcess( NULL , strExec , NULL , NULL , FALSE , 0 , NULL , NULL , &si , π ) == FALSE ){
// エラー発生
LPVOID lpMsgBuf;
// エラー内容の表示
dwRet = GetLastError();
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL , dwRet, LANG_USER_DEFAULT, (LPTSTR)&lpMsgBuf , 0, NULL );
MessageBox( NULL , (LPTSTR)lpMsgBuf , "Error" , MB_OK|MB_ICONINFORMATION );
bRet = FALSE;
}else{
// 正常
hProc = pi.hProcess;
// コマンド終了まで待つ、n秒以内に終了しないと強制終了させる。INFINITEはずっと待つ
if( WaitForSingleObject( hProc , INFINITE ) == WAIT_FAILED ){
GetExitCodeProcess( hProc , &dwExitCode );
}
bRet = TRUE;
}
// ハンドル開放
if( hProc ){
CloseHandle( hProc );
hProc = NULL;
}
return bRet;
}[/code][/hide][hide][code]/* API登録 */
#uselib "kernel32.dll"
#func CreatePipe "CreatePipe" sptr,sptr,sptr,sptr
#func CloseHandle "CloseHandle" sptr
#func CreateProcessA "CreateProcessA" sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr,sptr
#func ReadFile "ReadFile" sptr,sptr,sptr,sptr,sptr
/* 各種定数 */
#const TRUE 1
#const FALSE 0
#const NULL 0
#define NAME_CB_EXE "cb.exe"
#const SIZE_SEC_ATTR 12 // SECURITY_ATTRIBUTES構造体サイズ
// STARTUPINFO構造体パラメータ
#const SIZE_SUP_INFO 68 // STARTUPINFO構造体サイズ
#const STARTF_USESHOWWINDOW 0x00000001 // パラメータ使用フラグ(ウィンドウ表示状態)
#const STARTF_USESTDHANDLES 0x00000100 // パラメータ使用フラグ(標準出入力ハンドル)
#const SW_HIDE 0 // 起動時ウィンドウを表示しない
#const SIZE_BUF 1024 // ReadFile読み取りサイズ上限
/************/
/* 処理本体 */
/************/
mydir = dir_cur // このスクリプトの起動ディレクトリ
/* 名無しパイプ作成 */
secAttr = SIZE_SEC_ATTR, NULL, TRUE // SECURITY_ATTRIBUTES構造体
CreatePipe varptr(hRead),varptr(hWrite),varptr(secAttr),0
if stat=FALSE {
dialog "パイプの作成に失敗しました。スクリプトを終了します。", 1, "エラー"
end
}
/* パイプの書き込み側を標準出力につないでcb.exeを起動 */
cmdline = mydir + "\\" + NAME_CB_EXE
// STARTUPINFO構造体
supInfo = SIZE_SUP_INFO, NULL, NULL, NULL
supInfo(4) = 0, 0, 0, 0
supInfo(8) = 0, 0, NULL, STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES
supInfo(12) = SW_HIDE, NULL, NULL, hWrite, NULL
// PROCESS_INFOMATION構造体
dim procInfo,4
// cb.exeを起動
CreateProcessA NULL,cmdline,0,0,TRUE,NULL,NULL,NULL,varptr(supInfo),varptr(procInfo)
/* cb.exe起動のエラーチェック */
if stat=FALSE {
CloseHandle hWrite // パイプの書き込み側ハンドルを閉じる
dialog NAME_CB_EXE + "の起動に失敗しました。スクリプトを終了します。", 1, "エラー"
goto *@f
}
/* パイプの書き込み側ハンドルを閉じる(スクリプトでは使わない) */
CloseHandle hWrite
/* cb.exe関連のハンドルを閉じる(スクリプトでは使わない) */
CloseHandle procInfo(0)
CloseHandle procInfo(1)
/* パイプからcb.exeの出力を読み取る */
outbuf = "" // 出力受け取り用バッファ
size = 0 // ReadFile読み取りサイズ
repeat
sdim buf,SIZE_BUF+1 // ReadFile用バッファ
ReadFile hRead,varptr(buf),SIZE_BUF,varptr(size),NULL
if stat { // ReadFile成功
if size=0 { // 読み取り完了
break
}
outbuf += buf
}
else { // ReadFile失敗
break
}
loop
*@
/* パイプの読み取り側ハンドルを閉じる */
CloseHandle hRead
/* 結果表示 */
dialog "\""+outbuf+"\"",,"処理結果"
end[/code][/hide]