如何使用批处理文件下载文件而不使用任何外部工具?

26
我先澄清一下,这个问题是针对HTTP(s)下载的。至于FTP,也许我会问另一个问题(并回答)。
这里有一些类似的问题 - 但我想更加精确。
除了排除外部工具之外,我希望解决方案适用于尽可能多类型的Windows机器(包括仍然占有相当大份额的XP、Win2003、Vista)。同时,由于WSH是可能的选项之一,我更喜欢不使用临时文件,并且将所有内容打包在一个单独的.bat文件中(这在jscript和vbscript中都是可能的)。
有哪些可能的方法呢?
  1. 使用BITSADMIN - 一个命令行实用程序,可在每台Windows计算机上使用的“纯”批处理解决方案。虽然不太方便,但在不应使用其他脚本语言的情况下,它是唯一的选择。
  2. 使用WSH - 有三种方法可行 - WinHTTPMSXML2.XMLHTTPInternetExlorer.Application - 它们都是可访问的ActiveX对象,按我喜欢的顺序排列。WinHTTP和MSXML2.XMLHTTP在功能上非常相似,但WinHTTP更稳定。InternetExlorer.Application实际上只是通过ActiveX对象访问Internet Explorer,并且一些UI元素是不可避免的(是吗?),所以我会跳过这个。
  3. 使用.NET - 可以使用所有三个默认的.NET编译器(Jscript.net,VB.Net,C#)创建混合批处理文件。对于Jscript.net而言,没有多余的错误消息,所以我会优先选择它。如果忽略已编译的.exe文件,所有代码都在一个文件中,因此根据我的要求,这很适合。使用.NET,我们可以使用System.Net.WebClient或System.Net.HttpWebRequest(WebClient依赖于它)或System.Web.HttpRequest,但现在我只会发布System.Net.WebClient解决方案。甚至更多与WSH可访问的相同ActiveX对象也可在此处使用。因此,有很多使用.NET下载文件的方法。也许将来我会更新我的答案。无论如何,只有Webclient专门设计用于下载。
  4. 使用powershell - 与.NET具有相同的功能,但安装机器上的机会较少。因此,我也会跳过这个。
2个回答

45
答案。所有脚本都应该使用.bat/.cmd扩展名保存,并可以直接用作批处理脚本。
  1. Certutuil(因为某些原因,在最新的win10版本中,这被识别为特洛伊病毒):

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

为了方便起见,可以使用宏:

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

CertUtil 命令可以被滥用以从互联网下载文件。自Vista以来,在Windows中默认可用。对于WinXP,需要安装Administration Tools。

  1. Bitsadmin

最简单的使用方法。

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

使用宏:
set "dnld=bitsadmin /transfer myDownloadJob /download /priority normal"
%dnld% "https://download.sysinternals.com/files/PSTools.zip" %cd%\pstools.zip

或使用 bitsDownloader.bat
call bitsDownloader.bat "https://download.sysinternals.com/files/PSTools.zip" pstools.zip
  1. winhhtpjs.bat是一个命令行的http客户端,它使用WinHttpRequest。它可以执行整个范围的http(POST,DELETE,..)请求,并且也可用于下载文件(不是太大的文件)。还可以添加自定义标头。
call winhhtpjs.bat "https://example.com/files/some.zip" -saveTo "c:\somezip.zip" 

4. XMLHTTPDownloadJS.bat 是一个批处理文件,使用 MSXML2.XMLHTTP 对象来下载文件。虽然没有 winhhtpjs.bat 那么丰富的选项,但仍然是一个选择。

调用 XMLHTTPDownloadJS.bat "https://download.sysinternals.com/files/PSTools.zip pst2.zip" pstools.zip

5. WebClientDownload.bat 使用 .NET System.Net.WebClient 类。它创建一个小的可执行文件以便自我编译,并需要安装 .net 框架。由于该类在较早版本的 .net 中被引入,因此向后兼容性足够。
call webclientDownload.bat "https://download.sysinternals.com/files/PSTools.zip" pstools.zip

6. 最新版本的Windows 10中已经包含了CURL命令,但这不是向后兼容的选项。请注意,只有最新版本的Windows默认安装了CURL。
``` curl "https://download.sysinternals.com/files/PSTools.zip" --output pstools.zip ```

2
bitsadmin 可以用来下载网页上的所有文件吗? - Argyll
2
@WSH JScript存在多个问题。 WScript区分大小写,-saveTo用作未命名参数, XMLHTTPObj有时会拼错为WinHTTPObj。 我还建议您使用WScript.ScriptName来简化直接调用cscript。 - antonio
2
不要忘记 PowerShell 命令 (New-Object Net.WebClient).DownloadFile('Source, Dest')。适用于 PowerShell v2,未经过 v1 测试。这是唯一一个可以在具有如此低版本的 PS 和 CMD 的操作系统上下载文件的脚本。 - John Kens
2
@npocmaka 你好,我想知道如何仅获取文件的最后修改日期,而不是下载它们。谢谢你的回答/代码!无论如何,抱歉我的英语不太好。 - Io-oI
2
我发现我需要使用/dynamic开关。例如:bitsadmin /transfer myDownloadJob /dynamic /download /priority foreground https://github.com/microsoft/vscode-cpptools/releases/latest/download/cpptools-win32.vsix %USERPROFILE%\Downloads\cpptools-win32.vsix - user2023370
显示剩余6条评论

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 中的 Cmdlets:

$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://learn.microsoft.com/zh-cn/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上测试过。


certutil的问题是新出现的。现在它被检测为一个线程。谢谢。 - npocmaka
默认情况下,现在只有TrustedInstaller才能获得Certutil的写访问权限,因为病毒滥用它来下载exe、pif、vbs和bat文件。 https://www.hybrid-analysis.com/sample/87cf118bff58c38bc0d54c1d3fcc553e381df838437a99a2006dd8f726406c16?environmentId=100 - Zimba
certutil 相对于 cURLBitsAdmin 有什么优势?你也可以使用它们来下载东西... - npocmaka
1
certutil 与证书、pfx 文件、加密密钥、注册表、根证书、活动目录、策略、缓存、数据库、编码文件(以避免被杀毒软件检测)一起工作,此外还可以下载文件和证书,因此可能是病毒和恶意软件的常用选择。 - Zimba
1
为了避免进一步被检测,certutil 还可以将可执行文件隐藏在普通文件的备用数据流中,例如 trustme.txt - Zimba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接