0

createprocessを使用して開いたプロセスに文字列を送信するにはどうすればよいですか?

私はここStackoverflowで見つけたものの助けを借りてこのようなものを書きました:

    var
    StartUpInfo:TStartUpInfo;
    ProcessInfo: TProcessInformation;
    Creationflags: Cardinal;

    FillChar(StartUpInfo, sizeOf(TStartupinfo),0);
    StartUpInfo.cb := SizeOf(StartupInfo);
    Creationflags := NORMAL_PRIORITY_CLASS;

    if Createprocess(nil, Pchar('c:\program files\adobe\reader 9.0\reader\acrord32.exe'
    + ' ' + '/h /O /N /T "c:\ps\test2.pdf" "Generic printer"'),nil, nil,False, 
    creationflags, nil, 0 , StartUpInfo ,  ProcessInfo) then

    begin
      WaitForSingleObject(ProcessInfo.HProcess, infinite);
         begin
           //write some information into the process (a window that opens in 
           //acrobatreader) and then I want to press the enter button            
         end;
      CloseHandle(processinfo.hProcess);

    end;

だから私が欲しいのは、プロセスが終了したときに(singleobjectを待つ直後に)行を書き、次に「Enter」ボタンを押して、最後にプロセスが終了したときにプロセスを閉じることです。誰かが外部プロセスと対話する方法を知っていますか?プログラミングに関しては、私はまったくの初心者です。

よろしくお願いします

4

2 に答える 2

4

プログラムでAcrobatReadにドキュメントを印刷させようとしているようです。あなたの問題は、ユーザーの操作を要求せずにそうするように説得することはできないということです。

プロセスが終了するのを待っているため、現在のコードは機能しません。WaitForSingleObjectの単純な呼び出しから始めると、プロセスが終了するまでコードを実行できません。コードでそのボタンをクリックする機会はありません。

したがって、あなたがする必要があるのは、別の待機戦略を使用することです。これはかなり大雑把なハックのように見えるので、通常は提案しないもの、つまりポーリングを提案します。無限のタイムアウトで待機する代わりに、たとえば250msのタイムアウト値でループで待機する必要があります。待機が終了するたびに、プロセスが終了したかどうか、または待機がタイムアウトしたかどうかを確認します。

待機がタイムアウトすると、検索するダイアログウィンドウを探す機会があります。で見つけることができるはずですFindWindowEx()。そのクラス名はSpy++を使用して見つけることができます。ダイアログウィンドウを見つけたら、編集コントロールのウィンドウハンドルと、クリックするボタンを見つける必要がありますEnumChildWindows()。これでうまくいくはずです。

操作するコントロールのハンドルを取得したら、それらを操作する方法を理解する必要があります。運がSetWindowText良ければ、それがEDITコントロールなどである場合は、を呼び出して文字列を送信できます。それ以外の場合は、キーを押すことを偽造するか、WM_PASTEを送信する必要があります。ボタンはもっと面倒かもしれません。それをクリックすると、ボタンの親にWM_COMMANDが送信されます。ここでも、Spy ++は、ボタンをクリックしたときに送信されるメッセージを表示できます。

もちろん、FindWindowEx()まだ表示されていないため、電話をかけてもウィンドウが見つからない場合があります。それが起こったとき、あなたはへの呼び出しで再びループを一周しますWaitForSingleObject()

最後に、これを処理するためのはるかに優れた方法は、PDFの印刷専用のソフトウェアライブラリを使用することです。

于 2011-03-30T11:19:49.930 に答える
0

あなたがやりたいことははっきりしていません。

プロセスにデータを送信する方法はいくつかあります。

  • OLEオートメーション(例:MSWord)
  • CMDLine経由(例notepad file.txt:)
  • STDIN経由(例:std ioのみを使用するcmdアプリ)
  • 操作を介して(例:特定のwmメッセージを特定のプロセスウィンドウに送信する)

私が見るように、あなたは最後のアプローチが必要です。

基本的に、適切なWindows API関数を実行して、プロセスからウィンドウのリストを取得します。次に、winspy、winspy ++、またはdelphiを使用したプログラムを使用します(名前を忘れてしまいました。Delphiツールメニューにあります)。上記のツールを使用して、メッセージを送信するウィンドウのクラス名を見つけ、この特定のウィンドウが見つかるまでコードですべてのウィンドウをフィルターで除外してから、SendMessageAPIを使用します。

複雑に聞こえますが、(初心者向け)です。いくつかのチュートリアルを検索することをお勧めします。このコードでは、5つ以上の異なるAPI呼び出しが使用されています。さらに、コールバックを使用する必要があると確信しています。

于 2011-03-30T10:14:44.483 に答える