Created
December 22, 2013 03:36
-
-
Save SLaks/8078184 to your computer and use it in GitHub Desktop.
Parses PDBs from http://referencesource.microsoft.com/netframework.aspx and extracts source files to findable locations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//const string OriginalPath = @"C:\Users\SSL\Development\RefSrc\Source"; | |
const string PDBPath = @"C:\Users\SSL\Development\Symbols\RefSrc\Symbols"; | |
const string OriginalPath = @"C:\Users\SSL\Development\Symbols\RefSrc\Source\.NET 4.5\4.6.0.0"; | |
const string TargetPath = @"C:\Users\SSL\Development\3rd-Party Source\Microsoft\.Net 4.5.1"; | |
const string ErrorLog = TargetPath + @"\Errors.log"; | |
static readonly Regex GoodLine = new Regex(@"^[a-zA-Z0-9\\:]{5}"); | |
void Main() { | |
var pdbs = from file in Directory.EnumerateFiles(PDBPath, "*.pdb", SearchOption.AllDirectories) | |
group file by Path.GetFileName(file) into g | |
select g.OrderByDescending(p => new FileInfo(p).Length).First(); | |
var basePath = Path.Combine(OriginalPath, @"net"); | |
foreach(var pdb in pdbs) { | |
var assemblyName = Regex.Replace(Path.GetFileNameWithoutExtension(pdb), @"(^|\.)[a-z]", m => m.Value.ToUpper()) | |
.Replace("Durableinstancing", "DurableInstancing") | |
.Replace("Presentationframework", "PresentationFramework") | |
.Replace("Servicemodel", "ServiceModel"); | |
var assemblyTarget = Path.Combine(TargetPath, assemblyName); | |
Directory.CreateDirectory(assemblyTarget); | |
var log = Path.Combine(assemblyTarget, "Errors.log"); | |
foreach(var line in File.ReadLines(pdb)) { | |
if (line.Length < 3 || line[0] == '\0' || line[1] != ':') continue; | |
if (!GoodLine.IsMatch(line)) { | |
Console.WriteLine(line); | |
continue; | |
} | |
try { | |
//f:\dd\ndp\fx\src\SystemNet\Net\PeerToPeer\Cloud.cs*DEVDIV_TFS*/Dev10/Releases/RTMRel/ndp/fx/src/SystemNet/Net/PeerToPeer/Cloud.cs*1305376 | |
//f:\dd\ndp\clr\src\BCL\System\ValueType.cs*DEVDIV_TFS2*/DevDiv/D11Rel/FX45RTMRel/ndp/clr/src/BCL/System/ValueType.cs*597531 | |
var segments = line.Split('*'); | |
var fileName = Path.GetFileName(segments[2]); | |
var originalFile = Path.Combine(basePath, segments[0].Replace(@"f:\dd\ndp\", "").Replace(@"f:\dd\wpf\", ""), segments[3], fileName); | |
var dir = Path.Combine(assemblyTarget, (GetNamespace(originalFile) ?? "Unknown").Replace('.', '\\')); | |
Directory.CreateDirectory(dir); | |
var target = Path.Combine(dir, fileName); | |
if (!File.Exists(target)) | |
File.Copy(originalFile, target); | |
else | |
File.AppendAllText(log, "Existing file: " + target + "\t" + fileName + Environment.NewLine); | |
} catch (Exception ex) { | |
File.AppendAllText(log, @" | |
------------------------------------ | |
------------------------------------ | |
ERROR: | |
PDB: " + assemblyName + @" | |
Line: " + line + @" | |
Exception: | |
" + ex.ToString()); | |
} | |
} | |
} | |
} | |
static void CopyFlat() { //Ignores assemblies | |
foreach (var originalFile in Directory.EnumerateFiles(OriginalPath, "*", SearchOption.AllDirectories)) { | |
var fileName = Path.GetFileName(originalFile); | |
var dir = Path.Combine(TargetPath, (GetNamespace(originalFile) ?? "Unknown").Replace('.', '\\')); | |
Directory.CreateDirectory(dir); | |
var target = Path.Combine(dir, fileName); | |
if (!File.Exists(target)) | |
File.Copy(originalFile, target); | |
else | |
File.AppendAllText(ErrorLog, "Existing file: " + target + "\t" + fileName + Environment.NewLine); | |
} | |
} | |
static string FindLine(string file, Func<string, bool> matches) | |
{ | |
return File.ReadLines(file).FirstOrDefault(matches); | |
} | |
static string GetNamespace(string filePath) { | |
var fileName = Path.GetFileName(filePath); | |
switch (Path.GetExtension(filePath)) | |
{ | |
case ".vb": { | |
var nsLine = FindLine(filePath, s => s.StartsWith("Namespace ")); | |
if (nsLine == null) | |
return null; | |
else | |
return nsLine.Substring("Namespace ".Length).Trim(); | |
} | |
break; | |
case ".cs": { | |
var nsLine = FindLine(filePath, s => s.StartsWith("namespace ")); | |
if (nsLine == null) | |
return null; | |
else | |
return nsLine.Substring("namespace ".Length).Trim().TrimEnd('{',' ','\t').Trim(); | |
//var nsIndex = content.IndexOf(nsText); | |
//if (nsIndex == -1) | |
//{ | |
// var nst = "namespace "; | |
// nsIndex = content.IndexOf(nst); | |
// if (nsIndex >= 0) | |
// { | |
// var ns = content.Substring(nsIndex + nst.Length, content.IndexOf(Environment.NewLine, nsIndex) - (nsIndex + nst.Length)).Replace("{", "").Trim(); | |
// dir = Path.Combine(basePath, ns.Replace('.', '\\')); | |
// } | |
// else | |
// dir = Path.Combine(basePath, "Unknown"); | |
//} | |
//else | |
//{ | |
// var ns = content.Substring(nsIndex + nsText.Length, content.IndexOf(Environment.NewLine, nsIndex + 2) - (nsIndex + nsText.Length)).Replace("{", "").Trim(); | |
// dir = Path.Combine(basePath, ns.Replace('.', '\\')); | |
//} | |
} break; | |
} | |
return null; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment