lkaderavek
Goto Top

Automatische PDF-Erstellung und Mail-Versand aus einem Verzeichnis

TIFF-Dateien, die in ein Verzeichnis kommen automatisch in PDF umwandeln und per Mail versenden

Hallo,

ich möchte von meinem SBS 2003 den FAX-Dienst ein bisschen erweitern.

Folgende Situation, bei FAX-Empfang wird eine TIFF-Datei erstellt und in einem FAX-Verzeichnis abgelegt.

Diese Datei soll voll automatisch in PDF umgewandelt und per Mail versendet werden.

Bei FreePDF gibt es die Funktion per Mail versenden, kann man das Programm auch über eine Command-Shell bedienen?

Bitte um Info.

Danke

Ciao

Lukas

Content-Key: 170266

Url: https://administrator.de/contentid/170266

Printed on: April 20, 2024 at 02:04 o'clock

Member: Friemler
Friemler Jul 22, 2011 at 15:17:59 (UTC)
Goto Top
Hallo Lukas,

Betr. PDF erstellen über Batchscript: Schau mal hier nach.

Um das Verzeichnis, in dem die TIFF-Dateien abgelegt werden, auf neu erstellte Dateien zu überwachen, hätte ich auch noch eine Script-Lösung, per WMI Permanent Event Consumer (resourcenschonend). Es würde dann jedesmal ein Script gestartet (zuerst z.B. eine angepasste Version des obigen Scripts, dann weiterer Code, der die PDF-Datei per EMail verschickt). Das Monitor- und EMail-Script ist zwar schon quasi fertig (es müssen im Monitor nur 2 Zeilen VBScript angepasst werden, im EMail-Part etwas mehr), es ist aber etwas Erklärungsaufwand nötig, den ich nur betreiben will, wenn es sein muss. Außerdem: Wie sind Deine Scriptingfähigkeiten? Läuft ein Exchange Server auf dem System?

Gruß
Friemler
Member: LKaderavek
LKaderavek Jul 22, 2011 at 15:31:12 (UTC)
Goto Top
Hallo,

es läuft ein Exchange 2003.

Ich kenn mich mit Batch und VB-Script recht gut aus.

Danke für die Hilfe.
Member: Friemler
Friemler Jul 22, 2011 at 16:29:17 (UTC)
Goto Top
Hallo Lukas,

Ein Permanent Event Consumer muss einmalig über ein VBScript installiert werden.

Zunächst wird ein EventConsumer erstellt, dann ein Filter und schließlich ein Binding zwischen diesen beiden.

WMI stellt mehrere vordefinierte EventConsumer zur Verfügung, der praktischste ist der CommandLineEventConsumer. Wenn das im Filter angegebene Ereignis eintritt (hier: In einem bestimmten Verzeichnis wird eine neue Datei angelegt), kann der CommandLineEventConsumer ein Programm starten.

Im folgenden Script habe ich dafür CSCRIPT.exe, also den Windows Scripting Host für die Konsole genommen. Dem aufgerufenen Programm können Parameter übergeben werden. Das sind hier der Name eines VBScript, das sich im gleichen Verzeichnis wie der Installer befinden muss und auch dort verbleiben muss, sowie die Daten, die sich aus den WMI-Eventdaten gewinnen lassen (der vollständige Pfad zur Datei).

Die gestarteten Programme werden unter dem SYSTEM-Konto in Session 0 ausgeführt und können nicht interaktiv sein. Wenn z.B. CMD.exe mit einem auszuführenden Batchscript als Parameter gestartet wird, funktionieren deshalb dort Ein-/Ausgabeumleitungen nicht, da dem CMD-Prozess keine Konsole zugeordnet wird.

Hier also erstmal der Installer für den Permanent EventConsumer. Das Script muss mit Adminrechten ausgeführt werden, aber wie gesagt nur einmalig, auch nach einem Reboot bleibt die Registrierung bei WMI erhalten. Das Script kann danach gelöscht werden.

Es müssen nur die Zeilen 13 bis 15 angepasst werden:
  • strEventDescription: Unter diesem Bezeichner wird der Event Consumer in WMI registriert. Der Name des Scripts, das beim Eintreten des Events gestartet wird, wird ebenfalls aus diesem Wert erzeugt und muss für diesen Beispielfall NewTextfileCreationEventHandler.vbs heissen und sich zum Zeitpunkt der Installation des Event Consumers im gleichen Verzeichnis wie das Installscript befinden und später auch dort bleiben.
  • strMonitorFileSpec: Gib das zu überwachende Verzeichnis und den Dateityp an, hier sind es also TIFF-Dateien im Verzeichnis E:\Test.
  • strPollingIntervall: Gibt die Zeit in Sekunden an, nach der WMI prüfen soll, ob eine neue Datei im Verzeichnis angelegt wurde. Selbst ein Wert, wie hier, von einer Sekunde, erzeugt nur eine geringe Prozessorlast.

