Mic*_*ael 23 msbuild msbuildcommunitytasks
是否有内置的方法使用HTTP将文件下载到本地目录?
我可以打算忘记或编写自定义任务,但我想确保没有现成的方法来实现这一点.
提前致谢!
Jas*_*ome 28
在MSBuild 4.0中,您可以使用内联任务来避免需要在单独的程序集中编译和部署自定义任务.
<UsingTask TaskName="DownloadFile" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Address ParameterType="System.String" Required="true"/>
<FileName ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Reference Include="System" />
<Code Type="Fragment" Language="cs">
<![CDATA[
new System.Net.WebClient().DownloadFile(Address, FileName);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="DownloadSomething">
<DownloadFile Address="http://somewebsite/remotefile" FileName="localfilepath" />
</Target>
Run Code Online (Sandbox Code Playgroud)
Ste*_*HHH 10
如果您尝试下载需要身份验证的文件(例如TFS Web或连接到域的IIS服务器),则MSBuild扩展包和MSBuild社区任务似乎都无法提供用户名或密码. HTTP服务器.在这种情况下,我最终编写了一个自定义的MSBuild任务.这就是我做的.
我按照Stack Overflow用户Doug的建议,在他的回答下载了一个需要使用vb.net/c#进行身份验证的文件?,他在其中建议添加一些代码以添加到Tom Archer在Code Guru网站上编写的方法.
因此,我使用MS Visual Studio 2010创建了一个新的C#项目,其中包含以下代码,用于创建名为Wget的MSBuild目标(显示完整的源代码):
// Include references to the following frameworks in your solution:
// - Microsoft.Build.Framework
// - Microsoft.Build.Utilities.v4.0
// - System
// - System.Net
using System;
using System.Net;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace Wget
{
public class Wget: Task
{
[Required]
public String Address // HTTP address to access
{ get; set; }
[Required]
public String LocalFilename // Local file to which the downloaded page will be saved
{ get; set; }
public String Username // Credential for HTTP authentication
{ get; set; }
public String Password // Credential for HTTP authentication
{ get; set; }
public override bool Execute()
{
int read = DownloadFile(Address, LocalFilename, Username, Password);
Console.WriteLine("{0} bytes written", read);
return true;
}
public static int DownloadFile(String remoteFilename, String localFilename, String httpUsername, String httpPassword)
{
// Function will return the number of bytes processed
// to the caller. Initialize to 0 here.
int bytesProcessed = 0;
// Assign values to these objects here so that they can
// be referenced in the finally block
Stream remoteStream = null;
Stream localStream = null;
WebResponse response = null;
// Use a try/catch/finally block as both the WebRequest and Stream
// classes throw exceptions upon error
try
{
// Create a request for the specified remote file name
WebRequest request = WebRequest.Create(remoteFilename);
if (request != null)
{
// If a username or password have been given, use them
if (httpUsername.Length > 0 || httpPassword.Length > 0)
{
string username = httpUsername;
string password = httpPassword;
request.Credentials = new System.Net.NetworkCredential(username, password);
}
// Send the request to the server and retrieve the
// WebResponse object
response = request.GetResponse();
if (response != null)
{
// Once the WebResponse object has been retrieved,
// get the stream object associated with the response's data
remoteStream = response.GetResponseStream();
// Create the local file
localStream = File.Create(localFilename);
// Allocate a 1k buffer
byte[] buffer = new byte[1024];
int bytesRead;
// Simple do/while loop to read from stream until
// no bytes are returned
do
{
// Read data (up to 1k) from the stream
bytesRead = remoteStream.Read(buffer, 0, buffer.Length);
// Write the data to the local file
localStream.Write(buffer, 0, bytesRead);
// Increment total bytes processed
bytesProcessed += bytesRead;
} while (bytesRead > 0);
}
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// Close the response and streams objects here
// to make sure they're closed even if an exception
// is thrown at some point
if (response != null) response.Close();
if (remoteStream != null) remoteStream.Close();
if (localStream != null) localStream.Close();
}
// Return total bytes processed to caller.
return bytesProcessed;
}
}
}
Run Code Online (Sandbox Code Playgroud)
有了这个,我可以将以下任务添加到我的MSBuild项目:
<!-- Get the contents of a Url-->
<Wget
Address="http://mywebserver.com/securepage"
LocalFilename="mydownloadedfile.html"
Username="myusername"
Password="mypassword">
</Wget>
Run Code Online (Sandbox Code Playgroud)
Wget任务下载mywebserver.com提供的页面,并使用用户名"myusername"和密码"mypassword"将其保存到当前工作目录中的文件mydownloadedfile.html.
但是,为了使用自定义Wget MSBuild任务,我必须告诉MSBuild在哪里找到Wget程序集文件(.dll).这是通过MSBuild的元素完成的:
<!-- Import your custom MSBuild task -->
<UsingTask AssemblyFile="MyCustomMSBuildTasks\Wget\bin\Release\Wget.dll" TaskName="Wget" />
Run Code Online (Sandbox Code Playgroud)
如果你想获得想象力,你甚至可以让你的MSBuild项目在调用之前构建Wget.为此,使用<MSBuild Projects>任务构建解决方案,并使用<UsingTaks AssemblyFile>任务导入它,如下所示:
<!-- Build the custom MSBuild target solution-->
<MSBuild Projects="MyCustomMSBuildTasks\CustomBuildTasks.sln" Properties="Configuration=Release" />
<!-- Import your custom MSBuild task -->
<UsingTask AssemblyFile="MyCustomMSBuildTasks\Wget\bin\Release\Wget.dll" TaskName="Wget" />
<!-- Get the contents of a Url-->
<Wget
Address="http://mywebserver.com/securepage"
LocalFilename="mydownloadedfile.html"
Username="myusername"
Password="mypassword">
</Wget>
Run Code Online (Sandbox Code Playgroud)
如果您之前从未创建过自定义MSBuild目标,那么一旦您了解了基础知识,就不会太困难.查看上面的C#代码,查看官方MSDN文档,并在网上搜索更多示例.一个好的开始是:
MSBuild 15.8及更高版本中提供了DownloadFile任务(自2018年8月14日起)
例:
<PropertyGroup>
<LicenceUrl>https://raw.githubusercontent.com/Microsoft/msbuild/master/LICENSE</LicenceUrl>
</PropertyGroup>
<Target Name="DownloadContentFiles" BeforeTargets="Build">
<DownloadFile
SourceUrl="$(LicenceUrl)"
DestinationFolder="$(MSBuildProjectDirectory)">
<Output TaskParameter="DownloadedFile" ItemName="Content" />
</DownloadFile>
</Target>
Run Code Online (Sandbox Code Playgroud)
有关更多详细信息:DownloadFile任务
| 归档时间: |
|
| 查看次数: |
5132 次 |
| 最近记录: |