.net jscript wsh batch-file

.net - ¿Cómo puedo descargar un archivo con archivo por lotes sin usar ninguna herramienta externa?



jscript wsh (1)

Primero, para aclarar esta pregunta, está dirigida a la descarga de HTTP (s) .Para FTP, puedo hacer (y responder) otra pregunta. Aquí hay algunas preguntas similares , pero quiero ser más preciso.

Además de excluir las herramientas externas, quiero que la (s) solución (es) sea aplicable (s) a los tipos más amplios de máquinas con Windows (incluidos XP, Win2003, Vista, que todavía tienen una participación lo suficientemente grande). Además, como WSH es una de las opciones posibles, prefiero no usar archivos temporales y todo lo que se empaquetará en un solo archivo .bat (que es posible con jscript y vbscript).

¿Cuáles son los posibles enfoques?

  1. Solución por lotes "pura" con BITSADMIN : una utilidad de línea de comandos disponible en todas las máquinas Windows. No es muy conveniente, pero es una / la única opción donde no se debe utilizar ningún otro lenguaje de secuencias de comandos.
  2. Uso de WSH: son posibles tres enfoques: WinHTTP , MSXML2.XMLHTTP , InternetExlorer.Application : todos ellos son objetos ActiveX accesibles en el orden en que los prefiero. WinHTTP y MSXML2.XMLHTTP son bastante similares en sus capacidades, pero WinHTTP tiene una reputación de más estable.InternetExlorer.La aplicación es, de hecho, solo el explorador de Internet accesible a través del objeto ActiveX y algunos elementos de la interfaz de usuario son inevitables (¿lo son?), así que omitiré este.
  3. Uso de .NET: es posible crear un archivo por lotes híbrido con los tres compiladores .NET predeterminados (Jscript.net, VB.Net, C #) con Jscript.net, no hay mensajes de error redundantes, por lo que lo preferiría. ignore el hecho de que hay un .exe compilado, todo el código está en un archivo, por lo que, según yo, esto cumple con los requisitos :-) .Con .NET podemos usar System.Net.WebClient o System.Net.HttpWebRequest (el WebClient confía en ello) o
    System.Web.HttpRequest, pero por ahora solo publicaré la solución System.Net.WebClient. Incluso más objetos ActiveX accesibles con WSH están disponibles aquí también. Por lo tanto, hay muchas maneras de descargar un archivo con .Net.May en el futuro actualizaré mi respuesta. De todos modos, solo el Webclient está especialmente diseñado para su descarga.
  4. Usar powershell: tiene las mismas posibilidades que .NET, pero con menos posibilidades de instalarse en todas las máquinas que pueda encontrar, por lo que también me saltearé esta.

Las respuestas. Todos los scripts deben guardarse con extensiones .bat / .cmd y pueden usarse directamente como scripts por lotes.

1) Certutuil :

certutil.exe -urlcache -split -f "https://download.sysinternals.com/files/PSTools.zip" pstools.zip

CertUtil puede abusar del comando CertUtil para descargar un archivo de Internet. Disponible de forma predeterminada en Windows desde Vista. Para WinXP Server 2003 se necesitan herramientas de administración.

2) Bitsadmin :

La forma más simple de usarlo

bitsadmin /transfer myDownloadJob /download /priority normal http://downloadsrv/10mb.zip c:/10mb.zip

O (eventualmente necesitará esto si desea agregar credenciales, proxy y etc.)

