Clicky

20160828

Print PDF email attachements with hMailserver and Sumatra PDF

There are situations that you send an email with one purpose only and that is to print a PDF attachment.

In this case we have created a hMailserver script that:
- Checks for a specific email address ("pdfprint@youremaildomain.com");
- Checks a specific Subject field ("[pdfprint]");
- Checks for PDF attachment and if there is one, extract and print it.

To print the PDF, you need to have an app that renders PDFs and prints them. We are using Sumatra PDF, which has a command line interface that exactly does the job.

Steps:
  1. Create a new hMailserver user that will be used as a stub to receive the PDF print emails. Enter a long random password and forget it;
  2. Install Sumatra PDF. Take care of the location of the x86 or x64 version;
  3. Modify Eventhandler.vbs of hMailserver with the code below.
Notes:
  • Emails to "pdfprint@youremaildomain.com" will be discarded (not stored). You will see:
    "APPLICATION"    2284    "2016-08-28 08:48:37.699"    "SMTPDeliverer - Message 119900: Message deleted. Action was taken by script subscribing to OnDeliveryStart."
    " in the hMailserver eventlog;
  • You can address multiple printers (e.g. 2-side, b/w, color)) by adding additional Subject field markers and catch those in the script. Read the Samatra PDF documentation how to connect to specific printers;
  • You can add other attachment extensions (e.g. PNG, BMP, JPG, TXT, DOCX etc.) but then you need an app with a command line interface that is able to print the (extracted) file;
Tips:
  • You can set a rule to forward your emails that have the PDF print Subject marker ("[pdfprint]"). The email will stay in your email box while the PDF attachments are printed anyway
  • Now you can use even your tablet (Android, iPad) or Smartphone (BB, WP8, WP10, Android, iPhone) to print PDF right from your email app;
  • You can have much more checks like attachment size and filename , sender's email domain, etc. Let your fantasy flow!
---8<-------------------------
   Sub OnDeliveryStart(oMessage)
 
        dim wsh, fso, i
        dim AttachmentName, AttachmentType, tempAttachementName, tempFolder, objAttachement
        set wsh=CreateObject("wscript.shell")
        set fso=CreateObject("scripting.filesystemobject")


        tempFolder=fso.GetSpecialFolder(2)
  
        if oMessage.Attachments.Count > 0 then

            For i = 0 To oMessage.Attachments.Count-1

                set objAttachement = oMessage.Attachments(i)

                AttachmentName=tempFolder & "\" & objAttachement.Filename
                objAttachement.SaveAs(AttachmentName)
              
                AttachmentType=fso.GetExtensionName(AttachmentName)
                Select Case lcase(AttachmentType)
                Case "pdf"
                    Call WriteLogfile("Processing PDF attachment: " & AttachmentName)
                  
                    if lcase(oMessage.To)    =    "pdfprint@yourdomain.com"         and _
                        Instr(lcase(oMessage.Subject),"[pdfprint]") > 0      then                       
                        Call WriteLogFile("Printing PDF file for: " & oMessage.From & ", PDF file:'" & AttachmentName)
                        s="""C:\Program Files\SumatraPDF\SumatraPDF.exe"" -print-to-default " & chr(34) & AttachmentName & chr(34) & " -silent -exit-when-done"
                        wsh.run s,0,true
                        Call WriteLogfile("PDF print message processed.")                      
                    end if
                    fso.DeleteFile AttachmentName ,true
                End Select  
            next  
        end if

result.value=1   
End Sub
---8<-------------------------
   

20160801

Embedded binaries in VBscript

As I wrote before, VBscript is boo, boo and should be banned from the earth.

However, you can still do a lot of productive work with it. E.g. answer a long standing question: can I embed binary code, in this example an icon file, in my VBscript?

Yes you can! This is the method:

Step 1: Create a Base64 file from the icon file with the Windows build-in CERTUTIL command:

C:\> CERTUTIL -encode icon.ico icon.b64

The result will be a Base64 encoded "certificate" file. The "certificate" headers are used by CERTUTIL to recognize the start and end of the Base64 code.

Step 2: Append the Base64 code to your VBscript. Each line must be REMmed out to let the script run correctly. In this case the VBscript standard `' ` is used. So the code would look something like this:

' -----BEGIN CERTIFICATE-----
' AAABAAYAEBAAAAAACABoBQAAZgAAACAgAAAAAAgAqAgAAM4FAAAwMAAAAAAIAKgO
' AAB2DgAAEBAAAAAAIABoBAAAHh0AACAgAAAAACAAqBAAAIYhAAAwMAAAAAAgAKgl
' AAAuMgAAKAAAABAAAAAgAAAAAQAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAOLv

' ..
' ..
' AAAAHwAA/AAAAAA/AAD+AAAAAH8AAP+AAAAA/wAA/8AAAAP/AAD/4AAAB/8AAP/4
' AAAf/wAA//4AAH//AAD//8AD//8AAA==
' -----END CERTIFICATE-----


Step 3: Now we have to add some code to extract and decode the Base64 data from the VBscript:

    dim fso : set fso=CreateObject("scripting.FileSystemObject")
    dim wsh : set wsh=CreateObject("wscript.shell")
   
    '--- Extract ICO file in the %TEMP% folder...
    iconFile=fso.GetSpecialFolder(2) & "\icon"
    set f=fso.OpenTextFile(WScript.ScriptFullName)
    s=replace(f.ReadAll,"' ","")
    f.close
    set f=fso.OpenTextFile(iconFile & ".tmp",2,TRUE)
    f.writeline(s)
    f.close
    wsh.run "certutil -decode " & iconFile & ".tmp" & " " & iconFile & ".ico",0,true


This code will read the VBscript, strips the REM code, writes the result in the TEMP folder and uses CERTUTIL to decode the Base64 data in the icon (binary) file in the TEMP folder:

C:\>dir %temp%\icon.ico
 Volume in drive C has no label.
 Volume Serial Number is 7AC3-9DD3

 Directory of C:\Users\thisuser\AppData\Local\Temp

08/01/2016  06:40 AM            22,486 icon.ico
               2 File(s)        
22,486 bytes
               0 Dir(s)  25,406,103,552 bytes free


Now you can piggyback any binary inside your VBscript. Enjoy! 





Real Time Web Analytics