こんにちは。プログラミング初心者で申し訳ないのですが、調べてみてもどうしても分からない問題があり、ご質問させて頂きました。お手数をおかけしますがご回答頂ければ幸いです。
windowsアプリケーションにて外部のアプリを呼び出し、それを操作しようとした時に、私のような素人が思いつく方法としては、keybd_eventAPIなどでキーを送る、とかWM_LBUTTONDOWNなどのウィンドウメッセージを送る、くらいしか思いつかないのですが、それ以外に外部操作の方法はあるのでしょうか?
例えば、今私が作ろうとしているのは独自アプリよりコマンドプロンプトを呼び出し、事前に指定したいくつかのコマンドを実行する、といったものなのですが、CreateProcessにて起動し、コマンドプロンプトのハンドルを得たところまでは良かったのですが、そのハンドルを利用してどのようにコマンドを送れば良いのかがどうしても分かりませんでした。
「cd ../」というコマンドを送りたい場合、
Keybd_event(Byte('c'),0,0,0);
Keybd_event(Byte('c'),0,KEYEVENTF_KEYUP,0);
Keybd_event(Byte('d'),0,0,0);
Keybd_event(Byte('d'),0,KEYEVENTF_KEYUP,0);
Keybd_event(Byte(' '),0,0,0);
Keybd_event(Byte(' '),0,KEYEVENTF_KEYUP,0);
Keybd_event(Byte('.'),0,0,0);
Keybd_event(Byte('.'),0,KEYEVENTF_KEYUP,0);
Keybd_event(Byte('.'),0,0,0);
Keybd_event(Byte('.'),0,KEYEVENTF_KEYUP,0);
Keybd_event(Byte('/'),0,0,0);
Keybd_event(Byte('/'),0,KEYEVENTF_KEYUP,0);
のようなやり方しか思いつかないのですが、他に良い方法はございませんでしょうか?
宜しければご指導して頂けますよう宜しくお願い致します。
No.5
- 回答日時:
>以下のような組み方をしているのですが、お時間のある時で結構ですので、もし宜しければご教授お願い致しますm(_ _)m
とりあえず、ANo.3の参考urlのサンプルそのまま試してみては?それから不要な部分を削った方がいいかと。
なんか管理するべきハンドルの数が少ないような・・・
これで動かなかったらもっとちゃんとしたサンプル探してみますけど。
ご回答ありがとうございます。
とりあえずサンプルの方をそのまま試してみる事にします。
この度は本当にありがとうございました。
また宜しくお願い致します。
No.4ベストアンサー
- 回答日時:
>HANDLE hd;
>si.hStdInput = hd;
これじゃいくらなんでも。
hdの中身、不定じゃないですか。
CreatePipe等で作成したパイプのハンドルを指定すればいいんですよ。
ご回答ありがとうございます。
昨日より、教えて頂きましたパイプを使って子プロセスとの通信を行う方法を実装しようと、丸一日悩んだのですが、どうしてもうまくいかず困っております。
以下のような組み方をしているのですが、お時間のある時で結構ですので、もし宜しければご教授お願い致しますm(_ _)m
//パイプの標準入出力用ハンドル
HANDLE okp_r;
HANDLE okp_w;
SECURITY_ATTRIBUTES secAtt;
//親のプロセスID
HANDLE hParent = GetCurrentProcess();
secAtt.nLength = sizeof(SECURITY_ATTRIBUTES);
secAtt.lpSecurityDescriptor = NULL;
//継承設定
secAtt.bInheritHandle = TRUE;
//パイプ作成
CreatePipe(&okp_r,&okp_w,&secAtt,0);
//子供は親のWriteハンドルを継承しないように
DuplicateHandle(hParent,okp_w,hParent,NULL,0,FALSE,DUPLICATE_SAME_ACCESS);
//CreateProcess用の構造体の設定
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOW;
si.hStdInput = okp_r;
si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
//コマンドプロンプトのパス
char *cmd_path = getenv("COMSPEC");
//コマンドプロンプト呼び出し
if(CreateProcess(NULL, cmd_path, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
DWORD dw;
//実行コマンド
char cm[4048];
wsprintf(cm,"dir\r\n");
if(WriteFile(okp_w,cm,strlen(cm),&dw,NULL))
{
//成功
}else{
//失敗
}
}
No.3
- 回答日時:
標準入出力を備えたものが相手ならパイプ。
http://www.fides.dti.ne.jp/~tokai/vc/vcchips1.html
参考URL:http://www.fides.dti.ne.jp/~tokai/vc/vcchips1.html
ご返答ありがとうございます。
なるほど。。。パイプを使えば標準入力に送る事が可能なんですね!ありがとうございます。「パイプ」も名前はよく聞くのですが内容はよく知らなかった為、大変勉強になりました。
No.2
- 回答日時:
呼び出したコマンドプロンプトの標準入力に文字列(cdなどのコマンド)を出力すれば可能だと思います。
CreateProcessの引数にある、STARTUPINFO構造体あたりから指定できるようです。
ご回答ありがとうございます。
大変参考になりました。この方法で実装してみようと
現在がんばってみておりますが、どうしても失敗してしまいます(><;)
PROCESS_INFORMATION pi;
STARTUPINFO si;
ZeroMemory(&si,sizeof(si));
ZeroMemory(&pi,sizeof(pi));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW & STARTF_USESTDHANDLES;
si.wShowWindow = SW_SHOW;
HANDLE hd;
si.hStdInput = hd;
CreateProcess(NULL, cmd_path, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
DWORD dw;
char cm[] = "dir\r\n";
if(WriteFile(si.hStdInput,cm,strlen(cm),&dw,NULL))
{
//成功
}else{
//失敗
}
というようなコードを打ってみたのですが、どうしてもWriteFileが失敗を返してくれます。
でも方法の目安はついてきました。大変参考になりました。ありがとうございます。
No.1
- 回答日時:
コマンドプロンプト内でCUIのプログラムを動かすだけなら、バッチファイルを合成してsystem関数で実行するという手もありますが。
例えば
fh=fopen("test.bat","w");
fprintf(fh,"cd ../\n");
fclose(hf);
system("test.bat");
みたいな感じで実行は可能かと思います。
ただカレントディレクトリが怪しいことや、Windowsの種類によってはコマンドとアーギュメント双方にブランクが有る場合うまくいかない等がありその場合はもう少し面倒な話しになりますが。
keybd_eventは対象がアクティブなWindowに限定されますから、それとは別の、取得したプロセスにメッセージを送るには、
(1)windowを列挙して、それぞれのプロセスIDを取得する。
(2)目的のプロセスと一致するプロセスIDのWindowに対してsendmessageでメッセージを送る。
と結構煩雑な事をする必要が有ったように思います。
ちなみにMSDNによればNT/2000ではkeybd_eventの代わりにSendInputの使用が推奨されています。
なるほど。ありがとうございます。
そのような方法は思いつきませんでした。
大変参考になります。
プロセスIDを取得してsendmessageすればアクティブでないウィンドウにもキーメッセージが送れるとは知りませんでした。今度是非やってみたいと思います。ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# TCP/IP通信時のサーバーからの受信 2 2022/11/23 09:11
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# c言語の問題です 2 2023/07/21 10:51
- その他(プログラミング・Web制作) pythonで、tkinterとpillowの組み合わせ 2 2022/08/16 17:42
- JavaScript jsで質問です。 ボタンが二つ存在し、両方のボタンがクリックされたことをチェックしたいのですが、どの 4 2022/11/22 10:30
- その他(データベース) c言語の問題です。これを踏まえてコーディングしたいのでおしえていただきたいです。 3 2023/08/03 09:27
- Excel(エクセル) 【VBA】 Alt+PrintScreenにてアクティブウィンドウのスクショを貼付する方法 4 2022/12/08 20:53
- JavaScript Google reCAPTCHAについて 1 2023/02/22 14:37
- その他(プログラミング・Web制作) pythonのこのエラーがわかりません 3 2022/11/16 14:54
- ホームページ作成・プログラミング Qiitaは純日本のサイトみたいで70万人の登録者がいる! 1 2022/05/21 11:53
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Tera Term Proに関する質問です。
-
コマンドプロンプトが実行中か...
-
ttlで戻り値を取得する方法
-
バッチファイルでキー操作を行う。
-
負の数を正の数に変換
-
コマンドキーがないんですけど...
-
別のユーザーフォームのコマン...
-
PowerShell実行結果をデスクト...
-
シェルスクリプト
-
ディスクの空き容量を取得する...
-
mountのDOSコマンド
-
VBユーザーフォームで時間入力
-
文字の点滅はどうやるのですか?
-
コマンドプロンプトですべてのU...
-
ユーザーフォームのリストボッ...
-
C#でローカルユーザーやグルー...
-
BASICのコマンドリファレンスが...
-
runasで/savecredが指定できない
-
コマンドプロンプトで表示が多...
-
dosバッチ起動後、画面を閉じな...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチファイルでキー操作を行う。
-
コマンドプロンプトが実行中か...
-
コマンドプロンプトで表示が多...
-
ttlで戻り値を取得する方法
-
別のユーザーフォームのコマン...
-
VBユーザーフォームで時間入力
-
Tera Term Proに関する質問です。
-
コマンドプロンプトですべてのU...
-
コマンドキーがないんですけど...
-
TEXの表の位置が・・・
-
ルーターにつながっている全て...
-
デフォルトのショートカットキ...
-
dosバッチ起動後、画面を閉じな...
-
文字の点滅はどうやるのですか?
-
EEPROMのデータの初期化について
-
RTX1100の削除コマンド
-
コンボボックス(最終行取得)
-
JP1起動バッチについて
-
makeコマンドのエラー
-
ディスクの空き容量を取得する...
おすすめ情報