@echo off setlocal :: uses bitsadmin utility to download a file :: bitsadmin is not available in winXP Home edition :: the only way to download a file with ''pure'' batch :download if "%2" equ "" ( call :help exit /b 5 ) if "%1" equ "" ( call :help exit /b 6 ) set url=%~1 set file=%~2 rem ---- if "%~3" NEQ "" ( set /A timeout=%~3 ) else ( set timeout=5 ) bitsadmin /cancel download >nul bitsadmin /create /download download >nul call bitsadmin /addfile download "%url%" "%CD%/%file%" >nul bitsadmin /resume download >nul bitsadmin /setproxysettings download AUTODETECT >nul set /a attempts=0 :repeat set /a attempts +=1 if "%attempts%" EQU "10" ( echo TIMED OUT endlocal exit /b 1 ) bitsadmin /info download /verbose | find "STATE: ERROR" >nul 2>&1 && endlocal && bitsadmin /cancel download && echo SOME KIND OF ERROR && exit /b 2 bitsadmin /info download /verbose | find "STATE: SUSPENDED" >nul 2>&1 && endlocal && bitsadmin /cancel download &&echo FILE WAS NOT ADDED && exit /b 3 bitsadmin /info download /verbose | find "STATE: TRANSIENT_ERROR" >nul 2>&1 && endlocal && bitsadmin /cancel download &&echo TRANSIENT ERROR && exit /b 4 bitsadmin /info download /verbose | find "STATE: TRANSFERRED" >nul 2>&1 && goto :finishing w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:%timeout% >nul 2>&1 goto :repeat :finishing bitsadmin /complete download >nul echo download finished endlocal goto :eof :help echo %~n0 url file [timeout] echo. echo url - the source for download echo file - file name in local directory where the file will be stored echo timeout - number in seconds between each check if download is complete (attempts are 10) echo. goto :eof

3) - WinHttp y WSH (las opciones SSL / certificado y Proxy nunca se han probado ...). Aquí hay un script listo para usar que usa WinHttpRequest . Puede realizar una amplia gama de solicitudes http y también puede usarse para descargar archivos (no archivos demasiado grandes). Si lo necesita, también puede agregar sus propios encabezados de autenticación.

call winhhtpjs.bat https://example.com/files/some.zip -saveTo c:/somezip.zip

4) MSXML2.XMLHTTP y WSH (mejor uso de WinHTTP) (las opciones SSL / certificado y Proxy nunca se han probado ...)

