VBS真的能实现多线程?

标签: , , ,

今天在批处理之家看到一个帖子《vbs多线程下载》,想起以前在VBS吧也看过《多线程下载文件》,当时我就质疑这到底是不是多线程,今天正好研究一下VBS是否真的能实现多线程。

DownloadFile "http://www.baidu.com","baidu.txt"
DownloadFile "http://www.sohu.com","sohu.txt"
DownloadFile "http://www.sina.com.cn","sina.txt"

MsgBox "请等待下载完成..."&Space(20),0,"多线程下载 By 次碳酸钴"

Sub DownloadFile(s,n)
  c="Set h0=CreateObject(""Microsoft.XMLHTTP"")"&VbCrLf
  c=c&"Sub th0"&VbCrLf
  c=c&"If h0.ReadyState=4 Then SaveToFile h0.ResponseBody,""fn"""&VbCrLf
  c=c&"End Sub"&VbCrLf
  c=c&"h0.OnReadyStateChange=GetRef(""th0"")"&VbCrLf
  c=c&"h0.Open ""GET"",""url"",True:h0.Send"&VbCrLf
  c=Replace(c,"0",Rnd*1E15):c=Replace(c,"fn",n):c=Replace(c,"url",s):
  ExecuteGlobal c
End Sub

Sub SaveToFile(a,b)
  On Error Resume Next:Err.Clear
  With CreateObject("ADODB.Stream")
    .Type=1:.Mode=3:.Open
    .Write a
    If Err.Number Then Msgbox b&" 下载失败!":Exit Sub
    .SaveToFile b
    If Err.Number Then Msgbox b&" 文件保存失败或文件已存在!":Exit Sub
    Msgbox b&" 下载完成!"
  End With
End Sub

用OllyDbg载入wscript.exe,bp CreateThread和NtCreateThread函数,F9运行,根本没有被断下来,也就是说,根本没有创建新的线程。

我曾经也写过一篇《VBS实现“多线程”》(注意我的“多线程”加了双引号):

Dim IE
Set IE = CreateObject("InternetExplorer.Application")
IE.Navigate "about:blank"
Set window = IE.Document.parentWindow
id = window.setTimeout(GetRef("on_timeout"),3000,"VBScript")
name = InputBox("Please enter your name","InputBox Timeout")
window.clearTimeout id
If name <> "" Then MsgBox "Hello," & name
IE.Quit

'By Demon
'http://demon.tw

Sub on_timeout()
    Dim WshShell
    set WshShell = CreateObject("wscript.Shell")
    WshShell.SendKeys "{ESC}"
End Sub

很遗憾,用OllyDbg调试的结果和上面的一样,根本没有用CreateThread函数创建新线程。

但是如果你观察OllyDbg的线程窗口,会发现会有新的线程创建,这是怎么回事呢?事实上,Windows程序大多数都是多线程的,即使程序没有主动去创建线程。(Most Win32 applications are really multithreaded, even if they don’t know it)如果不是CreateThread创建的线程,那很有可能是系统为完成某些工作而创建的线程,不属于用户代码。以上面的VBS多线程下载为例,异步请求的内部应该调用了某些异步IO的API,而这些API为了实现异步的功能可能会创建新的进程。

所以VBS是否能实现多线程,得看你从哪个角度来看,如果从系统角度来看,它的确使用了多线程(切,谁不是呢);如果从用户的角度看,它并没有创建新的线程。

但是一般意义上的多线程指的是程序主动去创建的,个人认为上面的VBS不属于多线程。

随机文章:

  1. 用VBS解压缩ZIP文件
  2. NETGEAR WNDRMAC路由器刷OpenWrt
  3. VB6拾遗:数组的内部实现
  4. VBS的SendKeys,你真的懂吗?
  5. 用Python脚本查询纯真IP库QQWry.dat(Demon修改版)

留下回复