physi has asked for the wisdom of the Perl Monks concerning the following question:

Hi brothers ;)

After a couple of weeks non-perl-work :(
I now try to get some experience with the Windows-perl world.
But I have a litte question and can't find anything in the documentation.

Ok, the problem is, that I want to use OLE to 'convert' a Word-file into postscript, make a accounting of the pages, upload it to Unix, and do there some magic work with the file, before uploading it to the MVS-world to print it out :)

The unix - perl part is still available and good working :)
But what I need is a chance to print the .doc file via OLE (that's easy). But I defined the printer to print to a file! So during each printing there raises a window, which ask me for the filename.
I like to put that into the automatism, so that the user don't need to interact during the printing.
So the question is, how can I comunicate from within perl to the print-to-with-filename window ?
Maybe someone solved this problem already or can give me a hint for the correct magic-word to search for in the documentaion :)

Thanks

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

Replies are listed 'Best First'.
Re: OLE print to a file
by clemburg (Curate) on Jun 20, 2001 at 12:53 UTC

    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

      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

Re: OLE print to a file
by Anonymous Monk on Jun 20, 2001 at 14:27 UTC
    There is a parameter in your OLE-function with a silly Name like 'InteractionAllowed' or so. If you don't allow Interaction no Dialog is shown.
Re: OLE print to a file
by John M. Dlugosz (Monsignor) on Jun 20, 2001 at 18:39 UTC
    You can find the window in question (via it's title and/or class) and call PostMessage or SendMessage to simulate clicking on the button, filling out the text fields, etc.
Re: OLE print to a file
by DCMonkey (Initiate) on Jun 22, 2001 at 03:14 UTC
    You might try Redmon (aka Redirection Port Monitor). It allows one to redirect a print job's output to a program's stdin. Not strictly a Perl solution, but it could do the job.