我是一個新的VB腳本程序員,嘗試使用VB腳本通過默認程序(本例中爲Adobe Reader X)打開PDF文件,並將其另存爲文本文件。如何等待應用程序在VBScript中啓動?
我打開PDF的當前腳本,等待1秒鐘,然後將其另存爲文本。但是,對於速度較慢的計算機,PDF可能需要超過1秒才能加載。有沒有人知道如何做一個睡眠循環,直到文件打開或狀態準備就緒?
我是一個新的VB腳本程序員,嘗試使用VB腳本通過默認程序(本例中爲Adobe Reader X)打開PDF文件,並將其另存爲文本文件。如何等待應用程序在VBScript中啓動?
我打開PDF的當前腳本,等待1秒鐘,然後將其另存爲文本。但是,對於速度較慢的計算機,PDF可能需要超過1秒才能加載。有沒有人知道如何做一個睡眠循環,直到文件打開或狀態準備就緒?
首先,因爲您是初學者,請務必使用Option Explicit
。許多錯誤是由變量名稱中的拼寫錯誤引起的,如果您強制自己聲明您使用的所有變量,則會捕獲它們。
其次,您不需要創建兩個WScript.Shell
對象,只需重新使用現有的對象即可。
第三,您需要激活要發送命令的應用程序。這就是Shell對象的AppActivate
method的用途。它返回True
或False
,指示是否將有問題的應用程序放到前臺運行或不運行。你可以在循環中使用它(While Not Shell.AppActivate("Adobe Reader") ...
),只要應用程序需要就等待。
然而,缺點是您需要知道應用程序窗口(或其進程ID)的確切標題才能使用。應用程序標題可能會在沒有警告的情況下更改,所以這是不穩定的。 PID很健壯,但不可猜測。
最後,您需要WMI的幫助列出所有進程,獲取正確的PID,然後將其傳遞給AppActivate
。 Win32_Process
class就是爲此而製作的。
Dim Shell, WMI, pid
Set Shell = WScript.CreateObject("WScript.Shell")
Set WMI = GetObject("winmgmts:!\\.\root\cimv2")
Shell.Run "start ""C:\Temp\Gasprices.pdf"""
pid = WaitForProcess("AcroRd32.exe", 5)
If pid > 0 Then
Shell.AppActivate pid
Shell.SendKeys "%FAX%S"
Else
WScript.Echo "Could not talk to PDF reader"
WScript.Quit 1
End If
Function WaitForProcess(imageName, tries)
Dim wql, process
wql = "SELECT ProcessId FROM Win32_Process WHERE Name = '" & imageName & "'"
WaitForProcess = 0
While tries > 0 And WaitForProcess = 0
For Each process In WMI.ExecQuery(wql)
WaitForProcess = process.ProcessId
Next
If WaitForProcess = 0 Then
WScript.Sleep 1000
tries = tries - 1
End If
Wend
End Function
注意,分配給函數名(如WaitForProcess = 0
)設置返回值。
您可以通過finding the script's own PID優化這和WaitForProcess()
查詢
"SELECT ProcessId FROM Win32_Process WHERE ParentProcessId = '" & scriptPID & "'"
。
另一個可能的選擇是,以測試工藝CPU使用率...
您將需要測試,看看這是否在您的環境...
Dim oShell, oExec, PID, X, Z
Set oShell = CreateObject("WScript.Shell")
Set oExec = oShell.Exec(Chr(34) & "C:\ADOBE PATH" & Chr(34) & " " & Chr(34) & "C:\YOUR PDF PATH.pdf" & Chr(34))
PID = oExec.ProcessID
WScript.Echo PID
'Prevent an Endless Loop
Z = 600 'about one minute worse case
Do
WScript.Sleep 100
X = GetCPUUsage(PID)
WScript.Echo X
Z = Z - 1
If oExec.Status <> 0 Then
MsgBox "The Process has been Terminated. Ending Script"
WScript.Quit
End If
Loop Until X = 0 Or Z = 0
If Z > 0 Then
WScript.Echo "Process Is More Or Less Opened"
Else
WScript.Echo "Process is open... Maybe?"
End If
Function GetCPUUsage(ProcID)
Dim objWMIService, colItems, objItem
Const wbemFlagReturnImmediately = &h10
Const wbemFlagForwardOnly = &h20
'Just in case
GetCPUUsage = 0
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT PercentProcessorTime FROM Win32_PerfFormattedData_PerfProc_Process WHERE IDProcess = '" & ProcID & "'", _
"WQL", wbemFlagReturnImmediately + wbemFlagForwardOnly)
For Each objItem In colItems
GetCPUUsage = objItem.PercentProcessorTime
Next
End Function
非常感謝你,我正在學習你的代碼! – aqpham1
謝謝你讓我玩與您的代碼響應! – aqpham1