Author Topic: Redirecting output from .exe command line tool  (Read 4261 times)

0 Members and 1 Guest are viewing this topic.

SimonK

  • Newbie
  • *
  • Posts: 3
Redirecting output from .exe command line tool
« on: February 18, 2013, 03:22:01 AM »
When I redirect output from the command line version of PDFShellTool as follows

C:\Program Files\Intology\Drive Analyser>PDFshelltools SetMetaData "Metadata='Title=New Title'" J_71a.pdf >test.log

The file test log does not get created. Is there any way of redirecting output from the command line tool to a file so that I can programmatically check if the operation has been successful?

RTT

  • Administrator
  • *****
  • Posts: 768
Re: Redirecting output from .exe command line tool
« Reply #1 on: February 18, 2013, 10:25:32 AM »
Tried just now and is redirecting just fine. Are you trying from a open command line console or using another calling method?
That example of command line you show is also a bit dubious. What Windows version are you using? In Windows Vista and up, programs don't usually have permissions to write to the Program Files, and its sub-folders, and your example is doing exactly that by using relative paths.

Take also note that the PDFShellTools.exe can't work as stand alone. You must have a functional full install of the program.

SimonK

  • Newbie
  • *
  • Posts: 3
Re: Redirecting output from .exe command line tool
« Reply #2 on: February 18, 2013, 09:26:54 PM »
PDFShellTools.exe is running in a cmd window in Windows XP (The read-only property of the Program Files folder in Vista/Win 7/... has tripped me up before) but not in the install folder. Redirection indeed works fine when I use PDFShelltools.exe in the install folder.

Thanks for the prompt reponse.


SimonK

  • Newbie
  • *
  • Posts: 3
Re: Redirecting output from .exe command line tool
« Reply #3 on: February 19, 2013, 11:16:18 PM »
An extra wrinkle - redirection works OK from the Windows command line window but using the VBA function Shell with a command with redirection included as below fails to create the file:
Code: [Select]
sPath = C:\>"C:\Program Files\Intology\Drive Analyser\PDF-ShellTools\PDFShellTools" SetMetaData "Metadata='Title=NewTitle2'" "C:\Program Files\Intology\Drive Analyser\PDF-ShellTools\J_71.pdf" > "C:\Program Files\Intology\Drive Analyser\PDF-ShellTools\PDFShelltools.log"

Call Shell(sPath,0)




This a limitation of the VBA shell command. The code below from  http://www.xtremevbtalk.com/showthread.php?t=138193 by NCrawler provides a method of getting command line function output to a calling program in VBA without writing and then opening a file. Very useful!
Code: [Select]
Option Explicit

Private Declare Function CreatePipe Lib "kernel32.dll" (ByRef phReadPipe As Long, ByRef phWritePipe As Long, ByRef lpPipeAttributes As SECURITY_ATTRIBUTES, ByVal nSize As Long) As Long
Private Declare Function CreateProcess Lib "kernel32.dll" Alias "CreateProcessA" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByRef lpProcessAttributes As Long, ByRef lpThreadAttributes As Long, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, ByRef lpEnvironment As Any, ByVal lpCurrentDriectory As String, ByRef lpStartupInfo As STARTUPINFO, ByRef lpProcessInformation As PROCESS_INFORMATION) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function ReadFile Lib "kernel32.dll" (ByVal hFile As Long, ByRef lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, ByRef lpNumberOfBytesRead As Long, ByRef lpOverlapped As Long) As Long

Private Const STARTF_USESHOWWINDOW As Long = &H1
Private Const STARTF_USESTDHANDLES As Long = &H100
Private Const SW_HIDE As Long = 0

Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type

Private Type STARTUPINFO
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Byte
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type

Public Sub ExecAndCapture(ByVal sCommandLine As String, cTextBox As TextBox, Optional ByVal sStartInFolder As String = vbNullString)

Const BUFSIZE As Long = 1024 * 10
Dim hPipeRead As Long
Dim hPipeWrite As Long
Dim sa As SECURITY_ATTRIBUTES
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
Dim baOutput(BUFSIZE) As Byte
Dim sOutput As String
Dim lBytesRead As Long

    With sa
        .nLength = Len(sa)
        .bInheritHandle = 1    ' get inheritable pipe handles
    End With
   
    If CreatePipe(hPipeRead, hPipeWrite, sa, 0) = 0 Then
        Exit Sub
    End If
   
    With si
        .cb = Len(si)
        .dwFlags = STARTF_USESHOWWINDOW Or STARTF_USESTDHANDLES
        .wShowWindow = SW_HIDE          ' hide the window
        .hStdOutput = hPipeWrite
        .hStdError = hPipeWrite
    End With
   
    If CreateProcess(vbNullString, sCommandLine, ByVal 0&, ByVal 0&, 1, 0&, ByVal 0&, sStartInFolder, si, pi) Then
        Call CloseHandle(hPipeWrite)
        Call CloseHandle(pi.hThread)
        hPipeWrite = 0
        Do
            DoEvents
            If ReadFile(hPipeRead, baOutput(0), BUFSIZE, lBytesRead, ByVal 0&) = 0 Then
                Exit Do
            End If
            sOutput = Left$(StrConv(baOutput(), vbUnicode), lBytesRead)
            cTextBox.SelText = sOutput
        Loop
        Call CloseHandle(pi.hProcess)
    End If
    Call CloseHandle(hPipeRead)
    Call CloseHandle(hPipeWrite)
   
End Sub


RTT

  • Administrator
  • *****
  • Posts: 768
Re: Redirecting output from .exe command line tool
« Reply #4 on: February 19, 2013, 11:57:11 PM »
You don't need all that code. Just ShellExecute the cmd.exe, and pass as parameters /c and your pdfshelltools command line enclosed in double quotes.

Example in JScript:
Code: [Select]
var oShell = WScript.CreateObject("WScript.Shell");
oShell.Run('cmd.exe /c ""C:\\Program Files\\PDF-ShellTools\\pdfshelltools.exe" setmetadata "Metadata=\'Title=NewTitle\'" c:\\PDFs\\*.pdf>c:\\temp\\PDFShelltools.log"', 0 /* SW_HIDE*/, true /* bWaitOnReturn */);