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;

所以我想要的是在进程完成时(就在waitforsingleobject之后)写一行然后按“enter”按钮,最后在完成后关闭进程。有谁知道如何与外部进程交互?在编程方面,我是一个完全的新手。

此致

4

2 回答 2

4

您似乎正在尝试以编程方式让 Acrobat Read 打印您的文档。您的问题是,如果不要求用户交互,您就无法说服它这样做。

您当前的代码无法工作,因为您正在等待进程终止。一旦您从一个简单的 WaitForSingleObject 调用开始,您的任何代码都无法运行,直到进程终止。您没有机会让您的代码单击该按钮。

所以你需要做的是使用不同的等待策略。由于这似乎是一个相当粗略的黑客攻击,我会建议一些我通常不会建议的东西:轮询。而不是无限超时等待,您应该在一个循环中等待超时值,例如 250 毫秒。每次等待终止时,您都会检查进程是否已终止,或者等待是否超时。

当等待超时时,您有机会查找您想要查找的对话窗口。您应该可以使用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工具菜单中)。使用上述工具找到您要发送消息的窗口的类名,让您的代码过滤掉所有窗口,直到找到这个特定的窗口,然后使用 SendMessage api。

这听起来很复杂,而且(对于初学者来说)。我建议你四处寻找一些教程。该代码使用了 5 个或更多不同的 API 调用,而且我很确定您需要使用回调。

于 2011-03-30T10:14:44.483 回答