
No.7ベストアンサー
- 回答日時:
WinSockでpingっていうと…
「WinSock2.0プログラミング―Window Socket APIによるネットワークプログラミングのすべて」(江村 豊 監修 ソフトバンク ISBN4-7973-0688-2 )
サンプルプログラムがそのままです。
アマゾン.COMにてこの本を購入しました。確かにズバリ希望の
ソースがありました。これを参考にして全体のプログラムを構成する
ことができそうです。この本もLAN通信の解説として良書で、これで
いろいろ勉強してみます。どうも、ありがとうございました。
No.6
- 回答日時:
そこで苦労するなら素直にWinSockでpingを作ったほうが楽ではないでしょうか?
ICMPでechoを送って応答時間を調べるだけです。
この回答への補足
回答、ありがとうございます。
pingを書く方法も検討したいのですが、WinSockではUDP/TCP
しか書いたことがありません。WinSockでpingを書くための
良いサンプルなどがありましたら教えて頂くと助かります。
Netで探せばいいのですが、ネットワーク関連のプログラミング
知識が乏しいため、読みこなせないでおります。
よろしくお願いします。
No.5
- 回答日時:
> しかし、ダイアログベースではAllocConsole();を削除すると
> 動作しなくなってしまいます。どうしても、ダイアログベースで
> 作りたいと思ってます。なかなか難しいですね。
うーん、SDK でならまともに動いたんですが・・・。
MFC は扱ったことがないんでちょっと解らないです・・・。
No.4
- 回答日時:
僕自身勉強中なのでよくわからないんですが・・・。
// コンソール割り当て
FreeConsole();
AllocConsole();
と、コンソールを割り当てている部分を削除して、STARTUPINFO 構造体で、
startInfo.dwFlags = STARTF_USESHOWWINDOW;
startInfo.wShowWindow = SW_HIDE;
のようにしてやってから CreateProcess 関数に渡してやるとコンソールが開かないみたいです。
*************************************************
#include <windows.h>
#include <string.h>
#define R 0
#define W 1
#define CHR_BUF 4048
int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow){
HANDLE hPipeP2C[2]; // 親 → 子 のパイプ(stdin)
HANDLE hPipeC2P[2]; // 子 → 親 のパイプ(stdout)
HANDLE hPipeC2PE[2]; // 子 → 親 のパイプ(stderr)
HANDLE hDupPipeP2CW; // 親 → 子 のパイプ(stdin)の複製
HANDLE hDupPipeC2PR; // 子 → 親 のパイプ(stdout)の複製
HANDLE hDupPipeC2PE; // 子 → 親 のパイプ(stderr)の複製
SECURITY_ATTRIBUTES secAtt;
STARTUPINFO startInfo;
PROCESS_INFORMATION proInfo;
HANDLE hParent = GetCurrentProcess();
char str[CHR_BUF],processName[CHR_BUF];
DWORD dwByte;
//------------------------------------------------------
// パイプ作成(STDOUT,STDERR,STDIN の3本)
// 親の STDOUT , STDIN ,STDERR のハンドルを保存
HANDLE hOldIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hOldOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hOldErr = GetStdHandle(STD_ERROR_HANDLE);
// SECURITY_ATTRIBUTES の設定(パイプを作るのに必要
secAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
secAtt.lpSecurityDescriptor = NULL;
secAtt.bInheritHandle = TRUE; // ハンドル継承
//------------------------------------------------------
// STDOUT
// パイプ作成
CreatePipe(&hPipeC2P[R],&hPipeC2P[W],&secAtt,0);
// 「子」プロセスの STDOUT をセット
SetStdHandle(STD_OUTPUT_HANDLE,hPipeC2P[W]);
// 「子」からくるパイプの読み側(つまり親がリードする側)は継承しない
DuplicateHandle(hParent,hPipeC2P[R],hParent,&hDupPipeC2PR,0,FALSE,DUPLICATE_SAME_ACCESS);
// 読み側のハンドルをクローズ
CloseHandle(hPipeC2P[R]);
//------------------------------------------------------
// STDERR
// パイプ作成
CreatePipe(&hPipeC2PE[R],&hPipeC2PE[W],&secAtt,0);
// 「子」プロセスの STDERR をセット
SetStdHandle(STD_ERROR_HANDLE,hPipeC2PE[W]);
// 「子」からくるパイプの読み側(つまり親がリードする側)は継承しない
DuplicateHandle(hParent,hPipeC2PE[R],hParent,&hDupPipeC2PE,0,FALSE,DUPLICATE_SAME_ACCESS);
// 読み側のハンドルをクローズ
CloseHandle(hPipeC2PE[R]);
//------------------------------------------------------
// STDIN
//パイプ作成
CreatePipe(&hPipeP2C[R],&hPipeP2C[W],&secAtt,0);
// 「子」プロセスの STDIN をセット
SetStdHandle(STD_INPUT_HANDLE,hPipeP2C[R]);
// 「子」からくるパイプの書き込み側(つまり親がライトする側)は継承しない
DuplicateHandle(hParent,hPipeP2C[W],hParent,&hDupPipeP2CW,0,FALSE,DUPLICATE_SAME_ACCESS);
// 書き込み側のハンドルをクローズ
CloseHandle(hPipeP2C[W]);
// パイプ作成終了
//------------------------------------------------------
// STARTUPINFO の設定
memset(&startInfo,0,sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
startInfo.dwFlags = STARTF_USESHOWWINDOW;
startInfo.wShowWindow = SW_HIDE;
// 子プロセスでコマンドインタープリタを起動
// STDIN,STDOUT,STDIN のハンドルが継承される(つまり親とパイプでつながる)
GetEnvironmentVariable("ComSpec",processName,CHR_BUF);
if(CreateProcess(processName,"",NULL,NULL,TRUE,
0,NULL,NULL,&startInfo,&proInfo)==TRUE){
// 子プロセスが起動したら親の STDIN と STDOUT を戻す
SetStdHandle(STD_OUTPUT_HANDLE,hOldOut);
SetStdHandle(STD_INPUT_HANDLE,hOldIn);
SetStdHandle(STD_ERROR_HANDLE,hOldErr);
// "dir" コマンドを子プロセスに送る
wsprintf(str,"dir\r\n"); // (注) CR-LF を入れないとコマンドを受け取ってくれない
WriteFile(hDupPipeP2CW,str,strlen(str),&dwByte,NULL);
// "exit"
wsprintf(str,"exit\r\n");
WriteFile(hDupPipeP2CW,str,strlen(str),&dwByte,NULL);
// バッファのフラッシュ
FlushFileBuffers(hDupPipeP2CW);
FlushFileBuffers(hDupPipeC2PR);
// 子プロセスが終るまで停止
WaitForSingleObject(proInfo.hProcess,INFINITE);
// 子からきたメッセージを読む
ReadFile(hDupPipeC2PR,str,CHR_BUF,&dwByte,NULL);
str[dwByte] = '\0';
MessageBox(NULL,str,"",NULL);
}
return 0;
}
*************************************************
この回答への補足
回答ありがとうございます。コンソールベースのプログラムでは
確かに新たなコンソールは作らなくなります。
しかし、ダイアログベースではAllocConsole();を削除すると
動作しなくなってしまいます。どうしても、ダイアログベースで
作りたいと思ってます。なかなか難しいですね。
No.3
- 回答日時:
僕もハマリました。
で、調べてみたら、どうやらパイプを使うと標準入力やらを横取りできるらしいです。
http://www.fides.dti.ne.jp/~tokai/vc/index.html
↑の「パイプでプロセス間通信の基本」辺りが参考になるかと思います。
参考URL:http://www.fides.dti.ne.jp/~tokai/vc/index.html
この回答への補足
回答ありがとうございます。
このコードはかなり目的に近いものでした。VisualC++6.0にて、
ダイアログベースのアプリケーションとして、ボタンと
EditBox(メンバ変数:m_ed1)を配置しました。ボタンのハンドラ
を以下のコードにしたところ、pingの出力がみごとにEditBoxに表示
されました。
しかし、実行するとコマンドプロンプトが表示されてしまいます。
コマンドプロンプトの表示を阻止する方法はないでしょうか?
void CP6Dlg::OnButton1()
//int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
//int main(int argc, char* argv[])
{
HANDLE hPipeP2C[2]; // 親 → 子 のパイプ(stdin)
HANDLE hPipeC2P[2]; // 子 → 親 のパイプ(stdout)
HANDLE hPipeC2PE[2]; // 子 → 親 のパイプ(stderr)
HANDLE hDupPipeP2CW; // 親 → 子 のパイプ(stdin)の複製
HANDLE hDupPipeC2PR; // 子 → 親 のパイプ(stdout)の複製
HANDLE hDupPipeC2PE; // 子 → 親 のパイプ(stderr)の複製
SECURITY_ATTRIBUTES secAtt;
STARTUPINFO startInfo;
PROCESS_INFORMATION proInfo;
HANDLE hParent = GetCurrentProcess();
char str[CHR_BUF],processName[CHR_BUF];
DWORD dwByte;
// コンソール割り当て
FreeConsole();
AllocConsole();
//------------------------------------------------------
// パイプ作成(STDOUT,STDERR,STDIN の3本)
// 親の STDOUT , STDIN ,STDERR のハンドルを保存
HANDLE hOldIn = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hOldOut = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE hOldErr = GetStdHandle(STD_ERROR_HANDLE);
// SECURITY_ATTRIBUTES の設定(パイプを作るのに必要
secAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
secAtt.lpSecurityDescriptor = NULL;
secAtt.bInheritHandle = TRUE; // ハンドル継承
//------------------------------------------------------
// STDOUT
// パイプ作成
CreatePipe(&hPipeC2P[R],&hPipeC2P[W],&secAtt,0);
// 「子」プロセスの STDOUT をセット
SetStdHandle(STD_OUTPUT_HANDLE,hPipeC2P[W]);
// 「子」からくるパイプの読み側(つまり親がリードする側)は継承しない
DuplicateHandle(hParent,hPipeC2P[R],hParent,&hDupPipeC2PR,0,FALSE,DUPLICATE_SAME_ACCESS);
// 読み側のハンドルをクローズ
CloseHandle(hPipeC2P[R]);
//------------------------------------------------------
// STDERR
// パイプ作成
CreatePipe(&hPipeC2PE[R],&hPipeC2PE[W],&secAtt,0);
// 「子」プロセスの STDERR をセット
SetStdHandle(STD_ERROR_HANDLE,hPipeC2PE[W]);
// 「子」からくるパイプの読み側(つまり親がリードする側)は継承しない
DuplicateHandle(hParent,hPipeC2PE[R],hParent,&hDupPipeC2PE,0,FALSE,DUPLICATE_SAME_ACCESS);
// 読み側のハンドルをクローズ
CloseHandle(hPipeC2PE[R]);
//------------------------------------------------------
// STDIN
//パイプ作成
CreatePipe(&hPipeP2C[R],&hPipeP2C[W],&secAtt,0);
// 「子」プロセスの STDIN をセット
SetStdHandle(STD_INPUT_HANDLE,hPipeP2C[R]);
// 「子」からくるパイプの書き込み側(つまり親がライトする側)は継承しない
DuplicateHandle(hParent,hPipeP2C[W],hParent,&hDupPipeP2CW,0,FALSE,DUPLICATE_SAME_ACCESS);
// 書き込み側のハンドルをクローズ
CloseHandle(hPipeP2C[W]);
// パイプ作成終了
//------------------------------------------------------
// STARTUPINFO の設定
memset(&startInfo,0,sizeof(STARTUPINFO));
startInfo.cb = sizeof(STARTUPINFO);
// 子プロセスでコマンドインタープリタを起動
// STDIN,STDOUT,STDIN のハンドルが継承される(つまり親とパイプでつながる)
GetEnvironmentVariable("ComSpec",processName,CHR_BUF);
if(CreateProcess(processName,"",NULL,NULL,TRUE,
0,NULL,NULL,&startInfo,&proInfo)==TRUE){
// 子プロセスが起動したら親の STDIN と STDOUT を戻す
SetStdHandle(STD_OUTPUT_HANDLE,hOldOut);
SetStdHandle(STD_INPUT_HANDLE,hOldIn);
SetStdHandle(STD_ERROR_HANDLE,hOldErr);
// "dir" コマンドを子プロセスに送る
//wsprintf(str,"dir\r\n"); // (注) CR-LF を入れないとコマンドを受け取ってくれない
wsprintf(str,"ping localhost\r\n"); // (注) CR-LF を入れないとコマンドを受け取ってくれない
WriteFile(hDupPipeP2CW,str,strlen(str),&dwByte,NULL);
// "exit"
wsprintf(str,"exit\r\n");
WriteFile(hDupPipeP2CW,str,strlen(str),&dwByte,NULL);
// バッファのフラッシュ
FlushFileBuffers(hDupPipeP2CW);
FlushFileBuffers(hDupPipeC2PR);
// 子プロセスが終るまで停止
WaitForSingleObject(proInfo.hProcess,INFINITE);
// 子からきたメッセージを読む
ReadFile(hDupPipeC2PR,str,CHR_BUF,&dwByte,NULL);
str[dwByte] = '\0';
//MessageBox(NULL,str,"",NULL);
m_ed1 = str;
UpdateData(FALSE);
}
//return 0;
}
No.2
- 回答日時:
> Helpを見ると「_popen()をWindowsプログラムで使用すると
> 無効なハンドルが返され、プログラムがハングアップします。」とのこと。
いたたたた...そうでしたか。
お役に立てずごめんなさい。
# うまくいったら教えてくださいな^^;
No.1
- 回答日時:
むちゃくちゃローテクですけど、
FILE* fp = _popen("ping ...", "r");
while ( !feof(fp) ) {
fgets(...);
}
_pclose(fp);
とか^^;
この回答への補足
回答ありがとうございます。Windowプログラムの中で_popen()を使ったら、実行時にエラーになってしまいました。
Helpを見ると「_popen()をWindowsプログラムで使用すると
無効なハンドルが返され、プログラムがハングアップします。」とのこと。
WindowsプログラムではCreatePipe, CreateProcess等々を使えとのことでした。
これでやってみますと、pingを起動することはできるのですが、pingのstdoutを
取ってくるのがうまくいきません。
もう少し試してみて、うまく行かない場合にはまた相談させてください。
よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
スティーブ・ジョブズはプログ...
-
バッチファイルでPINGログ取得
-
タスクマネージャの「プロセス...
-
Windowsでのfork方法
-
プロセスのアタッチ・デタッチ...
-
【C#】別プロセスがロックか...
-
IISがフリーズ
-
特定ユーザーのプロセス情報を...
-
実行中のプログラムIDが取得...
-
〔Windowsタスクマネージャ〕メ...
-
LSIのプロセス技術開発について...
-
VBでエクセルを起動し、プロ...
-
.NETアプリケーションの戻り値
-
タスクマネージャーのプロセス...
-
AF_UNIXのsocketと共有メモリを...
-
AppActivate関数について
-
非表示になったエクセルは?
-
スマホ Androidの方、又は機械...
-
VBS(WSH)で開いたIEのウィンド...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バックグラウンドのプロセスの...
-
タスクマネージャーのプロセス...
-
ADOでアクセスのレコードに...
-
VB6.0 SHELLで起動...
-
プロセスのアタッチ・デタッチ...
-
C#でのbatファイル実行結果取得
-
vb.netでEXCEL起動がうまくでき...
-
プロセスIDの取得方法について
-
非表示になったエクセルは?
-
Process.Startの戻り値を後で取得
-
IISがフリーズ
-
API関数 GetExitCodeProcess
-
VB.NETで起動したExcelの閉じ方...
-
explorer.exeが異様にメモリを食う
-
Visual C++からpingを実行して...
-
c言語でプロセスIDを調べたい
-
VBS(WSH)で開いたIEのウィンド...
-
Linuxでのスレッド間メッセージ...
-
怪しいプロセス教えてください。
-
VBAで別プロセスのExcelのフル...
おすすめ情報