Как отправить строку или информацию процессу, который я открыл с помощью Createprocess в Delphi 7 - PullRequest
0 голосов
/ 30 марта 2011

Как отправить строку открытому процессу с помощью 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;

Итак, я хочу написать строку после завершения процесса (сразу после waitforsingleobject), а затем нажать кнопку «Ввод» и, наконец, закрыть процесс после его завершения. Кто-нибудь знает, как взаимодействовать с внешними процессами? Я новичок в программировании.

С наилучшими пожеланиями

Ответы [ 2 ]

4 голосов
/ 30 марта 2011

Вы, похоже, пытаетесь программно заставить Acrobat Read распечатать ваш документ. Ваша проблема в том, что вы не можете убедить его сделать это без запроса взаимодействия с пользователем.

Ваш текущий код не может работать, потому что вы ожидаете завершения процесса. Как только вы начнете с простого вызова WaitForSingleObject, ни один из вашего кода не сможет работать, пока процесс не завершится. У вас нет возможности для кода нажать эту кнопку.

Так что вам нужно использовать другую стратегию ожидания. Так как это выглядит довольно грубым взломом, я предложу кое-что, что я бы обычно не предлагал: опрос. Вместо ожидания с бесконечным тайм-аутом вы должны ждать в цикле со значением тайм-аута, скажем, 250 мс. Каждый раз, когда ожидание прекращается, вы проверяете, завершился ли процесс или, наоборот, истекло ли время ожидания.

Когда время ожидания истекло, у вас есть возможность найти диалоговое окно, которое вы хотите найти. Вы должны быть в состоянии найти его с помощью FindWindowEx(). Вы можете узнать его имя класса, используя Spy ++. После того, как вы нашли диалоговое окно, вам нужно найти дескриптор окна для элемента управления редактирования и кнопку, которую вы хотите нажать: EnumChildWindows() должна помочь.

Когда у вас есть ручки элементов управления, которыми вы хотите манипулировать, вы должны решить, как ими манипулировать. Если вам повезет, вы можете отправить строку с вызовом на SetWindowText, если это элемент управления EDIT или аналогичный. В противном случае вам, возможно, придется подделать нажатия клавиш или отправить WM_PASTE. Кнопка может быть более хлопотно. Нажатие на него включает отправку WM_COMMAND родительскому элементу кнопок. Снова Spy ++ может показать вам, какие сообщения отправляются, когда вы нажимаете кнопку.

Конечно, вы не можете найти свое окно, когда звоните FindWindowEx(), потому что оно еще не показывалось. Когда это происходит, вы снова идете по кругу с вызовом WaitForSingleObject().

Наконец, гораздо лучший способ справиться с этим - использовать библиотеку программного обеспечения, предназначенную для печати PDF!

0 голосов
/ 30 марта 2011

То, что вы хотите сделать, не совсем понятно.

Есть несколько способов отправить материал в процесс;

  • OLE-автоматизация (например, MSWord)
  • через CMDLine (например: notepad file.txt)
  • через STDIN (например, приложения cmd, использующие только стандартный ввод данных)
  • с помощью манипуляций (например, отправка определенных сообщений wm определенному процессуwindow)

На мой взгляд, вам нужен последний подход.

По сути, запустите правильные функции Windows API, чтобы получить список окон из вашего процесса.Затем используйте программу типа winspy, winspy ++ или ту, что с delphi (забыла, как она называется, она есть в меню инструментов Delphi).Используйте указанный инструмент, чтобы найти имя класса окна, в которое вы хотите отправлять сообщения, заставить свой код отфильтровывать все окна до тех пор, пока вы не найдете это конкретное, а затем использовать SendMessage api.

Звучит сложно, и этоесть (для начинающего).Я предлагаю вам поискать некоторые учебники.Код использует около 5 или более различных вызовов API, и я уверен, что вам нужно использовать обратный вызов.

...