2014-08-29 56 views
0

這裏或那裏我找到了Cleanmgr.exeCcleaner掛起。當他們這樣做時,通常CPU使用率高達90%以上。這些掛起是間歇性的,很難再現,但是當它們掛起時,任務管理器已經報告說它們運行超過8個小時。幾秒鐘內99%的CPU使用率是典型的。如果運行時間過長,間歇性無法殺死進程

因此,我寫了一個小小的vbScript來運行這些應用程序,如果它需要很長時間,就殺了它 - 我想每個應用程序不超過3分鐘。僅供參考,從WinXp到8.1,我用完了,所以我真的只有vbScript和命令行。

第一次嘗試似乎成功了,但後來我發現我不得不應用第二次測試,再次用另一個計時器,但是,現在我發現當Cleanmgr或CCleaner掛起時,我的腳本根本不會退出。

這開始很簡單,現在它是堅果。我希望有人在這裏能幫助我。我認爲問題是,這個過程正在咀嚼我的CPU,所以定時器檢查我的腳本不能運行...

它發生在我身上,我從一個cmd文件使用cScript調用 - 可以那裏有一些問題?

有沒有辦法跟蹤處理時間,而不是從計時器?創建比進程更高優先級的線程,以便在掛起時可以終止?也許我的代碼有bug?請幫助,我瘋了。謝謝。

Option Explicit 
On Error Goto 0 

Dim wshShell, sysPath, waitTime, i, str, masterTimer, mElapsed, slp 
Dim apps(), paths(), params() 

Set wshShell=WScript.CreateObject("wScript.Shell") 
sysPath = wshShell.ExpandEnvironmentStrings("%SystemRoot%") 
waitTime = 90 
slp  = 2255 

ReDim apps(2) 
ReDim paths(2) 
ReDim params(2) 

apps(0) = "cleanmgr.exe" 
paths(0) = sysPath&"\System32" 
params(0) = "/SageRun:101" 
apps(1) = "ccleaner.exe" 
paths(1) = "C:\Program Files\ccleaner" 
params(1) = "/AUTO" 
apps(2) = "ccleaner64.exe" 
paths(2) = "C:\Program Files\ccleaner" 
params(2) = "/AUTO" 

For i=LBound(apps) to UBound(apps) 
str="cmd.exe /C taskkill.exe /im " & apps(i) & " /f /t" 
wshShell.run str 
str="cmd.exe /C taskkill.exe /im " & apps(i) & " /f" 
wshShell.run str 
str="cmd.exe /C tskill.exe "  & apps(i) & " /a /v" 
wshShell.run str 
WScript.Sleep slp 
    masterTimer = Timer 
    mElapsed = 0 
    RunCleaner paths(i),apps(i),params(i) 
str="cmd.exe /C taskkill.exe /im " & apps(i) & " /f /t" 
wshShell.run str 
str="cmd.exe /C taskkill.exe /im " & apps(i) & " /f" 
wshShell.run str 
str="cmd.exe /C tskill.exe "  & apps(i) & " /a /v" 
wshShell.run str 
Set Str=Nothing 
Wscript.sleep slp 
Next 

ReDim apps(0) 
ReDim paths(0) 
ReDim params(0) 
Erase apps 
Erase paths 
Erase params 

Set slp=Nothing 
Set sysPath=Nothing 
Set wshShell=Nothing 
Set waitTime=Nothing 

WScript.Quit(0) 

Public Sub RunCleaner(strPath, prog, args) 
Dim objFSO, objWMIService, objProcess, objStartup, objConfig, colMonitoredProcesses, objLatestProcess 
Dim intProcessID, erReturn, processes, proc 
Dim fullPath, elapsed, startTime, running 

Set objFSO=CreateObject("Scripting.FileSystemObject") 
fullPath = "" & strpath & "\" & prog 

