Wer einen HTPC sein Eigen nennt und diesen über WLAN betreibt, kennt sicherlich das Problem das öfters mal Ruckler bei der Wiedergabe entstehen können (bei Benutzung eines Servers oder NAS). Aber auch Kabelbrüche mit sporadischen Netzwerktrennungen oder inkompatible Geräte & Treiber können dazu führen das man einen Film lieber zuerst auf die eigene Festplatte kopiert als diesen vom Server zu starten.
Um mir in solchen Fällen ein paar Handgriffe zu ersparen habe ich das folgende Script geschrieben. Für die Auswahl meiner Film-Aufnahmen benutze ich das Programm FreeCommander, dieses Tool kann auch mehrere Netzwerkfreigaben in Tabs gleichzeitig geöffnet halten. Zeitweise habe ich auch XBMC benutzt…
Mein Skript benötigt als erstes die Installation von Robocopy (bei Windows 7 und Vista bereits enthalten): Link.
In FreeCommander kann man anschließend über den Menüpunkt Extras\Programmfavoriten\Bearbeiten… das Script hinzufügen. Man fügt dort ein neues Element ein und ordnet diesem Element dann mein VB-Script zu – mit folgenden Parametern:
"%LeftDir%" "%LeftItem%" "E:\temp"
Denn mein Script erwartet drei Übergabeparameter: 1. das Verzeichnis der Quelldatei, 2. den kompletten Dateinamen (mit Pfad) und 3. das temporäre Verzeichnis zum Zwischenspeichern.
Wichtig: das temporäre Verzeichnis ist ohne abschließenden Backslash anzugeben - und sollte bereits existieren. Die Funktion GetFolder von VBS funktioniert übrigens nicht mit UNC-Pfaden, deswegen muss das Netzwerk-Share – ohne Dateinamen – einzeln übergeben werden (%LeftDir%).
Diesem neuen Programmfavoriten kann man in FreeCommander dann auch ein Tastenkürzel zuordnen - aber sobald man das Element hinzugefügt hat ist dafür auch ein neues Icon ganz links in der Toolbar zu sehen.
Die Praxis sieht dann so aus: man wählt im linken Fenster die Datei aus, klickt dann auf das Toolbar-Icon oder drückt die Tastenkombination des Skripts, und die selektierte Datei wird zuerst auf die lokale Festplatte ins temporäre Verzeichnis kopiert und anschließend von dort ausgeführt (nach Bestätigung) – sprich, die Wiedergabe wird gestartet.
Nachdem man den Player geschlossen hat kommt dann eine Abfrage, ob man die temporäre Datei wieder löschen möchte. Insgesamt also kein weltbewegendes Skript, aber es erspart einem ein paar ständig wiederkehrende Handgriffe. Außerdem ist robocopy beim Kopieren stabiler als der Windows-Explorer.
Nachfolgend nun das Skript, dieses ist in einer Textdatei mit der Endung .vbs abzuspeichern:
' Übergabeparameter:
' (0)=Verzeichnis der Quelldatei
' (1)=kompletter Dateiname mit Pfad
' (2)=temp. Verzeichnis
Option Explicit
dim Args
dim Shell
dim fso
dim Film
dim FileName
dim FileVerz
dim TempVerz
dim ZielDatei
dim rcopy
set Args = WScript.Arguments
set shell = CreateObject("WScript.Shell")
set fso = CreateObject("Scripting.FileSystemObject")
Film = """" & Args(1) & """"
FileName = fso.GetFileName(Film)
FileVerz = """" & Args(0) & """"
TempVerz = """" & Args(2) & """"
ZielDatei = """" & Args(2) & "\" & fso.GetFileName(Args(1)) & """"
rcopy = """" & "%SystemRoot%\System32\robocopy.exe" & """"
shell.run rcopy & " " & FileVerz & " " & TempVerz & " /IF " & FileName & " /W:3 /TBD /Z",1,vbtrue
msgbox "Film wird gestartet."
shell.run ZielDatei,1,vbtrue
if msgbox ("Film aus dem temporären Verzeichnis löschen?",vbOKCancel,"Frage")=1 then
'beim Löschen der Datei darf der Dateinamen-String nicht gequotet sein, beim Öffnen der Datei muss er es dagegen schon sein wegen evtl. Leerzeichen im Pfad/Dateinamen
zieldatei=mid(zieldatei,2,len(zieldatei)-2)
FSO.DeleteFile(zieldatei)
end if
set shell = nothing
set fso = nothing
Eine Funktion wie quotedstr() in Delphi damals scheint es in VBScript leider nicht zu geben. In dem Skript wird robocopy mit dem Parameter /Z gestartet, in diesem Modus fängt robocopy bei einer Netzwerk-Unterbrechung nicht von vorne mit dem Kopieren einer Datei an, sondern fährt fort wo er aufgehört hat.
Zuerst hatte ich daran gedacht das Player-Programm über das Skript festzulegen, aber dann ist mir eingefallen das man auch direkt eine Filmdatei öffnen kann – und das mit dem Dateityp von Windows assoziierte Programm spielt anschließend diese Datei ab.
Als ich noch den VLC direkt über das Skript starten wollte, funktionierte das übrigens über die Shell.Run-Funktion nicht – dafür musste ich die object.Exec-Funktion benutzen, siehe MSDN. Bei der Shell.Run-Methode sorgt der Parameter vbtrue dafür, das mit der Abarbeitung des Skripts bis zum Schließen des Programms gewartet wird.
Mit der object.Exec-Methode hätte es so ausgesehen:
Set VLCPfad = shell.Exec(
"%ProgramFiles(x86)%\VideoLAN\VLC\vlc.exe $Parameter$")
Do While VLCPfad.Status = 0
WScript.Sleep 100
Loop
Bedeutung: Programm starten, und mit einer Sleep-Schleife auf die Beendigung dieses Programms durch den User warten…
Kleine Ergänzung noch, bei %ProgramFiles(x86)% handelt es sich um eine Systemvariable (bei einem 64-Bit-Windows für die 32-Bit-Programme) - eine weitere Variable lautet %ProgramFiles% (bei einem 64-Bit-Windows sind dort die 64-Bit-Programme gespeichert, bei 32-Bit-Systemen die 32-Bit-Anwendungen). Wenn man sehen will welche Umgebungsvariablen im System definiert sind, öffnet man eine Eingabeaufforderung und gibt einfach SET ein.
Update 26.02.2011: FreeCommander selbst sollte die Argumente bereits gequotet übergeben, ansonsten kann es passieren das der Pfad bis zum Leerzeichen als erstes und der nachfolgende Teil als zweites Argument übergeben wird. Ich habe die obige Anleitung entsprechend angepasst. Nach der Übergabe sind die Anführungszeichen für das Script übrigens erst einmal wieder weg und müssen erst wieder hinzufügt werden.
Update 27.02.2011: bei Windows 7 (Professional, Business und Ultimate) gibt es auch die Funktion Offlinedateien: Link - bei meinem Vista 64 Home Premium ist diese Funktion im Synchronisierungscenter leider nicht enthalten. In früheren Windows-Versionen war diese Funktion auch bereits integriert, jedoch an einer anderen Stelle: Link. Mit dieser Funktion kann ein ganzes Netzwerkshare automatisch vollständig zwischengespeichert werden. Benötigt aber natürlich mehr Speicherplatz als mein Skript oben, und robocopy ist stabiler als die Standard-Kopierroutinen von Windows.
Nachfolgend noch ein paar wichtige Links:
In der Windows 7-Version von robocopy gibt es übrigens den neuen Parameter /MT, um multithreaded zu kopieren.