@if (@X)==(@Y) @end /* JScript comment @echo off rem :: the first argument is the script name as it will be used for proper help message cscript //E:JScript //nologo "%~f0" "%~nx0" %* exit /b %errorlevel% @if (@X)==(@Y) @end JScript comment */ // used resources //http://www.codeproject.com/Tips/506439/Downloading-files-with-VBScript //http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx //https://msdn.microsoft.com/en-us/library/ie/ms535874(v=vs.85).aspx //https://msdn.microsoft.com/en-us/library/aa923283.aspx //https://msdn.microsoft.com/en-us/library/ms759148(v=vs.85).aspx //https://msdn.microsoft.com/en-us/library/ms759148(v=vs.85).aspx //https://msdn.microsoft.com/en-us/library/ms760236(v=vs.85).aspx //http://.com/questions/20712635/providing-authentication-info-via-msxml2-serverxmlhttp //https://msdn.microsoft.com/en-us/library/ms763680(v=vs.85).aspx //https://msdn.microsoft.com/en-us/library/ms757849(v=vs.85).aspx //http://fm4dd.com/programming/shell/microsoft-vbs-http-download.htm //http://.com/questions/11573022/vba-serverxmlhttp-https-request-with-self-signed-certificate //http://www.qtcentre.org/threads/44629-Using-XMLHttpRequest-for-HTTPS-Post-to-server-with-SSL-certificate // global variables and constants var ARGS = WScript.Arguments; var scriptName=ARGS.Item(0); var url=""; var saveTo=""; var user=0; var pass=0; var proxy=0; var bypass=""; var proxy_user=0; var proxy_pass=0; var certificate=0; var force=true; //ActiveX objects //Use the right version of MSXML /*var progIDs = [ ''Msxml2.DOMDocument.6.0'', ''Msxml2.DOMDocument.5.0'', ''Msxml2.DOMDocument.4.0'', ''Msxml2.DOMDocument.3.0'', ''Msxml2.DOMDocument'' ] for (var i = 0; i < progIDs.length; i++) { try { var XMLHTTPObj = new ActiveXObject(progIDs[i]); }catch (ex) { } } if typeof XMLHTTPObj === ''undefined''{ WScript.Echo ("You are using too ancient windows or you have no installed IE"); WScript.Quit(1); }*/ var XMLHTTPObj = new ActiveXObject("MSXML2.XMLHTTP"); var FileSystemObj = new ActiveXObject("Scripting.FileSystemObject"); var AdoDBObj = new ActiveXObject("ADODB.Stream"); function printHelp(){ WScript.Echo(scriptName + " - downloads a file through HTTP"); WScript.Echo(scriptName + " url localfile [-force yse|no] [-user username -password password] [-proxy proxyserver:port -bypass bypass_list]"); WScript.Echo(" [-proxyuser proxy_username -proxypassword proxy_password] [-certificate certificateString]"); WScript.Echo("-force - decide to not or to overwrite if the local exists"); WScript.Echo("proxyserver:port - the proxy server"); WScript.Echo("bypass- bypass list can be /"/" if you don''t need it"); WScript.Echo("proxy_user , proxy_password - credentials for proxy server"); WScript.Echo("user , password - credentials for the server"); WScript.Echo("certificate - location of SSL certificate"); WScript.Echo("Example:"); WScript.Echo(scriptName +" http://somelink.com/somefile.zip c://somefile.zip -certificate /"LOCAL_MACHINE//Personal//My Middle-Tier Certificate/""); } function parseArgs(){ // if (ARGS.Length < 3) { WScript.Echo("insufficient arguments"); printHelp(); WScript.Quit(43); } url=ARGS.Item(1); saveTo=ARGS.Item(2); if(ARGS.Length % 2 != 1) { WScript.Echo("illegal arguments"); printHelp(); WScript.Quit(44); } for (var i=3;i<ARGS.Length-1;i=i+2){ if(ARGS.Item(i).toLowerCase=="-force" && ARGS.Item(i+1)==''no''){ force=false; } if(ARGS.Item(i).toLowerCase=="-user"){ user=ARGS.Item(i+1); } if(ARGS.Item(i).toLowerCase=="-password"){ pass=ARGS.Item(i+1); } if(ARGS.Item(i).toLowerCase=="-proxy"){ proxy=ARGS.Item(i+1); } if(ARGS.Item(i).toLowerCase=="-bypass"){ bypass=ARGS.Item(i+1); } if(ARGS.Item(i).toLowerCase=="-proxyuser"){ proxy_user=ARGS.Item(i+1); } if(ARGS.Item(i).toLowerCase=="-proxypassword"){ proxy_pass=ARGS.Item(i+1); } if(ARGS.Item(i).toLowerCase=="-certificate"){ certificate=ARGS.Item(i+1); } } } function existsItem(path){ return FileSystemObj.FolderExists(path)||FileSystemObj.FileExists(path); } stripTrailingSlash = function(path){ while (path.substr(path.length - 1,path.length) == ''//') { path=path.substr(0, path.length - 1); } return path; } function deleteItem(path){ if (FileSystemObj.FileExists(path)){ FileSystemObj.DeleteFile(path); return true; } else if (FileSystemObj.FolderExists(path) ) { FileSystemObj.DeleteFolder(stripTrailingSlash(path)); return true; } else { return false; } } function writeFile(fileName,data ){ AdoDBObj.Type = 1; AdoDBObj.Open(); AdoDBObj.Position=0; AdoDBObj.Write(data); AdoDBObj.SaveToFile(fileName,2); AdoDBObj.Close(); } function download( url,file){ if (force && existsItem(file)){ if(!deleteItem(file)){ WScript.Echo("Unable to delete "+ file); WScript.Quit(8); } }else if (existsItem(file)){ WScript.Echo("Item " + file + " already exist"); WScript.Quit(9); } if (proxy!=0 && bypass !="") { //https://msdn.microsoft.com/en-us/library/ms760236(v=vs.85).aspx XMLHTTPObj.setProxy(SXH_PROXY_SET_DIRECT,proxy,bypass); } else if (proxy!=0) { XMLHTTPObj.setProxy(SXH_PROXY_SET_DIRECT,proxy,""); } if (proxy_user!=0 && proxy_pass!=0 ) { //https://msdn.microsoft.com/en-us/library/ms763680(v=vs.85).aspx XMLHTTPObj.setProxyCredentials(proxy_user,proxy_pass); } if(certificate!=0) { //https://msdn.microsoft.com/en-us/library/ms763811(v=vs.85).aspx WinHTTPObj.setOption(3,certificate); } if (user!=0 && pass!=0){ //https://msdn.microsoft.com/en-us/library/ms757849(v=vs.85).aspx XMLHTTPObj.Open(''GET'',url,false,user,pass); } else { XMLHTTPObj.Open(''GET'',url,false); } XMLHTTPObj.Send(); var status=XMLHTTPObj.Status switch(status){ case 200: WScript.Echo("Status: 200 OK"); break; case 401: WScript.Echo("Status: 401 Unauthorized"); WScript.Echo("Check if correct user and password were provided"); WScript.Quit(401); break; case 407: Wscript.Echo("Status:407 Proxy Authentication Required"); Wscript.Echo("Check if correct proxy user and password were provided"); WScript.Quit(407); break; default: Wscript.Echo("Status: "+status); WScript.Echo("Try to help yourself -> https://en.wikipedia.org/wiki/List_of_HTTP_status_codes"); WScript.Quit(status); } writeFile(file,XMLHTTPObj.ResponseBody); } function main(){ parseArgs(); download(url,saveTo); } main();

