in reply to OLE print to a file

You need the "sendkeys" functionality (send keystrokes to a window identified by its title or window id) - it's available in several Perl modules (e.g., SendKeys in Win32::SetupSup, which can be found at Roth's site). There is some nice wrapup on how to use Win32::SetupSup in chapter 4 of "Perl for System Administration" (from O'Reilly).

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

Replies are listed 'Best First'.
Re: Re: OLE print to a file
by physi (Friar) on Jun 20, 2001 at 20:24 UTC
    Good hint, thx ;)
    I use Win32::GuiTest for the job now, there is also an sendkeys implemented.
    but now I have the problem, that my program waits until the "Save to ... " Window is closed. So I have to use fork on Win NT and up to now I only get Dr. Watson to say Hello everytime I try to fill the window by the child process. ;-()
    But I'll keep on trying ... tomorrow :)

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

      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

        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-- -----------------------------------