delphiにて作成したアプリを、バッチ(open.bat)から起動しています。
バッチを実行することにより、コマンドプロンプトが起動し、
コマンドプロンプトからアプリが起動される流れになりますが、
このアプリを呼び出したコマンドプロンプトのハンドルを取得したいのです。
もちろん、コマンドプロンプトのキャプション(自分のNTの環境では
C:\Winnt\System32\cmd.exe」)やクラス(ConsoleWindowClass)
を指定すれば取得できるのですが、他に開かれている場合、区別できませんし、
違うOS(Windows98など)ではキャプションもクラスも異なります。
自分を呼び出したウインドウのハンドルを取得する方法がありましたら、
教えてください。
そのやり方だと、たぶん無理でしょう。
方法としては、バッチを起動する前に、起動しているコマンドプロンプトのハンドルを取得し、バッチを起動後に、それらに含まれないハンドルを探せばよいかと思いますが、同時にコマンドプロンプトを起動されると判別できません。
# 複数の、「調べていないコマンドプロンプト」が見つかります
やりたいことはたぶん標準出力の取得でしょうから、CreateProcessのパラメータで設定して、起動元のアプリケーションに標準出力を返すようにすればよいかと思います。
アドバイスいただいた方法で調べてみましたが、
・「作成したアプリからコマンドプロンプトを起動し、コマンドプロンプトに
入力された内容を取得する」
ことはできても、私が実現したい
・「コマンドプロンプトから作成したアプリを起動し、そのアプリの実行結果を
コマンドプロンプトに返す」
こともできるのでしょうか?
ちょっと起動元(コマンドプロンプト)の指定方法がわかりませんでした。
申し訳ありませんが、教えてください。
入力と出力の方向がわかりにくいので確認します。
アプリケーションの出力は、コマンドプロンプトの出力(StdOut)に出力されます。
コマンドプロンプトのStdOutは、CreateProcessの引数StartupInfoの、hStdOutputで設定できます。StdInも、hStdInputで設定できます。
# dwFlagsに、STARTF_USESTDHANDLESが必要です。CreateProcessの引数bInheritHandlesもTRUEでないとだめかも。
方向としては、例えば大元のアプリケーションがアプリA、バッチから起動するアプリケーションがアプリBであれば、次のようになります。
アプリAが、入出力を監視しない場合
・出力
アプリB>コマンドプロンプト
・入力
コマンドプロンプト>アプリB
・出力
アプリB>アプリA>コマンドプロンプト
・入力
コマンドプロンプト>アプリA>アプリB
もし、コマンドプロンプトの標準出力に対して出力していないのであれば、この方法では無理かもしれません。
また、アプリB側で、出力先を変更している場合も同じく無理です。
Halbow です。
すみません、よこから失礼します。
どうも何か食い違いがあるように感じます。
この質問をはじめて読んだときに、非常に不思議に感じました。
・なぜ、バッチでコマンドラインから起動する必要があるんだろう。
・いわゆるDOS窓のハンドルを取得して何をしたいんだろうか。
質問者の本当にしたいことが明確でないので、非常に回答しづらいです。
わたしもにしのさんのように、起動したDOS窓に起動されたプログラム
から文字列などを出力したいのではないか、と考えました。
Perl や Java や C# や Delphi で作ったコンソールアプリや Delphi 自身
のコンパイラなどは、起動したアプリにその処理結果を表示することが
できます。これは標準出力を起動したアプリにリダイレクトしているから
です。にしのさんのご指摘のように、CreateProcess() で起動すると
パイプをつかってこのようなことができます。
いずれにしても、本当になにをしたいのか分からないとこれ以上の進展は
望めないように思います。
食い違いの意味がわかりました。
もしかして、質問は、
・コマンドプロンプトからコンソールアプリケーションを起動し、コンソールアプリケーションの出力を得る
でなく、
・コマンドプロンプトからウィンドウアプリケーションを起動し、ウィンドウアプリケーションの出力を得る
でしょうか。
前者と思っていましたが、後者であれば、無理です。
コンソールアプリケーションからウィンドウを作成し、その出力をコンソールに返すような仕組みが必要です。
起動元のコマンドプロンプトに直接出力というのは難しいと思います。
バッチで起動したアプリの終了状態を判定する程度であればウィンドウアプリ(Delphiプログラム)で終了時にExitCode変数を設定してやれば可能です。ExitCodeに設定した値がそのプログラムの終了コードになり、その値をバッチのif errorlevel … で判定できます。
例えば、バッチファイルで...
:
MyWinApp.exe
if errorlevel 2 Goto …
if errorlevel 1 Goto …
:
といった具合に、プログラムのExitCodeに応じて処理を分岐できます。
単に、コマンドプロンプトに文字を出すのであれば、ウィンドウアプリ側でテキストファイルを作成してバッチでTYPEコマンドで出力する方法もありますが...(複数同時に実行した場合にまずいか?)
どのようなことをされるのかわかりませんが、参考までに...
私の拙い文章のせいで混乱させてしまったようで申し訳ありません。
私が作ろうと(あったらいいな、と)思ったものは、にしの様が指摘された
「コマンドプロンプトからウィンドウアプリケーションを起動し、
コマンドプロンプトがウィンドウアプリケーションの出力を得る」
です。
業務で、ファイルのコピーなどを何台のパソコンにも行うような際に、
よくバッチファイルを作成して使用しており、たいていの作業は間に合います。
ただ、ユーザからの入力を必要とする場合、基本的にバッチ名のあとに引数として
記入する以外方法が無かった(知らない)ため、これを補いたいと思ったのです。
masayan様からご指摘いただいたようなものは、実は作成済みです。ただ、
1.バッチからcallでウィンドウアプリを起動し、
2.ユーザに入力してもらい、
3.「OK」を押すと指定したフォルダにファイルを作成して入力内容を入れてウィンドウを閉じ、
4.バッチ側ではfor /fを使用してtypeで内容を取得
という流れになるのですが、直接コマンドプロンプトに入力された文字を
送り込めたらなぁ、と考えたのです。
終了コードでは文字や文字数に制限があって、ちょっと使用できないのです。
追記(お願い)
にしの様から頂いた回答の中に
「コンソールアプリケーションからウィンドウを作成し、その出力をコンソールに返すような仕組みが必要です。」
とありますが、すみません、私まだ使い始めたばかりで、
コンソールアプリケーションは、今あわてて(Webで)勉強中です。
もし上のようなことがコンソールアプリケーションを使用することで
実現できそうでしたら、流れなどアドバイスいただけますでしょうか?
宜しくお願いいたします。
その流れでしたら、バッチからアプリを起動するのでなくて、アプリでデータを入力させ、アプリがバッチを起動すればすっきりしそうですが。
だめですか?
コンソールアプリケーションでの入力であれば、ヘルプでReadLn手続きを調べてみてください。
ReadLn, WriteLnの例が、コンソールアプリケーションの例です。
# 当方、Delphi7Proの環境の場合
ウィンドウアプリから起動元コマンドプロンプトへの文字出力ですが、プロジェクトソースに{$APPTYPE CONSOLE}を追記することで簡単に実現するようです。
program Project1;
{$APPTYPE CONSOLE} // ←これを追加
uses
Forms,
Unit1 in 'Unit1.pas' {Form1};
:
後は、WriteLnなどで標準出力に文字を書き込むだけです。
例えば...
WriteLn(Output,'HELLOW!!');
細かな検証はしていませんが試して見てください。
ツイート | ![]() |