【问题标题】:Windows Script Host (jscript): how do i download a binary file?Windows 脚本宿主 (jscript):如何下载二进制文件?
【发布时间】:2011-05-09 01:00:48
【问题描述】:

我正在尝试使用 Windows Script Host (JScript) 自动下载文件。我看到 ADODB.Stream 有一个 Open 方法,其文档表明应该可以打开 HTTP URL 并流式传输响应正文:

var url = 'http://example.com/example.tar.gz';
var path = 'example.tar.gz';

var input = WScript.CreateObject('ADODB.Stream');

input.Open(url);
input.SaveToFile(path);
input.Close();

但它会在 Open 调用时爆炸

(null):在此操作范围内未找到与名称、范围或选择条件匹配的对象或数据。

【问题讨论】:

  • 孩子们,对于以“如何使用 WSH 来...”开头的任何问题,唯一正确的答案是 不要。这个问题只是我当时遇到的问题的冰山一角,决定使用 python 及其 win32api,虽然它不是一流的(文档),但我能够在 Windows 中实现相当多的自动化而不会失去理智.

标签: adodb wsh jscript


【解决方案1】:

这里是 JScript 中的下载代码。还添加了一些对 API 信息的引用。

var Source = WScript.Arguments.Item(0);
var Target = WScript.Arguments.Item(1);
var Object = WScript.CreateObject('MSXML2.XMLHTTP');

Object.Open('GET', Source, false);
Object.Send();

if (Object.Status == 200)
{
    // Create the Data Stream
    var Stream = WScript.CreateObject('ADODB.Stream');

    // Establish the Stream
    Stream.Open();
    Stream.Type = 1; // adTypeBinary
    Stream.Write(Object.ResponseBody);
    Stream.Position = 0;

    // Create an Empty Target File
    var File = WScript.CreateObject('Scripting.FileSystemObject');
    if (File.FileExists(Target))
    {
        File.DeleteFile(Target);
    }

    // Write the Data Stream to the File
    Stream.SaveToFile(Target, 2); // adSaveCreateOverWrite
    Stream.Close();
}

ADODB 流:

Scripting.FileSystemObject:

【讨论】:

  • 我无法确认这确实有效,因为我不再使用 Windows(万岁!),最后我还是使用了 python。它看起来很正常,而且它是 jScript,所以我接受它。
【解决方案2】:

你在正确的轨道上。

您应该使用 XMLHTTPRequest 对象与服务器进行通信。它有点像 Windows 脚本的“curl”。从远程服务器读取数据后,您可以将其写入 ADODB 流并在脚本中对其进行操作。在您的情况下,使用 FileSystemObject 写入文件似乎是最合乎逻辑的做法。

所以你的脚本可能看起来像这样:

' Set your settings
strFileURL = "http://www.domain.com/file.zip"
strSavePath = "C:\somefolder\"

' Send an HTTP request for the file
Set objXMLHTTP = CreateObject("MSXML2.XMLHTTP")

objXMLHTTP.open "GET", strFileURL, false
objXMLHTTP.send()

' If the server responds with "OK"...
If objXMLHTTP.Status = 200 Then
    ' Create a stream object to write downloaded data to
    Set objADOStream = CreateObject("ADODB.Stream")
    objADOStream.Open
    objADOStream.Type = 1 'adTypeBinary

    objADOStream.Write objXMLHTTP.ResponseBody
    objADOStream.Position = 0

    ' Create an empty file on disk
    Set objFso = Createobject("Scripting.FileSystemObject")
    ' Make sure we don't have any name collision...
    If objFso.Fileexists(strSavePath) Then objFSO.DeleteFile strSavePath
    Set objFso = Nothing

    ' Write the stream data to file
    objADOStream.SaveToFile strSavePath
    objADOStream.Close
    Set objADOStream = Nothing
End if

Set objXMLHTTP = Nothing

【讨论】:

  • 那是VBscript,不是JScript
【解决方案3】:

将上述代码转换为 JavaScript。这似乎对我有用。建议向调用者添加一个 try catch 块。此外,转换为异步。我用这段代码同时保存了大约 90 个文件。由于删除文件(覆盖失败时是必需的)是同步的,因此最好将多个文件移到单独的函数中。

function saveFile(sSourceUrl, sDestFile) {
    var objXMLHTTP = new ActiveXObject("MSXML2.XMLHTTP");
    objXMLHTTP.onreadystatechange=function() {
        if (objXMLHTTP.readyState === 4) {
            var objADOStream = new ActiveXObject("ADODB.Stream");
            objADOStream.open();
            objADOStream.type = 1; // Binary
            objADOStream.write(objXMLHTTP.ResponseBody);
            objADOStream.position = 0;
            objADOStream.saveToFile(sDestFile, 2);
            objADOStream.close();
        }
    };

    objXMLHTTP.open("GET", sSourceUrl, false);
    objXMLHTTP.send();
}

【讨论】:

  • 使用objADOStream.saveToFile(sDestFile, 2); // adSaveCreateOverWrite 摆脱文件删除的需要。
  • 感谢埃克哈德的帮助。
【解决方案4】:

您的网址需要采用以下格式:

URL=scheme://server/folder

【讨论】:

  • 您愿意解释一下原因吗?
  • MSDN Open Method (ADO Stream)。这就是说源应该是格式为var url = 'URL=http://example.com/example.tar.gz'; 的字符串
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-28
  • 1970-01-01
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-03
相关资源
最近更新 更多