windows 如何检查windows中的vbs脚本是否正在运行?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7849699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to check vbs script in windows is running or not?
提问by shanmugamgsn
I have created a VBS script in Windows. I will run this script to get size of a file.
我在 Windows 中创建了一个 VBS 脚本。我将运行此脚本来获取文件的大小。
I made this to run for ever. (even this is my requirement).
我让这个永远运行。(即使这是我的要求)。
How should I know if it is running or stopped?
我应该如何知道它是在运行还是已停止?
------ Exact Script starts here -----
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FSO_check=CreateObject("Scripting.FileSystemObject")
do while infiniteLoop=0
----- This code is lasting for ever ----
Loop
Am i clear in my ques?
我的问题清楚吗?
采纳答案by nimizen
How about using the commandline property? I think this need Windows XP and up.
如何使用命令行属性?我认为这需要 Windows XP 及更高版本。
For example:
例如:
Set objSWbemServices = GetObject ("WinMgmts:Root\Cimv2")
Set colProcess = objSWbemServices.ExecQuery _
("Select * From Win32_Process where name = 'wscript.exe'")
For Each objProcess In colProcess
WScript.Echo objProcess.Name, _
objProcess.ProcessId, _
objProcess.CommandLine
Next
回答by h pic
I made a script and at the beginning i wanted to avoid having multiple / duplicate instances of the same process running. This is my code to quit the newer instance in case it gets launched when already running.
Note: This does note prevent multiple wscripts files from running - just prevents the same particular file from having simultaneous instances.
我制作了一个脚本,一开始我想避免运行同一进程的多个/重复实例。这是我退出较新实例的代码,以防它在已经运行时启动。
注意:这确实会阻止多个 wscripts 文件运行 - 只是阻止同一个特定文件同时具有实例。
To adapt to suit the original question... just use the block which checks current running processes, if the any of the wscript file names equal the script file you're looking for, then it's running.
为了适应原始问题......只需使用检查当前正在运行的进程的块,如果任何 wscript 文件名等于您正在寻找的脚本文件,那么它正在运行。
function duplicate_check
'if two scripts get here at the same time - stagger when the generate _
'the list of running processes _
'ie - give 1 of them time to close
'else they can both quit leaving no more scripts running
call random_script_sleep(2500,500)
dim myfilename
myfilename = Wscript.ScriptName
strComputer = "."
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from win32_process")
'fill arrary w/ all running script names
i = 0
For Each objProcess in colProcesses
If objProcess.Name = "wscript.exe" Then
strScriptName = Trim(Right(objProcess.CommandLine,Len(objProcess.CommandLine) - InstrRev(objProcess.CommandLine,"\")))
strScriptName = Left(strScriptName, Len(strScriptName) - 1)
a(i)= strScriptName '
i=i+1
end if
Next
'kill script if already running w/ same name
if i > 1 then 'if > 1 wscript instance
for s = 0 to i
if a(s) = myfilename then
wscript.quit
end if
next
end if
'sometimes duplicate check fails, if so, write to error log
If Err.Number = 1 Then
error_notes = " @duplicate check, firstdupcheck(0/1):" & firstdupcheck
call error_log
error_notes = "error undefined"
end if
' if debugmsg = 1 then CreateObject("WScript.Shell").Popup _
' "found this many scripts: " & i & vbCrlf & _
' "<>" & i & vbCrlf & _
' ", 1, "debug popup"
end function
回答by Fabricio
@nimizen answer is not correct. If you have another wscript running, it will return that your script is already running.
@nimizen 答案不正确。如果你有另一个 wscript 正在运行,它会返回你的脚本已经在运行。
@h pic answer is correct, but I get an error with the "a" array in my windows. So I changed it a little and cleaned to work.
@h pic 答案是正确的,但我的窗口中的“a”数组出现错误。所以我稍微改变了它并清理工作。
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\.\root\cimv2")
Set colProcesses = objWMIService.ExecQuery("select * from win32_process where name = 'wscript.exe'")
i = 0
For Each objProcess in colProcesses
if not (IsNull(objProcess.CommandLine )) then
strScriptName = Trim(Right(objProcess.CommandLine,Len(objProcess.CommandLine) - InstrRev(objProcess.CommandLine,"\")))
strScriptName = Left(strScriptName, Len(strScriptName) - 1)
if strScriptName = Wscript.ScriptName then
i=i+1
end if
if i > 1 then 'if > 1 wscript instance
'Wscript.Echo "Duplicate :"&strScriptName&" ."
Wscript.Quit
end if
end if
Next
'Wscript.Echo "Pause 2 have 2 scripts running ."
回答by klaatu
Hmm, well first if its an infinite loop script, then you're probably using it to periodically check a folder to do some work. This sounds bad but is usually less resource intense than hooking into WMI for notifications. If its up and running, its running. The real problem is discriminating it from all the other WScript and CScripts scripts you may have running.
嗯,首先,如果它是一个无限循环脚本,那么您可能正在使用它来定期检查文件夹以完成一些工作。这听起来很糟糕,但通常比挂接到 WMI 以获取通知所需的资源更少。如果它启动并运行,它正在运行。真正的问题是将它与您可能运行的所有其他 WScript 和 CScripts 脚本区分开来。
MS Sysinternals Process Explorer http://technet.microsoft.com/en-us/sysinternals/bb896653is good at telling you information about your running processes. Mostly I would use it to tell by unique command line arguments which script process is hosting which script.
MS Sysinternals Process Explorer http://technet.microsoft.com/en-us/sysinternals/bb896653擅长告诉您有关正在运行的进程的信息。大多数情况下,我会使用它通过独特的命令行参数来判断哪个脚本进程托管哪个脚本。
There is no easy way to exactly find your script's process Id from within a script. It is one of the few pieces of runtime information not exposed in the script environment's object model. Since you are already using the File System Object perhaps you could have it look for a dummy file name to use as the indicator that it is running. If the script couldn't create or open the file then you could assume that another instance of the script is already running.
没有简单的方法可以从脚本中准确地找到脚本的进程 ID。它是少数未在脚本环境的对象模型中公开的运行时信息之一。既然您已经在使用文件系统对象,也许您可以让它寻找一个虚拟文件名来用作它正在运行的指示器。如果脚本无法创建或打开文件,那么您可以假设脚本的另一个实例已经在运行。
Or have another unique named dummy file that you can easily create and your script automatically deletes during its processing run. That way you simply create an empty file of that name as a test and if it doesn't disappear in a few seconds you know no instances of your script are running.
或者有另一个独特的命名虚拟文件,您可以轻松创建该文件,并且您的脚本会在其处理运行期间自动删除。这样,您只需创建一个该名称的空文件作为测试,如果它在几秒钟内没有消失,您就知道没有脚本实例正在运行。
Also I was thinking that you could launch your script from another script using Exec() which returns the ProcessID of the launched script and then release your reference to it, storing the ProcessID wherever you need it for later use.
此外,我认为您可以使用 Exec() 从另一个脚本启动您的脚本,该脚本返回已启动脚本的 ProcessID,然后释放对它的引用,将 ProcessID 存储在您需要的任何地方以备后用。
Set oExec = WshShell.Exec( "infinite.vbs" )
MyProcessID = oExec.ProcessID ' procID of shell'd program.
set oExec = Nothing
and do something with MyProcessID
Then I noticed this posting
然后我注意到了这个帖子
Find my own process ID in VBScript
Which uses Exec() to run an HTA script, get its ProcessID and look that up in WMI, then use the result set from WMI to locate the Parent process' ProcessID which should be the script making the Exec() and WMI calls. The problem with it is the HTA may terminate before WMI gets a chance to find it.
它使用 Exec() 运行 HTA 脚本,获取其 ProcessID 并在 WMI 中查找,然后使用 WMI 的结果集定位父进程的 ProcessID,它应该是执行 Exec() 和 WMI 调用的脚本。它的问题是 HTA 可能会在 WMI 有机会找到它之前终止。
Dim iMyPID : iMyPID = GetObject("winmgmts:root\cimv2").Get("Win32_Process.Handle='" & CreateObject("WScript.Shell").Exec("mshta.exe").ProcessID & "'").ParentProcessId
Mostly I get the feeling that this is all overkill for whatever reason you think you need to know if the script is running. Instead focus on what action "knowing if the process is running or not" causes you to take. Since that hasn't been explained we really can't offer you an alternative strategy to get you there, but I'm sure a more simple solution is available. TheFolderSpy http://venussoftcorporation.blogspot.com/2010/05/thefolderspy.htmlfor example would be one alternative way to run your program without an infinite loop.
大多数情况下,我觉得无论出于何种原因,您认为您需要知道脚本是否正在运行,这一切都太过分了。而是专注于“知道进程是否正在运行”导致您采取的行动。由于尚未对此进行解释,因此我们确实无法为您提供替代策略来帮助您实现目标,但我相信有更简单的解决方案可用。例如,TheFolderSpy http://venussoftcorporation.blogspot.com/2010/05/thefolderspy.html将是一种在没有无限循环的情况下运行程序的替代方法。
Don't forget to use a sleep command in your loop to let other programs get work done. It makes a great difference in resource use. Also you only need one FSO instance, make it global to all your code by creating it early on in your script before any subroutines.
不要忘记在循环中使用 sleep 命令来让其他程序完成工作。它在资源使用方面有很大的不同。此外,您只需要一个 FSO 实例,通过在任何子例程之前的脚本中尽早创建它,使其对所有代码都是全局的。
Since you are looking at the size of a file, you are probably checking it for changes. I've found that a loop with a small WScript.Sleep 200 delay in it is good to detect if a file is done being altered. That way you can process the file instead of having to skip it until the next main loop pass which should be set to 10 seconds or more.
由于您正在查看文件的大小,因此您可能正在检查它是否有更改。我发现具有较小 WScript.Sleep 200 延迟的循环可以很好地检测文件是否已完成更改。这样你就可以处理文件,而不必跳过它,直到下一个主循环传递应该设置为 10 秒或更长时间。