Windows Script Host (jscript): как загрузить двоичный файл?
Я пытаюсь автоматизировать загрузку файлов с помощью 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): Объект или данные, соответствующие имени, диапазону или критериям выбора, не были найдены в рамках этой операции.
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 Stream:
- http://www.w3schools.com/ado/ado_ref_stream.asp
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms675032.aspx
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms680846.aspx
Scripting.FileSystemObject:
Вы на правильном пути.
Вы должны использовать объект 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
Преобразовал приведенный выше код в 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();
}
Ваш URL должен быть в следующем формате:
URL=scheme://server/folder