5) .NET y cliente web (Aquí no hay opción SSL. Intentará agregarlo. Las opciones de Poxy nunca han sido probadas)

@if (@X)==(@Y) @end /* JScript comment @echo off setlocal for /f "tokens=* delims=" %%v in (''dir /b /s /a:-d /o:-n "%SystemRoot%/Microsoft.NET/Framework/*jsc.exe"'') do ( set "jsc=%%v" ) ::if not exist "%~n0.exe" ( "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0" ::) %~n0.exe %* endlocal & exit /b %errorlevel% */ //todo SSL Support //todo Better help message //todo check if local file exists import System; import System.Net.WebClient; import System.Net.NetworkCredential; import System.Net.WebProxy; import System.Uri; import System.Security.Cryptography.X509Certificates; var arguments:String[] = Environment.GetCommandLineArgs(); var url=0; var toFile=0; var force=true; var user=0; var password=0; var proxy=0; var bypass=0; var proxy_user=0; var proxy_pass=0; var certificate=0; function printHelp(){ Console.WriteLine(arguments[0] + "download from url to a file"); Console.WriteLine(arguments[0] + "<url> <file> [-user user -password password] [-proxy proxy] [-proxy_user proxy.user -proxy_pass proxy.pass]"); } function parseArgs(){ if (arguments.length < 3) { Console.WriteLine("Wrong arguments"); printHelp(); Environment.Exit(1); } if (arguments.length %2 != 1) { Console.WriteLine("Wrong number arguments"); printHelp(); Environment.Exit(2); } url=arguments[1]; toFile=arguments[2]; for (var i=3;i<arguments.length-1;i=i+2){ var arg=arguments[i].ToLower(); switch (arg){ case "-user" : user=arguments[i+1]; break; case "-password" : password=arguments[i+1]; break; case "-proxy" : proxy=arguments[i+1]; break; case "-proxy_user" : proxy_user=arguments[i+1]; break; case "-proxy_pass" : proxy_pass=arguments[i+1]; break; case "-bypass" : bypass=[arguments[i+1]]; break; /*case "-certificate" : certificate=arguments[i+1]; break;*/ default: Console.WriteLine("Invalid argument "+ arguments[i]); printHelp(); Environment.Exit(3); } } } function download(){ var client:System.Net.WebClient = new System.Net.WebClient(); if (user!=0 && password!=0){ client.Credentials=new System.Net.NetworkCredential(user, password); } if (proxy!=0){ var webproxy =new System.Net.WebProxy(); webproxy.Address=new Uri(proxy); if (proxy_user!=0 && proxy_pass!=0){ webproxy.Credentials=new System.Net.NetworkCredential(proxy_user,proxy_pass); } webproxy.UseDefaultCredentials =false; if (bypass!=0){ webproxy.BypassList=bypass; webproxy.BypassProxyOnLocal = false; } client.Proxy=webproxy; } try { client.DownloadFile(arguments[1], arguments[2]); } catch (e) { Console.BackgroundColor = ConsoleColor.Green; Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("/n/nProblem with downloading " + arguments[1] + " to " + arguments[2] + "Check if the internet address is valid"); Console.ResetColor(); Environment.Exit(5); } } parseArgs(); download();