Windows Script Host (jscript):如何下载二进制文件?

发布于 2024-10-02 06:36:56 字数 418 浏览 6 评论 0原文

我正在尝试使用 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 ): 在此操作范围内未找到与名称、范围或选择条件匹配的对象或数据。

i'm trying to automate a file download with Windows Script Host (JScript). i see ADODB.Stream has an Open method whose documentation makes it seem like it should be possible to open a HTTP URL and stream the response body:

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();

But it bombs on the Open call with

(null): Object or data matching the name, range, or selection criteria was not found within the scope of this operation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

哥,最终变帅啦 2024-10-09 06:36:56

这是 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:

Here is the download code in JScript. Also added some references to API information.

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 Stream:

Scripting.FileSystemObject:

够运 2024-10-09 06:36:56

你走在正确的轨道上。

您应该使用 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

You're on the right track.

You should be using the XMLHTTPRequest Object to communicate with the server. It's sort of like "curl" for Windows Script. Once the data is read from the remote server, you can write it into an ADODB stream and manipulate it within your script. In your case, writing to a file using the FileSystemObject seems like the most logical course of action.

So your script might look something like this:

' 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
雨落星ぅ辰 2024-10-09 06:36:56

将上面的代码转换为 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();
}

Converted the above code to JavaScript. This appears to work for me. Recommend adding a try catch block to the caller. Also, converted to async. I've used this code to save some 90 files at the same time. Since the delete file (necessary as the overwrite fails) is synchronous, it is better moved to a separate function for multiple files.

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();
}
玩心态 2024-10-09 06:36:56

您的 URL 需要采用以下格式:

URL=scheme://server/folder

Your URL needs to be in this format:

URL=scheme://server/folder
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文