maksyuli
Goto Top

PIDs von VBScript gestarteten Prozessen herausfinden

Hallo Script Master,

ich habe folgende interessante Fragestellung über die ich schon zwei Tage lang meinen Kopf zerbreche und dies fängt langsam an zu schmerzen;)
Ich habe ein Batch file der mir ein VBScript startet. Der Batch beschäftigt sich mit seiner Sachen weiter und das VBscript zeigt inzwischen einen Statusbar in form Einer HTML Saite an, so dass der User weiß, dass da was abläuft (der Batch). Tja, nachdem der Batch fertig ist sollte dieses HTML Fenster abgeschossen werden. Bevor es aber Tod umfällt sollte man bedenken dass nicht nur es sondern auch einen weiteren wscript.exe Prozess vom VBScript gestartat wird. Ich weiß eigentlich nicht wieso diesen weiteren Prozess gestartet wurde aber man braucht ihn anscheinend um das HTML Fenster zu aktivieren. Dies geschieht mit diesen Zeilen vermute ich:

Set objWshShell = WScript.CreateObject("WScript.Shell")
objWshShell.AppActivate("Microsoft Internet Explorer")

das volle Script kann unter
http://cwashington.netreach.net/depo/view.asp?Index=796
gesehen werden nur dass ich die schleife unendlich gemacht habe anstatt bis 1000 zu zählen.

Mein Prozessor ist verrückt nach diesen Prozess (wscript.exe) und läuft die ganze Zeit wie verliebter Hund mit 45-50 Belastung wenn er gestartet ist.
Tja, das heißt natürlich dass ich auch den abschießen müsste, so dass sich der Prozessor bisschen beruhigt und sich auch mit anderen Sachen beschäftigt. Ich suche schon die ganze Zeit nach einer Möglichkeit die PID von genau diesen Prozessen herauszufinden so dass nicht einfach wahllos in die Menge von IE-s und wscript.exe-s schieße. Anscheinend hat der VBScript an sich kein PID weil er einfach eine ausführbare Datei ist aber er startet die oben beschriebenen zwei Prozesse. Diese zwei PIDs sollte ich herausfinden und die Stoppen wie mache ich das? Any suggestions?

Content-Key: 93673

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

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

Member: bastla
bastla Aug 05, 2008 at 13:08:35 (UTC)
Goto Top
Hallo maksyuli und willkommen im Forum!

Um mehrere "wscript"-Prozesse zu unterscheiden, könntest Du per WMI die "CommandLine"-Eigenschaft abfragen (im Beispiel gleich durch "WHERE" eingeschränkt auf Ergebnisse mit enthaltenem "wscript.exe"):
strComputer = "."   
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")   
Set colItems = objWMIService.ExecQuery( _
    "SELECT * FROM Win32_Process WHERE CommandLine LIKE '%wscript.exe%'")   
For Each objItem in colItems 
    WScript.Echo "CommandLine: " & objItem.CommandLine  
Next
Grüße
bastla
Member: maksyuli
maksyuli Aug 05, 2008 at 15:54:57 (UTC)
Goto Top
Bastlaaaaaaa ist der Beste,

unglaublich es hat funktioniert. Doch es hat sich herausgestellt, dass ich das eigentlich gar nicht bräuchte, denn wenn ich die blöde Schleife nicht nur unendlich mache sondern ganz raushaue taucht dieses wscript.exe Prozess gar nicht auf, sondern es kommt nur das IE Fenster hoch. Das ist eigentlich alles was ich bräuchte, nur etwas was sich hin und her schleust damit dem User nicht langweilig ist während der Batch arbeitet. Dann wird auch seine Maschine nicht belastet. Trotzdem für die die sich interessieren hier den vollen Code:

‘ Killbill_vol1.vbs
strComputer = "."  
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2")  
Set colItems = objWMIService.ExecQuery( _
"SELECT * FROM Win32_Process WHERE CommandLine LIKE '%wscript.exe%'")  
For Each objItem in colItems  
stringText = objItem.CommandLine
'statusbar.vbs is used like an identifier for the exact prozess to terminate  
n = InStr(stringText, "Statusbar.vbs")  
if (n > 0) Then
objItem.Terminate
end if
Next

Und jetzt bleibet eigentlich die schwierigere Aufgabe genau ein IE von mehrere IE-s abzuknallen.

Das Resultat von den obigen code wenn mehrere IE Fenster geöffnet sind

"SELECT * FROM Win32_Process WHERE CommandLine LIKE '%IEXPLORE.exe%'"  

lautet

CommandLine: "C:\Program Files\Internet Explorer\IEXPLORE.EXE"   
CommandLine: "C:\Program Files\Internet Explorer\IEXPLORE.EXE"   
CommandLine: "C:\Program Files\Internet Explorer\IEXPLORE.EXE"  

Nutzt leider nichts.

Das einzige was ich bis jetzt gefunden habe und bei mir Funktioniert lautet folgender mase:

for /f "delims=, tokens=2" %%i in ('tasklist /FO csv /FI "\blala\Statusbar.vbs"') do Set PID=%%~i  
taskkill /PID %PID% /T /F

das Problem hier ist, dass es zwar funktioniert aber nicht sauber genug ist. Es sollte nicht einfach das letzte was geöffnet wurde wieder geschlossen werden. Falls was schief geht könnte das falsche Fenster erwischt werden. Dieser Code ist mir nicht eindeutig genug. Was könnte man da machen?
I really appreciate your help guys!
Member: maksyuli
maksyuli Aug 05, 2008 at 16:08:07 (UTC)
Goto Top
Member: bastla
bastla Aug 05, 2008 at 20:44:25 (UTC)
Goto Top
Hallo makayuli!

