in reply to Re: Re: OLE print to a file
in thread OLE print to a file

I don't get your problem. Why do you need to fork?

If you just need to wait between keystrokes (e.g. sending the filename to the window, then wait for some 10 seconds or some other conservative value depending on your local machine configuration, then send a carriage return to "press the OK button"), you can implement that yourself in your perl script.

I once implemented this sendkeys stuff as a tool in VBScript, with a syntax extension to the WSH (Windows Script Host) sendkeys syntax that allows for time delays to be included as escapes in the sendkeys string. Maybe the code helps you. Source of file "sendkeys.vbs" (NOTE: Yes, this is VBScript, not Perl, and yes, yes, I know you don't like VBScript, neither do I):

Option Explicit ' -------------------------------------------------- ' Setup ' -------------------------------------------------- ' Essential Variables Dim ApplicationTitle Dim ApplicationPath Dim ApplicationStartupDelay Dim ApplicationSendkeysDelay Dim SendkeysTextFile Dim SendkeysText Dim Matches Dim Regex Dim DelayMatches Dim DelayRegex ' Sendkeys Escaping Mechanism Detection - matches WSH Sendkeys escapes + Set Regex = New RegExp Regex.Pattern = "^(\~|\+.|\^.|\%.|{[^}]+}|{}})" ' Add Delay Feature to Sendkeys Syntax Set DelayRegex = New RegExp DelayRegex.Pattern = "^{DELAY [0-9]+}$" ' Helper Stuff Dim Wsh Dim Fso Dim Tso Dim i Dim s Dim buf ' Arguments and Configuration If (WScript.Arguments.Count < 3 ) Then PrintUsage() SendkeysTextFile = WScript.Arguments.Item(0) ApplicationTitle = WScript.Arguments.Item(1) ApplicationPath = WScript.Arguments.Item(2) ' Wrap in quotes for passing to Shell again ApplicationPath = """" & ApplicationPath & """" If (WScript.Arguments.Count > 3 ) Then ApplicationStartupDelay = WScript.Arguments.Item(3) Else ApplicationStartupDelay = 1000 End If If (WScript.Arguments.Count > 4 ) Then ApplicationSendkeysDelay = WScript.Arguments.Item(4) Else ApplicationSendkeysDelay = 100 End If ' Files Set Wsh = CreateObject("WScript.Shell") Set Fso = CreateObject("Scripting.FileSystemObject") Set Tso = Fso.OpenTextFile(SendkeysTextFile) SendkeysText = Tso.ReadAll() ' -------------------------------------------------- ' Action ' -------------------------------------------------- If (not (Wsh.AppActivate(ApplicationTitle))) Then Wsh.Run(ApplicationPath) Wscript.Sleep(ApplicationStartupDelay) if (not (Wsh.AppActivate(ApplicationTitle))) Then WScript.Echo("Error: Could not activate application" & _ ApplicationTitle & " using path " & _ ApplicationPath) WScript.Quit(1) End If End if For i = 1 To (Len(SendkeysText)) s = Mid(SendkeysText, i, 1) set Matches = Regex.Execute(Mid(SendkeysText, _ i,Len(SendkeysText) - i + 1)) If (Matches.Count > 0) Then buf = Matches.Item(0).Value i = i + Matches.Item(0).Length - 1 ' Wscript.Echo("===> " & buf & " <===") & vbCrLf If (DelayRegex.Test(buf)) Then set DelayMatches = DelayRegex.Execute(buf) Wscript.Sleep(Mid(DelayMatches.Item(0).Value, _ Len("{DELAY ") + 1, _ (Len(DelayMatches.Item(0).Value) _ - (Len("{DELAY ") + 1)))) Else Wsh.Sendkeys(buf) End If Else Wsh.Sendkeys(s) End If Wscript.Sleep(ApplicationSendkeysDelay) Next Wscript.Quit(0) ' -------------------------------------------------- ' subs ' -------------------------------------------------- Sub PrintUsage Dim UsageText UsageText = vbCrLf & _ "Usage: sendkeys <cmd-file> <app-title> <app-path> " & _ "[startup-delay] [sendkeys-delay]" & vbCrLf & _ vbCrLf & _ "Arguments and Options:" & vbCrLf & _ vbCrLf & _ " cmd-file: file containing keys to send " & vbCrLf & _ " app-title: window title of target application window" & v +bCrLf & _ " app-path: path to target application" & vbCrLf & _ " startup-delay: delay after application startup (in millis +econds, default 1000)" & vbCrLf & _ " sendkeys-delay: delay between keys (in milliseconds, defa +ult 100)" & vbCrLf & _ vbCrLf WScript.Echo(UsageText) WScript.Quit(1) End Sub

Christian Lemburg
Brainbench MVP for Perl
http://www.brainbench.com

Replies are listed 'Best First'.
Re: Re: Re: Re: OLE print to a file
by physi (Friar) on Jun 21, 2001 at 12:24 UTC
    Good morning again :)

    The reason why I need to use fork, is that the OLE $Word->ActiveDocument->PrintOut ... doesn't return until the print-procedure is finished.
    So it waits until the Save-to-file window is filled. but while the programm waits for the $Word->ActiveDocument->PrintOut ... procedure to return, it can't fill the Save-to-file window. So I need to implement a child process, which can do that specific job.

    Cheers,
    physi

    ----------------------------------- --the good, the bad and the physi-- -----------------------------------

      To avoid the forking stuff, you could just call another script via system like this:

      #!/usr/bin/perl -w use strict; system('start perl -e "sleep 5; print qq(\007)"'); print "Before the beep ...\n";

      The important part here is the "start" thing. It starts your process and then returns to the shell spawning it immediately. Now you just have to wait a sensible amount of time (the "sleep" part above), and the do the sendkeys stuff (the "print" part above), and it should work, if the period to sleep is stable.

      Christian Lemburg
      Brainbench MVP for Perl
      http://www.brainbench.com