knuefi
Goto Top

Per VBS Prog. beenden wenn Ordner leer

Hallo zusammen,

ich habe ein Script das zwei Ordner überwacht und bei Eingang einer Datei ein Programm startet., das läuft soweit perfekt. Nun soll das Script noch erweitert werden. Nachdem die überwachten Ordner wieder leer sind, soll das Programm (das Script soll weiter laufen) wieder beendet werden und eine Meldung (Msgbox) "wieder Leer...." soll erscheinen. Ist das möglich, kann mir jemand helfen?.
'  
Const strPath = "C:\Users\Max\Desktop\Test1"  

Const strPath2 = "C:\Users\Max\Desktop\Test2"  

Const intInterval = "2"  
'------------------------------  
strDrive = Split(strPath,"\")(0)  
strFolder = Replace(Split(strPath,":")(1),"\","\\") & "\\"  

strDrive2 = Split(strPath2,"\")(0)  
strFolder2 = Replace(Split(strPath2,":")(1),"\","\\") & "\\"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objShell = CreateObject("Wscript.Shell")  
Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )  

strQuery = "Select * From __InstanceOperationEvent" _  
    & " Within " & intInterval _  
    & " Where Targetinstance Isa 'CIM_DataFile'" _  
    & " And ((TargetInstance.Drive='" & strDrive & "'"_  
    & " And TargetInstance.Path='" & strFolder & "') or "_  
    & "(TargetInstance.Drive='" & strDrive2 & "'"_  
    & " And TargetInstance.Path='" & strFolder2 & "'))"  
Set colEvents = objWMIService.ExecNotificationQuery (strQuery) 

Do 
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance
    
    Select Case objEvent.Path_.Class 
        Case "__InstanceCreationEvent"  
            objShell.Run """C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"""  
    End Select 
Loop

Gruß und Danke in voraus

Content-Key: 305140

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

Printed on: April 19, 2024 at 18:04 o'clock

Mitglied: 129413
129413 May 22, 2016 updated at 16:42:05 (UTC)
Goto Top
if fso.GetFolder(strPath).Files.Count = 0 then
Set ProcessList = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'AcroRd32.exe'")  
For Each objProcess In ProcessList
    objProcess.Terminate
Next
Msgbox "Ordner leer"  
End if
Gruß skybird
Member: Knuefi
Knuefi May 22, 2016 at 16:15:22 (UTC)
Goto Top
Hallo skybird,
erstmal Danke für deine schnelle Antwort. Wenn ich das richtig verstehe, ist das ein separates Script oder?. Kann ich es in den vorhandenen Sript einbinden?
Mitglied: 129413
129413 May 22, 2016 updated at 16:18:41 (UTC)
Goto Top
Zitat von @Knuefi:

Hallo skybird,
erstmal Danke für deine schnelle Antwort. Wenn ich das richtig verstehe, ist das ein separates Script oder?.
öhm nö, les mal Zeile 1, wo hätte ich sonst die Variablen strPath und fso her ???
Kann ich es in den vorhandenen Sript einbinden?
Ja
Member: Knuefi
Knuefi May 22, 2016 at 16:40:19 (UTC)
Goto Top
ich kriege es leider nicht hin bzw. verstehe es nicht, ich bekomme die Fehlermeldung.

'  
Const strPath = "C:\Users\Max\Desktop\Test1"  

Const strPath2 = "C:\Users\Max\Desktop\Test2"  

Const intInterval = "2"  
'------------------------------  
strDrive = Split(strPath,"\")(0)  
strFolder = Replace(Split(strPath,":")(1),"\","\\") & "\\"  

strDrive2 = Split(strPath2,"\")(0)  
strFolder2 = Replace(Split(strPath2,":")(1),"\","\\") & "\\"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objShell = CreateObject("Wscript.Shell")  
Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )  

strQuery = "Select * From __InstanceOperationEvent" _  
    & " Within " & intInterval _  
    & " Where Targetinstance Isa 'CIM_DataFile'" _  
    & " And ((TargetInstance.Drive='" & strDrive & "'"_  
    & " And TargetInstance.Path='" & strFolder & "') or "_  
    & "(TargetInstance.Drive='" & strDrive2 & "'"_  
    & " And TargetInstance.Path='" & strFolder2 & "'))"  
Set colEvents = objWMIService.ExecNotificationQuery (strQuery) 

Do 
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance
    
    Select Case objEvent.Path_.Class 
        Case "__InstanceCreationEvent"  
            objShell.Run """C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"""  
    End Select
loop
if fso.GetFolder(strPath).Files.Count = 0 then
Set ProcessList = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'AcroRd32.exe'")  
For Each objProcess In ProcessList
    objProcess.Terminate
Next objProcess
Msgbox "Ordner leer"  
End if
unbenannt
Mitglied: 129413
129413 May 22, 2016 updated at 16:47:49 (UTC)
Goto Top
Uups da war ich noch im VBA Modus, das objProcess in der Next-Zeile darf da nicht stehen.

Aber die Platzierung des Codes solltest du dir noch mal ansehen face-big-smile der wird sonst so an der Stelle nie ausgeführt, außer du springst aus dem Loop.

Ich frage mich ernsthaft ob du diesen Code wirklich selber geschrieben hast ?? Wenn du so hilflos daher kommst.

Wenn ich schon Code irgendwo her kopiere klatsche ich zumindest eine Quellenangabe dran!! Deswegen poste ich auch meist keinen fremden Code.
Etwas Hirn einschalten sollte man in einem Admin-Forum eigentlich voraussetzen können face-sad
Member: Knuefi
Knuefi May 22, 2016 at 17:04:25 (UTC)
Goto Top
Es wird leider das Programm nicht beendet.face-sad
'  
Const strPath = "C:\Users\Max\Desktop\Test1"  

Const strPath2 = "C:\Users\Max\Desktop\Test2"  

Const intInterval = "2"  
'------------------------------  
strDrive = Split(strPath,"\")(0)  
strFolder = Replace(Split(strPath,":")(1),"\","\\") & "\\"  

strDrive2 = Split(strPath2,"\")(0)  
strFolder2 = Replace(Split(strPath2,":")(1),"\","\\") & "\\"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objShell = CreateObject("Wscript.Shell")  
Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )  

strQuery = "Select * From __InstanceOperationEvent" _  
    & " Within " & intInterval _  
    & " Where Targetinstance Isa 'CIM_DataFile'" _  
    & " And ((TargetInstance.Drive='" & strDrive & "'"_  
    & " And TargetInstance.Path='" & strFolder & "') or "_  
    & "(TargetInstance.Drive='" & strDrive2 & "'"_  
    & " And TargetInstance.Path='" & strFolder2 & "'))"  
Set colEvents = objWMIService.ExecNotificationQuery (strQuery) 

Do 
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance
    
    Select Case objEvent.Path_.Class 
        Case "__InstanceCreationEvent"  
            objShell.Run """C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"""  

if fso.GetFolder(strPath).Files.Count = 0 then
Set ProcessList = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'AcroRd32.exe'")  
For Each objProcess In ProcessList
    objProcess.Terminate
Next objProcess
Msgbox "Ordner leer"  
End if
    End Select 
Loop
Mitglied: 129413
129413 May 22, 2016 updated at 17:15:53 (UTC)
Goto Top
Was ja auch klar ist wenn du das ganze in das Switch-Statement mit Case "__InstanceCreationEvent" einfügst. Denn dann wird es ja nur ausgeführt wenn eine Datei im Ordner angelegt wird! Und dann kann das IF-Ergebnis ja auch nicht positiv sein da ja Dateien im Ordner sind. Du musst also schon was mit diesen neuen Dateien tun (verschieben/löschen) damit der Ordner leer wird.
Du startest nur den Acrobat und tust sonst nichts ??? Wie soll der Ordner davon dann leer werden ??

Mir scheint du verstehst dein eigenes Skript überhaupt nicht ????

Das Skript überwacht ja Ordner auf neue Dateien und blockiert dementsprechend so lange den Loop bis neue Dateien im Ordner sind.

Ich bin hier raus.Nur Code kopieren macht noch keinen Programmierer... Für Grundlagen gibt es Bücher.

Ciao skybird
Member: Knuefi
Knuefi May 22, 2016 at 17:28:08 (UTC)
Goto Top
Der Adobe Reader sollte wieder beendet werden nachdem der Ordner wieder leer ist, wie schon geschrieben, egal wie er geleert wird, ob verschieben oder löschen.


Zitat von @129413:
Das Skript überwacht ja Ordner auf neue Dateien und blockiert dementsprechend so lange den Loop bis neue Dateien im Ordner sind.

Deshalb meine Frage ganz am Anfang, "ist es möglich?". Ich hatte schon die Befürchtung das es ein Widerspruch ist.


Zitat von @129413:

Ich bin hier raus.Nur Code kopieren macht noch keinen Programmierer... Für Grundlagen gibt es Bücher.

Ciao skybird

Trotzdem Danke für den Versuch mir zu helfen
Mitglied: 129413
129413 May 22, 2016 updated at 18:04:42 (UTC)
Goto Top
__InstanceDeletionEvent
https://github.com/Invoke-IR/Uproot/wiki/WMI-Event-Subscriptions

Dann sollte es nun endgültig Klick machen.

BTW. Schau mal hier:
PDF via Powershell drucken - Reader nach druck schließen
Member: Knuefi
Knuefi May 22, 2016 at 18:40:16 (UTC)
Goto Top
Irgendwie habe ich es nicht hinbekommen, deshalb werde ich es mit einen anderen zusätzlichen Script versuchen. Dieses wird vom Überwachungsscript mit gestartet. Also bei Eingang startet nicht nur das Programm, sonder zusätzlich ein weiteres Script. Das Script überwacht wiederum die Ordner und beendet, wenn Ordnerleer, das Programm. Ich kann mir gut vorstellen das dein Weg Sinnvoll ist, aber leider bekomme ich es nicht hin.
Member: Knuefi
Knuefi May 22, 2016 updated at 19:12:56 (UTC)
Goto Top
Ich werde oder bin verrückt, selbst über ein separates Script wird das Programm bei leeren Ordner nicht beendet.
Member: Knuefi
Knuefi May 22, 2016 at 19:37:42 (UTC)
Goto Top
Ich bin zu dumm und drehe mich im Kreis. Kann mir bitte jemand ein Script schreiben, dass einen Ordner überwacht und ein laufendes Programm beendet, wenn der Ordner leer ist. Zudem wäre eine Meldung ganz hilfreich.
Member: Knuefi
Knuefi May 23, 2016 at 15:38:50 (UTC)
Goto Top
kann mir keiner weiterhelfen?, schade
Member: Knuefi
Knuefi May 23, 2016 at 18:22:27 (UTC)
Goto Top
Nun habe ich folgendes zusammen gebastelt, leider ohne Erfolg. Das Programm wird beendet und die Meldung kommt nur wenn Datei in den Ordner eingefügt wird. Gewünscht ist aber das die Meldung und das Programm beendet kommt/wird wenn die Ordner leer sind.
Wo liegt der Fehler?
Const strPath = "C:\Users\Max\Desktop\test1"  

Const strPath2 = "C:\Users\Max\Desktop\test2"  

Const intInterval = "2"  

strDrive = Split(strPath,"\")(0)  
strFolder = Replace(Split(strPath,":")(1),"\","\\") & "\\"  

strDrive2 = Split(strPath2,"\")(0)  
strFolder2 = Replace(Split(strPath2,":")(1),"\","\\") & "\\"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objShell = CreateObject("Wscript.Shell")  
Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )  

strQuery = "Select * From __InstanceOperationEvent" _  
    & " Within " & intInterval _  
    & " Where Targetinstance Isa 'CIM_DataFile'" _  
    & " And ((TargetInstance.Drive='" & strDrive & "'"_  
    & " And TargetInstance.Path='" & strFolder & "') or "_  
    & "(TargetInstance.Drive='" & strDrive2 & "'"_  
    & " And TargetInstance.Path='" & strFolder2 & "'))"  
Set colEvents = objWMIService.ExecNotificationQuery (strQuery) 

Do 
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance
    
    Select Case objEvent.Path_.Class 
        Case "__InstanceCreationEvent"  

if fso.GetFolder(strPath).Files.Count = 0 then
Set ProcessList = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'FileJuggler.exe'")  
For Each objProcess In ProcessList
    objProcess.Terminate
Next
Msgbox "beide Ordner leer"  
End if
End Select
loop
Mitglied: 129413
Solution 129413 May 23, 2016 updated at 18:59:37 (UTC)
Goto Top
Siehe letztes Kommentar, falsches Event!!
Case "__InstanceCreationEvent" feuert nur wenn neue Dateien im Ordner erstellt werden. Also __InstanceDeletionEvent hinzufügen.

Const strPath = "C:\Users\Max\Desktop\test1"   
Const strPath2 = "C:\Users\Max\Desktop\test2"   

Const intInterval = 2

strDrive = Split(strPath,"\")(0)  
strFolder = Replace(Split(strPath,":")(1),"\","\\") & "\\"  

strDrive2 = Split(strPath2,"\")(0)  
strFolder2 = Replace(Split(strPath2,":")(1),"\","\\") & "\\"  

Set fso = WScript.CreateObject("Scripting.Filesystemobject")  
Set objShell = CreateObject("Wscript.Shell")  
Set objWMIService = GetObject( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )  

strQuery = "Select * From __InstanceOperationEvent" _  
    & " Within " & intInterval _  
    & " Where Targetinstance Isa 'CIM_DataFile'" _  
    & " And ((TargetInstance.Drive='" & strDrive & "'"_  
    & " And TargetInstance.Path='" & strFolder & "') or "_  
    & "(TargetInstance.Drive='" & strDrive2 & "'"_  
    & " And TargetInstance.Path='" & strFolder2 & "'))"  
Set colEvents = objWMIService.ExecNotificationQuery (strQuery) 

Do 
    Set objEvent = colEvents.NextEvent()
    Set objTargetInst = objEvent.TargetInstance
    
    Select Case objEvent.Path_.Class 
        Case "__InstanceCreationEvent"	'Event wenn eine neue Datei im Ordner erstellt wird  
			' Testweise Taschenrechner starten  
			objShell.Run "calc.exe"  
			
		Case "__InstanceDeletionEvent"	'Event tritt auf wenn eine Datei aus einem Ordner entfernt oder verschoben wird  
			' Wenn beide Ordner leer sind:  
			if fso.GetFolder(strPath).Files.Count = 0 And fso.GetFolder(strPath2).Files.Count = 0 then
				'Suche den Prozess und beende ihn (Demo: Alle Taschenrechner werden beendet)  
				Set ProcessList = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2").ExecQuery("SELECT * FROM Win32_Process WHERE Name = 'calc.exe'")  
				For Each objProcess In ProcessList
				    objProcess.Terminate
				Next
				' Nur eine Meldung ausgeben wenn mindestens eine Instanz des Programms beendet wurde  
				If ProcessList.Count > 0 Then
					Msgbox "Beide Ordner leer, Programm wurde beendet."  
				End If
			End if

	End Select
loop
Mitglied: 129413
Solution 129413 May 25, 2016 updated at 12:15:48 (UTC)
Goto Top
Wat nu ? , s.o. ...
Member: Knuefi
Knuefi May 25, 2016 at 20:54:48 (UTC)
Goto Top
Hallo skybird,

soorryyyy konnte es nicht früher testen. Es ist perfekt!!!, vor allem deine Erklärungen dazu.
So habe ich es auch Verstanden, dadurch ist für mich der Fehler in dem vorigen Script erkennbar.
DANKE und Gruß