Skip to content

Instantly share code, notes, and snippets.

@rkttu
Created August 15, 2016 11:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rkttu/7691068b5d16118aff7c86cf6690f3de to your computer and use it in GitHub Desktop.
Save rkttu/7691068b5d16118aff7c86cf6690f3de to your computer and use it in GitHub Desktop.
Visual Studio Prerequisites Bootstrap Package Downloader
<Query Kind="Program" />
// https://msdn.microsoft.com/en-us/library/hh873130%28v=vs.140%29.aspx
void Main()
{
MyWebClient webClient = new MyWebClient();
string baseDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "bootstrapDownloads");
if (!Directory.Exists(baseDir)) Directory.CreateDirectory(baseDir);
Console.WriteLine("Download Directory: {0}", baseDir);
string targetDir = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
@"Microsoft Visual Studio 14.0\SDK\Bootstrapper\Packages");
foreach (string eachProductDir in Directory.GetDirectories(targetDir))
{
string productDir = Path.Combine(baseDir, Path.GetFileName(eachProductDir));
if (!Directory.Exists(productDir)) Directory.CreateDirectory(productDir);
string eachProductXmlFilePath = Path.Combine(eachProductDir, "Product.xml");
if (!File.Exists(eachProductXmlFilePath)) continue;
XmlDocument productDoc = new XmlDocument();
productDoc.Load(eachProductXmlFilePath);
XmlNode productCodeNode = productDoc.DocumentElement.Attributes["ProductCode"];
if (productCodeNode == null) continue;
Console.WriteLine("Current Product: " + productCodeNode.Value);
foreach (string eachProductSubDir in Directory.GetDirectories(eachProductDir))
{
string productSubDir = Path.Combine(productDir, Path.GetFileName(eachProductSubDir));
if (!Directory.Exists(productSubDir)) Directory.CreateDirectory(productSubDir);
string eachPackageXmlFilePath = Path.Combine(eachProductSubDir, "Package.xml");
if (!File.Exists(eachPackageXmlFilePath)) continue;
XmlDocument packageDoc = new XmlDocument();
packageDoc.Load(eachPackageXmlFilePath);
XmlNamespaceManager nsManager = new XmlNamespaceManager(packageDoc.NameTable);
nsManager.AddNamespace("bootstrapper", "http://schemas.microsoft.com/developer/2004/01/bootstrapper");
XmlNodeList nodes = packageDoc.SelectNodes("/bootstrapper:Package/bootstrapper:Strings/bootstrapper:String", nsManager);
if (nodes == null || nodes.Count < 1) continue;
foreach (XmlNode eachNode in nodes)
{
XmlNode nameNode = eachNode.Attributes["Name"];
if (nameNode == null || String.IsNullOrWhiteSpace(nameNode.Value)) continue;
Uri temp;
if (!Uri.TryCreate(eachNode.InnerText, UriKind.Absolute, out temp)) continue;
string filePath = null;
string url = eachNode.InnerText;
Exception throwedException = null;
try
{
webClient.DownloadData(url);
Uri tempUri = webClient.ResponseUri;
url = tempUri.AbsoluteUri;
string fileName = Path.GetFileName(tempUri.GetComponents(UriComponents.Path, UriFormat.SafeUnescaped));
filePath = Path.Combine(productSubDir, fileName);
filePath.Dump();
}
catch (Exception ex)
{
throwedException = ex;
}
Console.WriteLine("* {0}: {1} -> {2}", throwedException == null ? "SUCCEED" : "FAILED", url, filePath);
if (throwedException != null) Console.WriteLine(throwedException.Message);
}
}
}
}
// http://stackoverflow.com/questions/690587/using-webclient-in-c-sharp-is-there-a-way-to-get-the-url-of-a-site-after-being-r
class MyWebClient : System.Net.WebClient
{
Uri _responseUri;
public Uri ResponseUri
{
get { return _responseUri; }
}
protected override WebResponse GetWebResponse(WebRequest request)
{
WebResponse response = base.GetWebResponse(request);
_responseUri = response.ResponseUri;
return response;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment