首先澄清这个问题是针对HTTP(s)下载的。对于FTP,我可能会问(并回答)另一个问题。 以下是some similar questions - 但我希望更加准确。
除了排除外部工具之外,我希望解决方案适用于最广泛类型的Windows机器(包括仍然具有足够大份额的XP,Win2003,Vista)。
另外,WSH
是可能的选项之一,我不喜欢使用临时文件,而是要将所有内容打包在一个.bat
文件中(jscript和vbscript都可以使用)。
有哪些可行的方法。
答案 0 :(得分:32)
答案。所有脚本都应使用.bat
/ .cmd
扩展名保存,并可直接用作批处理脚本。
1)Certutuil:
certutil.exe -urlcache -split -f "https://download.sysinternals.com/files/PSTools.zip" pstools.zip
可以滥用CertUtil命令从Internet下载文件。默认情况下可以在Windows中使用Vista.For WinXP Server 2003管理工具。
2) Bitsadmin :
最简单的使用方法
bitsadmin /transfer myDownloadJob /download /priority normal http://downloadsrv/10mb.zip c:\10mb.zip
或者(如果你想添加凭证,代理等,你最终会需要这个。)
@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 and WSH(SSL /证书和代理选项从未经过测试......)。 Here'准备好使用WinHttpRequest的脚本。它可以执行各种http请求,也可以用于下载文件(不是太大的文件)。如果需要,还可以添加你自己的身份验证标题。
call winhhtpjs.bat https://example.com/files/some.zip -saveTo c:\somezip.zip
4) MSXML2.XMLHTTP和WSH (更好地使用WinHTTP)(SSL /证书和代理选项从未经过测试......)
@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://stackoverflow.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://stackoverflow.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和webclient (这里没有SSL选项。请尝试添加它.Poxy选项从未经过测试)
@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();
答案 1 :(得分:2)
Windows上有一个实用程序(驻留在CMD中),可以从CMD运行(如果您具有写权限):
set url=https://www.nsa.org/content/hl-images/2017/02/09/NSA.jpg
set file=file.jpg
certutil -urlcache -split -f %url% %file%
:also certutil.exe -verifyctl -f -split %url% %file%
Powershell中的cmdlet:
$url = "https://www.nsa.org/content/hl-images/2017/02/09/NSA.jpg"
$file = "file.jpg"
$ProgressPreference = "SilentlyContinue";
Invoke-WebRequest -Uri $url -outfile $file
.Net在PowerShell下:
$url = "https://www.nsa.org/content/hl-images/2017/02/09/NSA.jpg"
$file = "file.jpg"
# Add the necessary .NET assembly
Add-Type -AssemblyName System.Net.Http
# Create the HttpClient object
$client = New-Object -TypeName System.Net.Http.Httpclient
$task = $client.GetAsync($url)
$task.wait();
[io.file]::WriteAllBytes($file, $task.Result.Content.ReadAsByteArrayAsync().Result)
使用csc.exe进行C#命令行构建:
https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/command-line-building-with-csc-exe
using System;
using System.IO;
using System.Net.Http;
using System.Threading.Tasks;
namespace DownloadImage
{
class Program
{
static async Task Main(string[] args)
{
using var httpClient = new HttpClient();
var url = "https://www.nsa.org/content/hl-images/2017/02/09/NSA.jpg";
byte[] imageBytes = await httpClient.GetByteArrayAsync(url);
using var fs = new FileStream("file.jpg", FileMode.Create);
fs.Write(imageBytes, 0, imageBytes.Length);
}
}
}
内置于Windows应用程序中。无需外部下载。
在Win 10上测试