ahe
Goto Top

Leere Datei erkennen

Hallo,

irgendwie steh' ich etwas auf dem Schlauch und komm' nicht weiter, dabei sieht es so simpel aus... face-smile

Ich versuche in einer Batch einen Kopier-Job zu starten, der allerdings erst einmal prüft, ob die Datein auf einer eingeschobenen CD/DVD liegen, oder ober er lieber im Netz nachschauen soll. Das Kopieren ist dabei nicht das Problem, auch nicht die Verbindung zum Netz.

Das Problem ist die Erkennung des CD/DVD Laufwerksbuchstabens. Dafür habe ich mir ein Skript gebastelt (unter Mithilfe einiger Biber'scher und BASTLAscher Beiträge... face-smile) und es funktioniert sogar: GetCDDriveLetter.vbs (kann man vielleicht noch 'mal brauchen, verbessern, oder gar verBASTLAn/verBIBERn... face-smile

On Error Resume Next
Dim objFSO
Dim objFile
Dim objFolder
Dim strDateiname
Dim strPFAD
Dim mysource

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

Set FSO = CreateObject("Scripting.FileSystemObject")   
Set Drives = FSO.Drives
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")  
strDateiname = WScript.ScriptFullName
Set objFolder = objFSO.getFolder(objFSO.getParentFolderName(strDateiname))
strDateiname = objFSO.getFileName(strDateiname)

Set colItems = objWMIService.ExecQuery("Select * from Win32_CDROMDrive")  

For Each objItem In colItems
	If objItem.MediaLoaded = vbTrue Then
		If (objFSO.FileExists(objItem.Drive & "\historie.txt")) Then  
			mysource = objItem.Drive
				'MsgBox "Verzeichnis vorhanden und Datei vorhanden!" & mysource & "\historie.txt"  
				WScript.echo mysource 
		End If
	End If
Next

Set Drives = Nothing
Set objFSO = Nothing
wscript.quit

Aufgerufen wird das VBScript in einer Batch und das Ergebnis in einer Datei abgelegt:
set sourcepath=
set tmpdirlog=c:\temp\dvddir.log
cscript //nologo %~dp0\GetCDDriveLetter.vbs >%tmpdvdlog%

Nun durchforste ich diese Datei (sollte ja bestenfalls nur ein einziges Zeichen sein) und setze meine Variable "sourcepath" für den Pfad:
for /F %%i in (%tmpdvdlog%) do (set sourcepath=%%i)

Dies funktioniert auch, aber nur dann, wenn auch eine CD/DVD eingelegt ist. Ist dies nicht der Fall, dann ist die Datei %tmpdvdlog% leer und es wird nix gesetzt, was so nicht beabsichtigt war... schließlich brauche ich ja einen Pfad...

Schön wäre jetzt, wenn ich einfach Folgendes in der For-Schleife machen könnte:
for /F %%i in (%tmpdvdlog%) do (
     if %%i =="" (  
          set sourcepath=\\netzwerkpfad\name
     ) else (
          set sourcepath=%%i
     )
)

Und genau das funktioniert nicht... face-sad es wird nix gesetzt, ein echo %sourcepath% bringt nur die Meldung, dass echo off ist...

Es ist irgendetwas mit dem IF, aber ich komme nicht 'drauf. Ich denke es ist eine Kleinigkeit, aber diese hält mich etwas auf... (vielleicht ist es auch einfach zu spät?)

Gute Nacht
Axel

Content-ID: 68552

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

Ausgedruckt am: 25.11.2024 um 04:11 Uhr

bastla
bastla 13.09.2007 um 01:49:25 Uhr
Goto Top
Hallo ahe!

Unter der Annahme, dass eine leere Datei eine Länge von 0 Byte hat, könnte als Workaround ja vielleicht (ungetestet)
for %%i in (%tmpdvdlog%) do if %%~zi equ 0 (
          set sourcepath=\\netzwerkpfad\name
) else (
          set sourcepath=%%i
)
klappen ...

... oder auch (genauso ungetestet, würde mir aber besser gefallen):
set sourcepath=
for /f %%i in ('cscript //nologo %~dp0\GetCDDriveLetter.vbs') do set sourcepath=%%i  
if not defined sourcepath set "sourcepath=\\netzwerkpfad\name"  

Grüße
bastla
maneich
maneich 13.09.2007 um 01:57:14 Uhr
Goto Top
Hallo,

ob ein drive exists oder isredy ist in vbs zweierlei.

Erläuterungen von MS dazu:

Bei Laufwerken mit austauschbaren Datenträgern gibt die DriveExists-Methode true zurück, auch wenn kein Datenträger eingelegt ist. Verwenden Sie die IsReady-Eigenschaft des Drive-Objekts, um festzustellen, ob das Laufwerk bereit ist.

Soll heißen, Der LW-Buchstabe ist ja vom System vergeben; nur ansprechen kannst Du das Laufwerk nicht, da es ohne Cd oder DVD nicht nicht aktiv ist.

Man sollte nicht alles so kompliziert machen, Möglichkeiten:

1. im VBScript Abfrage nach IsReady und wenn nein Aufforderung entsprechende CD/DVD einlegen und das alles in einer Schleife.

2. nach "for /F %%i in (%tmpdvdlog%) do (set sourcepath=%%i)"
Abfrage
if not %sourcepath" = "" goto weiter
echo keine CD/DVD im Laufwerk, Daten hier eingeben!!
set /p sourcepath=eingabe:
:weiter
... entsprechende Befehle

MfG maneich
ahe
ahe 13.09.2007 um 09:28:42 Uhr
Goto Top
Danke bastla,

gibt es eigentlich eine Nacht für Dich? face-smile


Mir gefällt die zweite Variante auch besser, wenn sie denn funktioniert.

Ich probiere sie gleich 'mal aus und melde mich dann wieder.

mfg
Axel
ahe
ahe 13.09.2007 um 09:41:07 Uhr
Goto Top
Danke maneich,

noch so ein Nachtschwärmer face-smile

Die Idee zu 2. war mir auch schon gekommen, allerdings kenne ich die Faulheit der Admins (bin selbst einer) immer etwas eingeben zu müssen und dann auch noch immer richtig... face-smile

Darum wollte ich das Ganze automatisiert machen, ohne jegliche Benutzerinteraktion.

Zu 1.: Hatte ich schon vermutet, da ich bei den ersten Tests mehrere Laufwerke als Ergebnis zurückbekam (einschließlich virtueller).
Darum hab' ich das Ganze in eine Schleife gepackt, die mir auf den gefundenen Laufwerken nach einer Datei sucht, die auf jeden Fall da sein muss, damit die richtige CD/DVD gefunden wird und damit auch der richtige Pfad zurückgeliefert wird.

Ansonsten danke für die Info mit der IsReady-Eigenschaft, dies könnte evtl. ja das Script etwas entschlacken/beschleunigen...ich bin in VBScript leider nicht so bewandert...

mfg
Axel
ahe
ahe 13.09.2007 um 10:27:47 Uhr
Goto Top
Hallo maneich,

ich weiß zwar nicht, ob Du das meintest, aber es scheint auch zu funktionieren:

anstelle der Abfrage:
If objItem.MediaLoaded = vbTrue Then

habe ich die folgende Abfrage eingefügt:
If objItem.DriveIntegrity = vbTrue Then

Auzug aus der Kontext sensitiven Hilfe vom SystemScripter:
"Die 'DriveIntegrity' Eigenschaft gibt an, ob Dateien vom CD-ROM-Laufwerk einwandfrei gelesen werden können, indem ein Datenblock zweimal gelesen und die Ergebnisse miteinander verglichen werden."

IsReady habe ich als Eigenschaft nicht gefunden, kann es sein, dass ich dafür eine andere Klasse bemühen muss?

Aah, klar, ein bischen in der Online-Hilfe blättern UND lesen, dann findet man auch was...

Es gibt da noch GetDrive...

Mmh, allerdings komme ich auf die Schnelle da wohl nicht weiter, ich bekomme keine Ausgabe...
Set d = objFSO.GetDrive(drvpath)
d.DriveType = 4
If (d.IsReady) Then
	MsgBox "Laufwerk " & d.DriveLetter & "ist da!"  
Else
	MsgBox "Kein Laufwerk vorhanden"  
End If

So wie es aussieht muss ich erst den Parameter "drvpath" füllen, aber wie?

Am "frühen" Morgen etwas verwirrt, wende ich mich jetzt erst einmal meinem Kaffee zu...
Axel
ahe
ahe 13.09.2007 um 10:35:48 Uhr
Goto Top
Hallo Bastla,

die kurze Version funktioniert, jetzt brauche ich auch die dusselige Temp-Datei nicht mehr.

Durch maneichs Hinweis habe ich jetzt auch noch das VBScript etwas abgeändert, ob allerdings in seinem Sinne werde ich wohl noch erfahren face-smile

Mich stört noch ein wenig die Performance, wenn tatsächlich eine DVD im Laufwerk liegt...

mfg
Axel
bastla
bastla 13.09.2007 um 10:59:22 Uhr
Goto Top
Hallo ahe!

gibt es eigentlich eine Nacht für Dich? face-smile
Mal so, mal so - aber dieses Mal war es tatsächlich schon sehr spät, daher die eher oberflächliche Behandlung des Themas ...

Grüße
bastla
Biber
Biber 13.09.2007 um 11:39:03 Uhr
Goto Top
Moin ahe,

nach dem Morgenkaffee solltest Du noch mal das "d.DriveType = 4" (=versuchte Zuweisung)
in eine höfliche Frage "IF d.DriveType = 4 then..." ändern.

Grüße
Biber
ahe
ahe 13.09.2007 um 17:50:47 Uhr
Goto Top
Mmh, ja,... da hast Du wohl recht... face-smile

Allerdings löst es jetzt noch nicht mein Problem mit dem Parameter "drvpath", der muss ja noch irgendwie gefüllt sein, oder?

Ob ein Medium eingelegt ist kann man übrigens auch mit "objItem.MediaLoaded" herausbekommen.

Ein wenig forschen in der Online Hilfe unter "IsReady Property" brachte dann etwas Licht ins Dunkel...

Die Funktion ShowDriveInfo (s. u.) und etwas grübeln über der zweiten Tasse Kaffee brachte mich dann auf die Idee... face-smile
Function ShowDriveInfo(drvpath)
   Dim fso, d, s, t
   Set fso = CreateObject("Scripting.FileSystemObject")  
   Set d = fso.GetDrive(drvpath)
   Select Case d.DriveType
      Case 0: t = "Unknown"  
      Case 1: t = "Removable"  
      Case 2: t = "Fixed"  
      Case 3: t = "Network"  
      Case 4: t = "CD-ROM"  
      Case 5: t = "RAM Disk"  
   End Select
   s = "Drive " & d.DriveLetter & ": - " & t  
   If d.IsReady Then 
      s = s & "<BR>" & "Drive is Ready."  
   Else
      s = s & "<BR>" & "Drive is not Ready."  
   End If
   ShowDriveInfo = s
End Function

Dies ist die "neue" GetCDDriveLetter.vbs, allerdings noch mit diversem unnötigen Debugcode und ein paar doppelten Ausgaben...
On Error Resume Next
Dim objFSO, d
Dim objFile
Dim objFolder
Dim strDateiname
Dim strPFAD
Dim mysource

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

Set FSO = CreateObject("Scripting.FileSystemObject")   
Set Drives = FSO.Drives
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")  
strDateiname = WScript.ScriptFullName
Set objFolder = objFSO.getFolder(objFSO.getParentFolderName(strDateiname))
strDateiname = objFSO.getFileName(strDateiname)

Set colItems = objWMIService.ExecQuery("Select * from Win32_CDROMDrive")  

For Each objItem In colItems
	drv = ShowDriveInfo (objItem.Drive)                  '************** die geklaute Funktion wird aufgerufen **************   
	
	If objItem.DriveIntegrity = vbTrue Then
	'If objItem.MediaLoaded = vbTrue Then  
		If (objFSO.FileExists(objItem.Drive & "\historie.txt")) Then  
			mysource = objItem.Drive
                         ' **************  objItem.MediaLoaded zeigt "wahr" an, wenn eine CD eingelegt ist,   
                         ' **************  war reine Neugier...  
			MsgBox "Verzeichnis vorhanden und Datei vorhanden! " & mysource & "\historie.txt" & " " & objItem.MediaLoaded      
			WScript.echo mysource 
		End If
	End If
Next
If mysource = "" Then   
	MsgBox "DVD nicht da"   
Else
	MsgBox "DVD Laufwerk: " & mysource   
End If

Set Drives = Nothing
Set objFSO = Nothing
WScript.quit

Function ShowDriveInfo(drvpath)       ' **************  etwas abgeändert Funktion ShowDriveInfo  
	Dim fso, d, s, t
   	Set FSO = CreateObject("Scripting.FileSystemObject")  
   	Set d = FSO.GetDrive(drvpath)
   	Select Case d.DriveType
      	Case 0: t = "Unknown"  
      	Case 1: t = "Removable"  
      	Case 2: t = "Fixed"  
      	Case 3: t = "Network"  
      	Case 4: t = "CD-ROM"  
      	Case 5: t = "RAM Disk"  
   	End Select
   	s = d.DriveLetter 
   	If d.IsReady = vbTrue Then 
    	   MsgBox "drive: " & s & ":"  
   	End If
   	ShowDriveInfo = s
End Function

Es geht also auch mit "IsReady", wenn auch etwas aufwändiger, als gedacht...

mfg
Axel
Biber
Biber 13.09.2007, aktualisiert am 18.10.2012 um 18:32:26 Uhr
Goto Top
Moin ahe,

ein etwas später Nachtrag, aber der Vollständigkeit halber:
Habe es gerade per Zufall gesehen: hier im Forum sind auch schon ähnliche Lösungen gepostet...

RE #8: Installationspfad einer Anwendung suchen auf unbekanntem PC

Danke Dir fürs Veröffentlichen Deiner Lösung!.

Grüße
Biber