Für etwas mehr Sicherheit könntest Du zwar mit dem Property "CreationDate" (der selben WMI-Abfrage wie oben, also mit "objItem.CreationDate") sorgen, indem Du die Zeit beim Erstellen des IE-Objektes mit allen Zeitwerten der "IEXPLORE.EXE"-Prozesse vergleichst, aber auch das wäre nur ein Workaround.

Zum Thema "WMI / Win32_Process" kannst Du dich ja selbst hier umsehen, vielleicht findest Du noch eine andere Möglichkeit ...
Eigentlich müsste sich aber das aufrufende Script selbst um das Beenden des IE-Prozesses kümmern (im von Dir verlinkten Originalscript durch "objIE.Quit" in der Function "CloseIE()") - daraus würde folgen, dass das Script auf das Ende des Batches warten müsste - entweder durch ein "True" als drittes Argument ("bWaitOnReturn") der "Run"-Methode, oder, indem etwa der Batch beim Beenden eine Datei erzeugt (oder löscht), deren Vorhandensein das Script abfragen kann - an passender Stelle im weiteren Ablauf oder etwa in einer Warteschleife mit zB 20 Sekunden-Abständen (mit "WScript.Sleep" erzeugt), um die Belastung etwas zu senken.
[Edit] Noch ein Nachtrag: Falls Du voraussetzen kannst, dass "Word" (ja, "Microsoft Office Word" face-wink) verfügbar ist: http://www.microsoft.com/technet/scriptcenter/resources/qanda/nov05/hey ... [/Edit]

Grüße
bastla
Member: maksyuli
maksyuli Aug 06, 2008 at 13:50:04 (UTC)
Goto Top
WMI / Win32_Process Ja, da habe isch schon gesucht und nichts Passendes gefunden.

Sonnst Creation Date ist auch so eine Sache die nicht so putzig ist.

Weiter geht es mit MS Word aber da das Programm auf einen Server laufen wird ist es auch nichts. Aber doch sehr interessante Möglichkeit muss ich sagen.

Das mit dem Dritten Argument habe ich nicht so verstanden. Wenn ich den Statusbar per Batch aufrufe, da muss ich ja schon die Parameter übergeben aber wie übergebe ich einen Weiteren Parameter zu einem späteren Zeitpunkt wenn der Batch zu ende gekommen ist. Hmmm?

Aber die Idee mit der Datei war natürlich klasse also habe ich es genau so gemacht wie du mir vorgeschrieben hast. Der Prozessor kriegt den Prozess alle 5 sec. zu sehen also kann er ganze 4 Sekunden was anderes machen. Und die dummy datei wird nach gebrauch wieder gelöscht.

Vielen vielen Dank Bastla!
Member: bastla
bastla Aug 06, 2008 at 14:20:22 (UTC)
Goto Top
Hallo maksyuli!

Das mit dem Dritten Argument habe ich nicht so verstanden. Wenn ich den Statusbar per Batch aufrufe, da muss ich ja schon die Parameter übergeben aber wie übergebe ich einen Weiteren Parameter zu einem späteren Zeitpunkt wenn der Batch zu ende gekommen ist. Hmmm?
Gemeint war, dass das Script auf das Ende des Batches warten müsste (was beim Aufruf über Run eben mit dem 3. Argument angegeben wird) und danach das "objIE.Close" ausführen könnte - aber da ich die Zusammenhänge zwischen Deinen jeweiligen Aufrufen nicht kenne, war das eine eher allgemeine Überlegung ...

Ansonsten freut's mich natürlich, dass Du eine akzeptable Lösung gefunden hast. face-smile

Grüße
bastla
Member: maksyuli
maksyuli Aug 18, 2008 at 15:09:44 (UTC)
Goto Top
Aaaha, jetzt habe isch verstanden wie du das meinsch.
But in my concept it actually works the other way around. Nicht das VBScript ruft den Batch sondern, ich starte das VBScript vom Batch. Deswegen würde hier die Möglichkeit mit dem Run die Sachen verkomplizieren.
Also die Leser würden natürlich gerne Code sehen deswegen hier die Solution:

1) Ich starte ein VBScript der mir einen Status bar darstellt und auf ready.txt jede sekunde prüft
2) Batch läuft weiter und tut was er tun muss
3) Batch kommt zu ende und kreiert ready.txt

@REM Ready file is required to signalize that the batch is completed and the statusbar can be closed
ready >> %READYFILE% 2>NUL

3) VBScript freut sich drauf weil es aus der „unendlichen“ warte Schleife rausgehen kann, sich schließen kann, und dabei den ready.txt mit auf die Fahrt ins Nirwana nehmen darf.

batchStillRunning=true
Do
If objFSObject.FileExists(readyFilePath) Then
	 batchStillRunning = False
result = DeleteFile(readyFilePath)
Else 
  WScript.Sleep(1000)
End If
Loop While batchStillRunning = True


Private Function DeleteFile(filePath)
Dim objFSO

set objFSO = CreateObject("Scripting.FileSystemObject")  
If objFSO.FileExists(filePath) Then
	On Error Resume Next 
	objFSO.DeleteFile(filePath)
	If Err.Number <> 0 Then 
	  Set objFSO = Nothing
	  DeleteFile = Err.Number : Exit Function
	End If  
    On Error Goto 0
End If   
Set objFSO = Nothing
DeleteFile=0 'return 0 if no problems accrued  
End Function