Хост сценариев Windows (jscript): как загрузить двоичный файл?

Я пытаюсь автоматизировать загрузку файла с помощью Windows Script Host (JScript). я вижу, что в ADODB.Stream есть метод Open, в документации которого создается впечатление, что должно быть возможно открыть URL-адрес HTTP и передать тело ответа:

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): объект или данные, соответствующие имени, диапазону или критериям выбора, не найдены в рамках этой операции.


person just somebody    schedule 12.11.2010    source источник
comment
Дети, единственный правильный ответ на любой вопрос, начинающийся со слов «Как мне использовать WSH для...» — это НЕ. этот вопрос был лишь верхушкой айсберга проблем, которые у меня были тогда, решил пойти с python и его win32api, и, хотя он не был звездным (документы), я смог немного автоматизировать в Windows, не теряя здравомыслия .   -  person just somebody    schedule 25.06.2013


Ответы (4)


Вот код загрузки в 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:

Сценарий.FileSystemObject:

person David Ruhmann    schedule 20.06.2013
comment
я не могу подтвердить, что это действительно работает, поскольку я больше не работаю с окнами (ура!), И в конце концов я все равно использовал python. это выглядит нормально, и это jScript, так что я принимаю это. - person just somebody; 25.06.2013

Вы на правильном пути.

Вы должны использовать объект XMLHTTPRequest для связи с сервером. Это что-то вроде «завитка» для Windows Script. Как только данные будут прочитаны с удаленного сервера, вы можете записать их в поток 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
person Nilpo    schedule 24.04.2011
comment
Это VBscript, а не JScript - person user2428118; 30.11.2012

Преобразовал приведенный выше код в 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();
}
person Greg    schedule 14.05.2014
comment
Используйте objADOStream.saveToFile(sDestFile, 2); // adSaveCreateOverWrite, чтобы избавиться от необходимости удаления файла. - person Ekkehard.Horner; 16.05.2014
comment
Спасибо за помощь Эккехарду. - person Greg; 16.05.2014

Ваш URL должен быть в следующем формате:

URL=scheme://server/folder
person bigeyes0x0    schedule 09.02.2011
comment
Не могли бы вы объяснить, почему? - person Serge Belov; 30.11.2012
comment
См. Метод открытия MSDN (ADO Stream). Это говорит о том, что источник должен быть строкой, отформатированной как var url = 'URL=http://example.com/example.tar.gz'; - person David Ruhmann; 21.06.2013