所以,我有一个下载文件的Powershell脚本,例如
$mech = new-object System.Net.WebClient
$mech.DownloadFile('http://www.example.com/folder./index.html', 'out.html')
Note the trailing dot here ^
哪个不起作用(给出404),查看发送的实际请求,结果发现尾随点被取出,这似乎源于此错误:https://connect.microsoft.com/VisualStudio/feedback/details/386695/
这似乎在.Net的某些版本中得到修复,但Powershell不使用这些版本(我在Win7中使用PS2.0,它使用.Net 2.0.50727.5472,也在PS3中尝试过.0使用的是.Net 4.0.30319.17929,两者都没有打补丁.Net 4.5。安装了一些东西)
所以,这可能是一个简单的问题,但是,上面的链接中列出了一个解决方法,我将如何在Powershell中应用它?
或者,如何让Powershell使用.Net的修补版本(哪些版本已修补?)
我宁愿不使用像wget这样的外部程序,否则我不能在Powershell中写这个,但是如果必须的话,它需要在url中支持UTF8
此外,服务器对此不满意。替换为%2e
答案 0 :(得分:0)
如何采用低级方法并将WinInet与P/Invoke一起使用? P / Invoke的介绍在MSDN。使用.Net类的工作要多得多。
另一种替代方法可能是使用第三方工具包,例如cURL。 Libcurl有一个.Net包装器,因此在Powershell中使用它应该比P / Invoke方式更容易。
答案 1 :(得分:0)
好吧,以防万一其他人需要解决方案,这是一个虽然我不能确切地说这是一个优雅的解决方案,但它仍然是一个。事实证明,您可以将C#直接推送到PS版本的PS> = 3.0
中$source = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Net;
public class FixedWebClient
{
public static System.Net.WebClient NewWebClient()
{
MethodInfo getSyntax = typeof(UriParser).GetMethod("GetSyntax", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
FieldInfo flagsField = typeof(UriParser).GetField("m_Flags", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
if (getSyntax != null && flagsField != null)
{
foreach (string scheme in new[] { "http", "https" })
{
UriParser parser = (UriParser)getSyntax.Invoke(null, new object[] { scheme });
if (parser != null)
{
int flagsValue = (int)flagsField.GetValue(parser);
// Clear the CanonicalizeAsFilePath attribute
if ((flagsValue & 0x1000000) != 0)
flagsField.SetValue(parser, flagsValue & ~0x1000000);
}
}
}
return new System.Net.WebClient();
}
}
"@
#Remove-TypeData 'FixedWebClient'
Add-Type -TypeDefinition $source
$mech = [FixedWebClient]::NewWebClient()
$mech.DownloadFile('http://www.example.com/folder./index.html', 'out.html')
我不确定效果的范围是使用这样的方法,所以我在其中创建WebClient对象以防万一,如果有更多PS / .Net经验的人可以澄清,那就太好了(这是我的第一个PS脚本,我使用Perl,但看到我更像是一个Windows家伙,我想我也可以学习一些PS。)
如果有人将其翻译成纯PS也会很好,因为看看它是如何工作会很有趣......