ShellExecute等で実行したプログラムの出力結果を取得したい
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
ShellExecute等で実行したプログラムの出力結果を取得したい
コンソールアプリケーションを実行すると、コマンドプロンプトにその結果が出力されますよね。
あれを、ShellExecute等で実行したときに取得したいわけです。
しかし、ファイルに出力してそれを読み込むという方法しかみつかりません。
できれば直接取得したいのですが、どうすればよいのでしょうか。
さらに、ShellExecuteではなくCreateProcessを使用する必要があるという記述も目にしました。
CreateProcessで実行したウインドウを非表示に設定する方法がわからなかったためShellExecuteを採用したのですが、できればウインドウは非表示にしたいですね。
また、実行したいプログラムは自分が作ったものではないということを前提としています。
よろしくお願いいたします。
あれを、ShellExecute等で実行したときに取得したいわけです。
しかし、ファイルに出力してそれを読み込むという方法しかみつかりません。
できれば直接取得したいのですが、どうすればよいのでしょうか。
さらに、ShellExecuteではなくCreateProcessを使用する必要があるという記述も目にしました。
CreateProcessで実行したウインドウを非表示に設定する方法がわからなかったためShellExecuteを採用したのですが、できればウインドウは非表示にしたいですね。
また、実行したいプログラムは自分が作ったものではないということを前提としています。
よろしくお願いいたします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
CREATE_NO_WINDOWでCreateProcessすれば良いんじゃないでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
子プロセスの標準入出力にアクセスする方法は一般的に「パイプ」と呼ばれます。
標準入出力のリダイレクトと説明している場合もあります。
「Win32 コンソール パイプ」というキーワードで検索するとサンプルコードがたくさん見付かると思います。
標準入出力のリダイレクトと説明している場合もあります。
「Win32 コンソール パイプ」というキーワードで検索するとサンプルコードがたくさん見付かると思います。
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
返信ありがとうございます。
>>ソフト屋さん
仰るとおりです。見逃していたようです。
>>ISLeさん
おかげ様でアルゴリズムは掴めました。
管理クラスも作って動作テストをしてみると、しかしCreateProcessの部分でエラーが常に発生してしまいます。
とりあえずCreateProcessを実行するだけのプログラムを書いてみましたが、これすらも動きません。
※インクルード文等は省略
fw::zeromemory()というのはZeroMemory()の引数を減少させた自作関数で、
fw::popup()というのはポップアップウインドウを表示するための自作関数です。
コンソール画面のスクリーンショットです。
なにがいけないのでしょうか?
OS:Windows8
IDE:VisualStudio2010
>>ソフト屋さん
仰るとおりです。見逃していたようです。
>>ISLeさん
おかげ様でアルゴリズムは掴めました。
管理クラスも作って動作テストをしてみると、しかしCreateProcessの部分でエラーが常に発生してしまいます。
とりあえずCreateProcessを実行するだけのプログラムを書いてみましたが、これすらも動きません。
int main(){
STARTUPINFO si;
fw::zeromemory(&si);
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
char cmdline[] = "notepad";
BOOL result = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
if(result==0) fw::popup("failed");
else fw::popup("succeeded!");
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
fw::zeromemory()というのはZeroMemory()の引数を減少させた自作関数で、
fw::popup()というのはポップアップウインドウを表示するための自作関数です。
コンソール画面のスクリーンショットです。
なにがいけないのでしょうか?
OS:Windows8
IDE:VisualStudio2010
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
基本ですが、とりあえずCreateProcessのエラーコードを調べてみては?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
エラーコードを調べてみました。
「メモリ ロケーションへのアクセスが無効です」
とのことです。
無効な場所にアクセスする可能性があるコードには見えないのですが…。
「メモリ ロケーションへのアクセスが無効です」
とのことです。
無効な場所にアクセスする可能性があるコードには見えないのですが…。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
zeromemoryにバグがあるんじゃないでしょうか?
私の所では、こうすると動きます。
私の所では、こうすると動きます。
#include <windows.h>
#include <stdio.h>
int main() {
static STARTUPINFO si;
si.cb = sizeof( si );
static PROCESS_INFORMATION pi;
char cmdline[] = "notepad";
BOOL result = CreateProcess( NULL, cmdline, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi );
if( result == 0 ) printf( "failed" );
else printf( "succeeded!" );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
返信ありがとうございます。
siをstaticにすると成功しました。
zeromemoryとpiは特に関係ありませんでした。
※インクルード文等は省略
※fw::exerrorクラスは拡張エラー情報を管理する自作クラス
とりあえずCreateProcessが使えるようになったので、これから管理クラスの動作テストをしていきます。
siをstaticにすると成功しました。
zeromemoryとpiは特に関係ありませんでした。
int main(){
static STARTUPINFO si;
fw::zeromemory(&si);
si.cb = sizeof(si);
PROCESS_INFORMATION pi;
char cmdline[] = "notepad";
BOOL result = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
if(result==0){
fw::exerror err;
printf("\nfailed:%s\n", err.get() );
}
else printf("\nsucceeded!\n");
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
※fw::exerrorクラスは拡張エラー情報を管理する自作クラス
とりあえずCreateProcessが使えるようになったので、これから管理クラスの動作テストをしていきます。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
zeromemoryってクリアのサイズをどうやって得ているかかなり疑問なんですが、どうやっているのでしょうか? ポインタしか渡していないように見えますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
>>ソフト屋さん
テンプレートを使用して、内部でsizeof演算を行っています。
というわけで、動作テストを行ってみました。
正常に実行が完了したのですが、結果の文字列を取得することができませんでした。
実行結果のコンソール画面です。
ソースコードです。
実行したのはfxc.exeという実行ファイルで、パスは通してあります。
これは Microsoft DirectX11 SDK というSDKに含まれている実行ファイルで、シェーダーの情報が別言語で記述されているファイルをC/C++言語用の.hファイルに変換する実行ファイルです。
この実行ファイルをコマンドプロンプトから実行すると、成功・失敗 どちらの場合でもその旨がコンソールに出力されます。
今回はこれを受け取るプログラムを作りたいわけです。
実行が完了しているのに結果がなしというのは有り得ないはずです。
よって、どこかが間違っているということになるはずです。
しかし全くわかりません。
このような場合はどうやってデバッグすれば良いのでしょうか?
ちなみに、充分予想できたと思いますが、fxc.exeはGUIではないため一々ファイル名等を手動で入力する必要があって、これが面倒だからfxc.exeを間接的に実行するGUIソフトを作ろうと思い立ち、現在に至ります。
テンプレートを使用して、内部でsizeof演算を行っています。
というわけで、動作テストを行ってみました。
正常に実行が完了したのですが、結果の文字列を取得することができませんでした。
実行結果のコンソール画面です。
ソースコードです。
► スポイラーを表示
これは Microsoft DirectX11 SDK というSDKに含まれている実行ファイルで、シェーダーの情報が別言語で記述されているファイルをC/C++言語用の.hファイルに変換する実行ファイルです。
この実行ファイルをコマンドプロンプトから実行すると、成功・失敗 どちらの場合でもその旨がコンソールに出力されます。
今回はこれを受け取るプログラムを作りたいわけです。
実行が完了しているのに結果がなしというのは有り得ないはずです。
よって、どこかが間違っているということになるはずです。
しかし全くわかりません。
このような場合はどうやってデバッグすれば良いのでしょうか?
ちなみに、充分予想できたと思いますが、fxc.exeはGUIではないため一々ファイル名等を手動で入力する必要があって、これが面倒だからfxc.exeを間接的に実行するGUIソフトを作ろうと思い立ち、現在に至ります。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 13年前
- 住所: 東海地方
- 連絡を取る:
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
>テンプレートを使用して、内部でsizeof演算を行っています。
了解です。
ただ、siをstaticにすると成功するのが意味不明なんですよね。
とりあえず、もっと単純なコードで試すことと、物事を単純にするために自分で作ったコンソールアプリでデバッグすることでしょうか。
他の人の動いているコードを試してみる必要もあるでしょう。
了解です。
ただ、siをstaticにすると成功するのが意味不明なんですよね。
とりあえず、もっと単純なコードで試すことと、物事を単純にするために自分で作ったコンソールアプリでデバッグすることでしょうか。
他の人の動いているコードを試してみる必要もあるでしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- MoNoQLoREATOR
- 記事: 284
- 登録日時: 13年前
- 住所: 東京
Re: ShellExecute等で実行したプログラムの出力結果を取得したい
解決しました。
CreateProcessの第5引数をtrueにする必要があったようです。
ありがとうございました。
CreateProcessの第5引数をtrueにする必要があったようです。
ありがとうございました。