' ===========================================  
' Run this script with administrative rights!  
' ===========================================  



'/////////////////////////////// Configure script's job ///////////////////////////////  

'******************** Customize according to your specific needs **********************  

'------------------ Set event description and job related variables -------------------  

strEventDescription  = "New Textfile Creation"  
strMonitorFileSpec   = "E:\Test\*.TIFF"  
strPollingIntervall  = "1"  



'---------------- Prepare Monitor Filespec for WMI Event Filter query -----------------  

Set FSO              = CreateObject("Scripting.FileSystemObject")  

strDrive             = FSO.GetDriveName(strMonitorFileSpec)

strFileName          = FSO.GetFileName(strMonitorFileSpec)
intPathBegin         = Len(strDrive) + 1
intPathLen           = Len(strMonitorFileSpec) - Len(StrDrive) - Len(strFileName)
strPath              = Replace(Mid(strMonitorFileSpec, intPathBegin, intPathLen), "\", "\\")  

strExtension         = FSO.GetExtensionName(strMonitorFileSpec)

Set FSO              = Nothing



'----------------------------- Set WMI Event Filter query -----------------------------  

strEventFilterQuery  = "SELECT * FROM __InstanceCreationEvent" _  
                     & " WITHIN " & strPollingIntervall _  
                     & " WHERE TargetInstance ISA 'CIM_DataFile'" _  
                     & " AND TargetInstance.Drive='" & strDrive & "'" _  
                     & " AND TargetInstance.Path='" & strPath & "'" _  
                     & " AND TargetInstance.Extension='" & strExtension & "'"  



'-------------- Set WMI Namespace where the monitored event will occure ---------------  

strEventNamespace    = "root\Cimv2"  



'----------- Set parameters which should be passed to Event Handler script ------------  

strEventHandlerParam = """" _  
                     & "%TargetInstance.Drive%" _  
                     & "%TargetInstance.Path%" _  
                     & "%TargetInstance.FileName%" _  
                     & "." _  
                     & "%TargetInstance.Extension%" _  
                     & """"  

'**************************************************************************************  





'//////////////////////////////// Set script variables ////////////////////////////////  

'- Set Event Handler path, quote it and prepare it and its working directory for WMI --  

Set FSO           = CreateObject("Scripting.FileSystemObject")  

strEventHandlerWD = Replace(FSO.GetParentFolderName(WScript.ScriptFullName), "\", "\\")  

strEventHandler   = Replace(strEventDescription, " ", "") & "EventHandler.vbs"  
strEventHandler   = """" & strEventHandlerWD & "\\" & strEventHandler & """"  

Set FSO           = Nothing



'----------------------- Test for existing Event Handler script -----------------------  

Set FSO = CreateObject("Scripting.FileSystemObject")  

If Not FSO.FileExists(Replace(Replace(strEventHandler, "\\", "\"), """", "")) Then  
  MsgBox "The Event Handler script " & vbCRLF _  
          & Replace(strEventHandler, "\\", "\") & vbCRLF _  
          & "does not exist. Please create it.", _  
         vbExclamation, _
         "Missing Event Handler script"  
End If

Set FSO = Nothing



'-------------------------- Build parameters for CScript.exe --------------------------  

strCScriptParam = strEventHandler & " " & strEventHandlerParam  



'---------------- Get path of Windows Directory and prepare it for WMI ----------------  

Set WshShell    = WScript.CreateObject("WScript.Shell")  

strWinDir       = Replace(WshShell.ExpandEnvironmentStrings("%SystemRoot%"), "\", "\\")  

Set WshShell    = Nothing
 


'---------------------- Set path of CScript.exe prepared for WMI ----------------------  

setCScriptPath  = strWinDir & "\\System32\\cscript.exe"  





'////////////////////////// Install permanent Event Consumer //////////////////////////  

'------- Get WMI Scripting API object (SWbemServices), Namespace: Subscription --------  

strComputer                          = "."  
Set objWMIService                    = GetObject("winmgmts:" _  
                                                 & "{impersonationLevel=impersonate}!" _  
                                                 & "\\" & strComputer & "\root\Subscription")  



'------------------------------ Create the Event Filter -------------------------------  

Set objFilterClass                   = objWMIService.Get("__EventFilter")  
Set objFilter                        = objFilterClass.SpawnInstance_()

objFilter.Name                       = strEventDescription & " Event Filter"  
objFilter.EventNamespace             = strEventNamespace
objFilter.QueryLanguage              = "WQL"  
objFilter.Query                      = strEventFilterQuery

Set EventFilterPath                  = objFilter.Put_()



'----------------------- Create the Commandline Event Consumer ------------------------  

Set objEventConsumerClass            = objWMIService.Get("CommandLineEventConsumer")  
Set objEventConsumer                 = objEventConsumerClass.SpawnInstance_()

objEventConsumer.Name                = strEventDescription & " Commandline Event Consumer"  
objEventConsumer.CommandLineTemplate = setCScriptPath & " " & strCScriptParam  
objEventConsumer.ExecutablePath      = setCScriptPath
objEventConsumer.WorkingDirectory    = strEventHandlerWD
objEventConsumer.ShowWindowCommand   = 0

Set CommandlineEventConsumerPath     = objEventConsumer.Put_()



'------------------ Bind Event Filter to Commandline Event Consumer -------------------  

Set objBindingClass                  = objWMIService.Get("__FilterToConsumerBinding")  
Set objBinding                       = objBindingClass.SpawnInstance_()

objBinding.Filter                    = EventFilterPath
objBinding.Consumer                  = CommandlineEventConsumerPath

objBinding.Put_()


Hier jetzt der Eventhandler, das Script, das EMails verschicken kann. Es wird das Colaboration Data Object (CDO) verwendet, deshalb meine Frage nach Exchange. Mit Exchange 2000/2003 gibt es keine Probleme, bei 2007 muss es erst nachinstalliert werden, ebenfalls bei Exchange 2010. Dort gibt es aber noch mehr zu beachten bzgl. der verwendeten CSCRIPT.exe auf 64Bit-Systemen. Eine Übersicht liefert diese Seite.

Es kann eingestellt werden, ob über SMTP oder SMTP over SSL gesendet wird, je nach Portwahl in Zeile 17. Wenn nicht die Standardports benutzt werden, muss auch der SELECT-CASE-Block ab Zeile 72 angepasst werden.

Dieses Script muss so benannt werden, wie oben bei der Erklärung von strEventDescription beschrieben.

Da das Script unter dem SYSTEM-Konto ausgeführt wird, sollten entsprechende NTFS-Zugriffsrechte betreffend Zugriff und Ändern gesetzt werden, um einen Missbrauch zu verhindern.

Const cdoSendUsingPickup = 1 'Send message using the local SMTP service pickup directory.  
Const cdoSendUsingPort   = 2 'Send the message using the network (SMTP over the network).  

Const cdoAnonymous       = 0 'Do not authenticate  
Const cdoBasic           = 1 'basic (clear-text) authentication  
Const cdoNTLM            = 2 'NTLM  


Set listArgs = WScript.Arguments

If listArgs.Count = 1 Then
  strSenderName     = "Your Name"  
  strSenderEMail    = "YourEMailAddress@Provider.com"  
  strRecipientEMail = "RecipientEMailAddress@Provider.com"  

  strSMTPServer     = "Your.SMTP.Server"  
  intSMTPPort       = 465
  strSMTPUserName   = "YourSMTPUserName"  
  strSMTPPassWord   = "YourSMTPPassword"  

  '  
  '  
  ' Hier Code zum Erzeugen der PDF-Datei einfügen.  
  ' Der Pfad+Name der neu erstellten TIFF-Datei steht in listArgs(0)  
  '  
  '  
  
  strSubject        = "Neue Datei"  
  strMailBody       = "Nachrichtentext"  
  strAttachmentFile = "Laufwerk:\Pfad\Datei.pdf"  'Hier den Pfad zur erzeugten  
                                                  'PDF-Datei einfügen  


  Set objMessage      = CreateObject("CDO.Message")  

  objMessage.Subject  = strSubject
  objMessage.From     = """" & strSenderName & """ <" & strSenderEMail & ">"  
  objMessage.To       = strRecipientEMail
  objMessage.TextBody = strMailBody

  If strAttachmentFile <> "" Then  
    objMessage.AddAttachment strAttachmentFile
  End If
  

  '==This section provides the configuration information for the remote SMTP server.  

  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/sendusing") = cdoSendUsingPort  

  'Name or IP of Remote SMTP Server  
  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strSMTPServer  

  'Type of authentication, NONE, Basic (Base64 encoded), NTLM  
  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = cdoBasic  

  'Your UserID on the SMTP server  
  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/sendusername") = strSMTPUserName  

  'Your password on the SMTP server  
  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = strSMTPPassWord  

  'Server port (typically 25 or 465 (SMTP over SSL))  
  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = intSMTPPort  

  'Use SSL for the connection (False or True)  
  Select Case intSMTPPort
    Case 25 :
      objMessage.Configuration.Fields.Item _
      ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = False  

    Case 465:
      objMessage.Configuration.Fields.Item _
      ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True  
      
  End Select

  'Connection Timeout in seconds (the maximum time CDO will try to establish a connection to the SMTP server)  
  objMessage.Configuration.Fields.Item _
  ("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 60  

  objMessage.Configuration.Fields.Update

  '==End remote SMTP server configuration section==  


  objMessage.Send

  Set objMessage = Nothing
End If

Set listArgs = Nothing

Wie schon als Kommentar im Script erwähnt wird, fehlt hier noch der Code zur Erzeugung der PDF-Datei. Da Du schreibst, Du kennst Dich mit Batchscript und VBS gut aus, solltest Du es ja schaffen, das Batchscript aus meinem Link oben in VBS umzuschreiben.


Genauere Informationen im Zusammenhang mit Permanent Event Consumers finden sich auf folgenden Seiten:

http://msdn.microsoft.com/en-us/library/aa392395%28v=VS.85%29.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2010/12/06/learn-how ...
http://www.codeproject.com/KB/system/PermEvtSubscriptionMOF.aspx
http://msdn.microsoft.com/en-us/library/aa394649%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa394639%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa394647%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/aa387236%28VS.85%29.aspx
http://www.codeproject.com/KB/system/WQLByExample.aspx


Gruß
Friemler
Member: Friemler
Friemler Jul 24, 2011 at 19:48:32 (UTC)
Goto Top
Hallo Lukas,

zum konvertieren der TIFF-Dateien nach PDF kann IrfanView verwendet werden. Dabei gibt es allerdings einiges zu beachten:

Vorbereitungen
  • Das Installer-Script und das Eventhandler-Script z.B. in das Verzeichnis C:\Programme\Automatic-Fax2EMail (Windows XP/Server2003) bzw. C:\Program Files\Automatic-Fax2EMail (ab Vista) kopieren.
  • Von der Homepage von IrfanView die aktuelle Version 4.30 und die Plugins herunterladen.

Dann folgende Schritte ausführen:
  • IrfanView installieren. Während der Installation erscheint eine Abfrage, wo das INI-File des Programms abgespeichert werden soll. Bis XP/Server 2003 Irfan View folder auswählen, für Windowsversionen ab Vista User's Application Data folder (recommended for Vista/Windows 7) wählen.
  • Plugins installieren.
  • IrfanView starten.
  • Unter Menü Optionen -> Einstellungen... gewünschte Einstellungen vornehmen, z.b. Sprache auf Deutsch umstellen.
  • Jetzt irgendein Bild mit IrfanView öffnen.
  • Unter Menü Datei -> Speichern Unter... wählen.
  • Als Dateityp PDF auswählen. -> Es erscheint ein zusätzliches Optionsfenster für das PDF-Plugin.
  • In diesem Fenster den Radiobutton unter Registerkarte Allgemein -> Vorschau des PDFs während des Speicherns -> nicht notwendig (wähle Einstellungen jetzt) aktivieren. Wichtig!
  • Unter Registerkarte Layout -> Seitenformat das Seitenformat für die PDF-Datei einstellen, z.B. A4. Wichtig!
  • Seitenformat (Hoch, Quer) einstellen.
  • Unter Bildposition "Im Zentrum" wählen.
  • Unter Bildgröße "Optimal" auswählen. Wichtig! Dadurch wird das Bild unter Beibehaltung des Seitenverhältnisses auf die Größe des eingestellten Seitenformats skaliert.
  • Den Haken unter Registerkarte Sicherheit -> Sicherheit aktivieren löschen. Wichtig! Ansonsten wird auch bei Aufruf von IrfanView mit Parametern zum konvertieren von Dateien nach PDF ein Dialog zur Passworteingabe dargestellt, der aber bei Ausführung aus dem EventHandler-Script nicht sichtbar ist. -> Das Script bleibt hängen.
  • Das geladene Bild speichern, damit die Einstellungen aus dem PDF-Optionenfenster gespeichert werden. Danach kann IrfanView beendet werden.

Die folgenden Schritte müssen nur unter Windowsversionen ab Vista ausgeführt werden:
  • Über den Windows Explorer in folgendes Verzeichnis wechseln: C:\Users\Benutzer\AppData\Roaming\IrfanView
  • Die Datei i_view32.ini in das Verzeichnis kopieren, in das das Installer-Script und das Eventhandler-Script unter Vorbereitungen kopiert wurden. Da das Eventhandler-Script unter dem SYSTEM-Konto ausgeführt wird, muss ein separates INI-File dafür zur Verfügung stehen, damit IrfanView seine Einstellungen laden kann. Die im Benutzerprofil abgelegte INI-Datei wird nicht gefunden.
  • Folgenden Code in das Eventhandler-Script an der Stelle einfügen, an der die PDF-Datei erzeugt werden muss (siehe Kommentare dort).
Set objFSO   = CreateObject("Scripting.FileSystemObject")  
Set objShell = WScript.CreateObject("WScript.Shell")  
strDestFile  = objFSO.BuildPath("E:\Fax2PDF", objFSO.GetBaseName(listArgs(0)) & ".pdf")  
objShell.Run """%ProgramFiles%\IrfanView\i_view32.exe"" """ & listArgs(0) & """ /ini=""%ProgramFiles%\Automatic-Fax2EMail"" /convert=""" & strDestFile & """", 0, True  

strSubject        = "Neue Datei"  
strMailBody       = "Nachrichtentext"  
strAttachmentFile = strDestFile
Den Pfad beim Parameter /ini=... in Zeile 4 bitte anpassen. Hier das Verzeichnis einsetzen, in das die i_view32.ini kopiert wurde.

Unter XP/Server2003 folgende Codezeilen einfügen:
Set objFSO   = CreateObject("Scripting.FileSystemObject")  
Set objShell = WScript.CreateObject("WScript.Shell")  
strDestFile  = objFSO.BuildPath("E:\Fax2PDF", objFSO.GetBaseName(listArgs(0)) & ".pdf")  
objShell.Run """%ProgramFiles%\IrfanView\i_view32.exe"" """ & listArgs(0) & """  /convert=""" & strDestFile & """", 0, True  

strSubject        = "Neue Datei"  
strMailBody       = "Nachrichtentext"  
strAttachmentFile = strDestFile

In beiden Fällen den Pfad E:\Fax2PDF in Zeile 3 bitte anpassen. In diesem Verzeichnis werden die erzeugten PDF-Dateien abgelegt.

  • Nachdem im Eventhandler-Script noch die Daten zur EMail-Übermittlung eingetragen wurden (Sender, Empfänger, SMTP-Daten), das Script speichern.
  • Jetzt noch das Verzeichnis anlegen, in dem die PDF-Dateien abgelegt werden sollen.
  • Im Installer-Script den Wert der Variablen strMonitorFileSpec anpassen (das Verzeichnis eintragen, wo die TIFF-Dateien der Faxe abgelegt werden) und ebenfalls speichern.

Nachdem das Installer-Script ausgeführt wurde, wird die nächste TIFF-Datei, die im Fax-Verzeichnis neu angelegt wird, in eine PDF-Datei konvertiert und per EMail verschickt.

Wenn es erstmal nicht funktionieren sollte, kann man zum debuggen im Eventhandler-Script leider nur eine Textdatei erzeugen und die zu überprüfenden Werte hineinschreiben, da man bei der Ausführung des Eventhandlers kein Konsolenfenster zu sehen bekommt und auch keine Messagebox anzeigen kann.

Gruß
Friemler
Member: LKaderavek
LKaderavek Jul 25, 2011 at 06:28:52 (UTC)
Goto Top
Hallo Friemler!

Danke für deine Mühe, ich werde das ausprobieren und gebe dir Bescheid, wie und ob es funkioniert hat.

Ciao

Lukas
Member: Friemler
Friemler Jul 27, 2011 at 11:12:42 (UTC)
Goto Top
Komisch, 80-90% der Leute, die sowas schreiben, machen das dann nicht.
Member: Skyemugen
Skyemugen Aug 31, 2011 at 11:45:06 (UTC)
Goto Top
Zitat von @Friemler:
Komisch, 80-90% der Leute, die sowas schreiben, machen das dann nicht.
Wahrscheinlich, weil gar nichts
funkioniert
hat aber funktioniert, da er aber nicht schrieb, dass er Bescheid gibt, ob es funktioniert hat, ist er im Recht face-wink
Member: LKaderavek
LKaderavek Aug 31, 2011 at 11:50:14 (UTC)
Goto Top
Hallo,

diese Lösung hat funktioniert...

War nur zu zeitaufwändig und da es ein SBS ist, wurde der FAX-Service genutzt und die FAX kommen jetzt im TIF-Format.

Habe bloß vergessen, mich zu melden...Sommer ist Urlaubszeit und ich hab's verschwitzt!

Danke nochmals.

Ciao

Lukas