If objFSO.FileExists(fullPath) Then 
    Set objWMIService= GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") 
    Set objProcess = GetObject("winmgmts:root\cimv2:Win32_Process") 
    Set objStartup = objWMIService.Get("Win32_ProcessStartup") 
    Set objConfig = objStartup.SpawnInstance_ 
    objConfig.ShowWindow = 1 
    elapsed = -1 * slp 
    startTime = Timer 
    Wscript.sleep slp 
    erReturn = objProcess.Create (fullPath & " " & args, Null, objConfig, intProcessID) 
    Set colMonitoredProcesses = objWMIService. _   
           ExecNotificationQuery("select * From __InstanceDeletionEvent " _ 
           & " within 1 where TargetInstance isa 'Win32_Process'") 

    Do While ((elapsed < waitTime) And ((mElapsed) < waitTime)) 
    Set objLatestProcess = colMonitoredProcesses.NextEvent 
    If objLatestProcess.TargetInstance.ProcessID = intProcessID Then 
    Exit Do 
    End If 
    elapsed = Timer - startTime 
    mElapsed = Timer - masterTimer 
    Loop 

    WScript.sleep slp 
    running = True 

    Do While ((running) And (elapsed < waitTime) And (mElapsed < waitTime)) 
    SET processes = GetObject("winmgmts:") 
    running = False 
    elapsed = (Timer - startTime)/2 
    For Each proc in processes.InstancesOf("Win32_Process") 
    If (StrComp(LCase(proc.Name), LCase(prog), vbTextCompare) = 0) Then 
    running = True 
    Exit For 
    End If 
    Next 
    Set processes=Nothing 
    mElapsed = (Timer - masterTimer)/2 
    Loop 

    WScript.sleep slp 
    fullPath = "cmd.exe /C taskkill.exe /im " & prog & " /f /t" 
    wshShell.run fullPath 
    fullPath = "cmd.exe /C taskkill.exe /im " & prog & " /f" 
    wshShell.run fullPath 
    fullPath = "cmd.exe /C tskill.exe "  & prog & " /a /v" 
    wshShell.run fullPath 

    Set objWMIService=Nothing 
    Set objProcess=Nothing 
    Set objStartup=Nothing 
    Set objConfig=Nothing 
    Set objProcess=Nothing 
    Set erReturn=Nothing 
    Set intProcessID=Nothing 
    Set colMonitoredProcesses=Nothing 
    Set elapsed=Nothing 
    Set startTime=Nothing 
    Set objLatestProcess=Nothing 
    Set running=Nothing-1 * slp 
    Set proc=Nothing 
    Set fullPath=Nothing 
End If 
Set objFSO=Nothing 
End Sub 
+0

如果您有Windows 8.1 PowerShell也是一個選項,因爲它自7以來本地安裝。 – Matt 2014-08-30 01:09:12

+0

謝謝馬特...我正在考慮PowerShell。批量和vbs總是似乎是越野車。這和似乎Msft正在將所有人都移動到Ps.Maybe我應該詢問有關檢測掛起的應用程序 – 2014-08-30 17:40:01

回答

0

你的腳本看起來有點複雜,它需要做什麼。嘗試一下。

exes被連續執行。如果任何運行時間超過3分鐘,則通過任務殺傷終止。如果你想完全消除WMI查詢(這可能是你的腳本不得不爲CPU爭奪的地方),你可以簡單地等待三分鐘,然後發送一個taskkill,而不檢查它是否仍在運行。您也可以執行任務列表而不是WMI查詢。

Dim fso, shl, wmi 
Set fso = CreateObject("Scripting.FileSystemObject") 
Set shl = CreateObject("WScript.Shell") 
Set wmi = GetObject("winmgmts:\\.\root\cimv2") 

Dim app1, app2, app3, apps() 
ReDim apps(-1) 
app1 = fso.BuildPath(shl.ExpandEnvironmentStrings("%SYSTEMROOT%"), "System32\cleanmgr.exe") 
app2 = "C:\Program Files\ccleaner\ccleaner.exe" 
app3 = "C:\Program Files\ccleaner\ccleaner64.exe" 
If fso.FileExists(app1) Then AddApp app1, "/SageRun:101" 
If fso.FileExists(app2) Then AddApp app2, "/AUTO" 
If fso.FileExists(app3) Then AddApp app3, "/AUTO" 
If UBound(apps) < 0 Then WScript.Quit ' None of the programs exist 

Dim apptorun, starttime, running, process 
For Each apptorun In apps 
    starttime = Now 
    process = fso.GetFile(apptorun.exe).Name 
    shl.Run apptorun.exe & " " & apptorun.param, 0, False 
    Do While 1 
     WScript.Sleep 5000 
     Set running = wmi.ExecQuery("select * from win32_process where name = """ & process & """") 
     If running.Count = 0 Then Exit Do 
     If DateDiff("n", starttime, Now) > 3 Then 
      shl.Run "taskkill /f /im " & process, 0, True 
      Exit Do 
     End If 
    Loop 
Next 


Sub AddApp(app, arg) 
    ReDim Preserve apps(UBound(apps) + 1) 
    Set apps(UBound(apps)) = New program 
    apps(UBound(apps)).exe = app 
    apps(UBound(apps)).param = arg 
End Sub 

Class program 
    Dim exe, param 
End Class 
+0

謝謝,是的,我知道對不對?它只是爆炸,因爲我試圖越來越多地殺死它...所以我想我應該發佈。我會試試看看它是如何發展的。再次感謝歐洲 – 2014-08-31 15:21:49

+0

良好的交易和謝謝 - 最後抓住每個人掛 - 一次使用0%的CPU使用率和99%的使用率 - 殺了它,繼續:)再次感謝 – 2014-09-01 18:13:59