Anyway, here you are. Specify a VS2005 solution file as the argument via CLI.
using System;using System.Collections.Generic;using System.Text;using System.IO;using System.Xml;class Program { static string Usage = "Usage: LineCountTool <-v|-verbose> SolutionFile.sln"; static bool Verbose = false; static IEnumerable<string> ProjectPaths(string SolutionPath) { if (!File.Exists(SolutionPath)) { Console.WriteLine("File not found: \"{0}\"", SolutionPath); return (new string[0]); } string[] Lines = File.ReadAllLines(SolutionPath); string DirPath = Path.GetDirectoryName(SolutionPath); if (Lines.GetLength(0) <= 1) { Console.WriteLine("File empty: \"{0}\"", SolutionPath); return (new string[0]); } if (Lines[1] != "Microsoft Visual Studio Solution File, Format Version 9.00") { Console.WriteLine("File does not appear to be Solution file (v 9.0)."); return (new string[0]); } string buf = ""; List<string> rtn = new List<string>(); foreach (string Line in Lines) { if (Line.StartsWith("Project")) { buf = Line; buf = buf.Remove(0, buf.IndexOf(',') + 1); buf = buf.Remove(buf.IndexOf(',')); buf = buf.Replace("\"", ""); buf = buf.Trim(); buf = DirPath + Path.DirectorySeparatorChar + buf; rtn.Add(buf); if (Verbose) { Console.WriteLine("Project: {0}", buf); } } } return (rtn); } static IEnumerable<string> CodePaths(string ProjectPath) { if (!File.Exists(ProjectPath)) { Console.WriteLine("File not found: \"{0}\"", ProjectPath); return (new string[0]); } XmlDocument csproj = new XmlDocument(); csproj.Load(ProjectPath); string DirName = Path.GetDirectoryName(ProjectPath); List<string> rtn = new List<string>(); if (Verbose) { Console.WriteLine(); Console.WriteLine("Files From {0}:", ProjectPath); } foreach (XmlNode node in csproj.GetElementsByTagName("Compile")) { foreach (XmlAttribute attrib in node.Attributes) { if (attrib.Name == "Include") { rtn.Add(DirName + Path.DirectorySeparatorChar + attrib.Value); if (Verbose) { Console.WriteLine(rtn[rtn.Count - 1]); } } } } if (Verbose) { Console.WriteLine(); } return (rtn); } static UInt64 LinesOfCode(string CodeFile) { if (!File.Exists(CodeFile)) { Console.WriteLine("File not found: \"{0}\"", CodeFile); return (0); } UInt64 rtn = (UInt64)File.ReadAllLines(CodeFile).GetLength(0); if (Verbose) { Console.WriteLine("Processing {0} ... {1} lines.", CodeFile, rtn); } return (rtn); } static void Main(string[] args) { UInt64 loc = 0; //Verbose = true; //string file = @"C:\src\Csharp-Barrier\Csharp-Barrier.sln"; #region Arg Parsing string file = ""; if (args.GetLength(0) == 0) { Console.WriteLine(Usage); return; } foreach (string arg in args) { if (arg == "-v" || arg == "-verbose") { Verbose = true; } file = args[args.GetLength(0) - 1]; } #endregion foreach (string project in ProjectPaths(file)) { foreach (string code in CodePaths(project)) { loc += LinesOfCode(code); } } if (Verbose) { Console.WriteLine(); } Console.WriteLine("Solution {0} ... {1} lines.", file, loc); }}
and sample verbose output for the current incarnation of moe:
// *snip*Processing c:\src\Csharp-moeClient2\..\Csharp-BaseSound\Csharp-BaseSound\BaseSound.cs ... 410 lines.Processing c:\src\Csharp-moeClient2\..\Csharp-BaseSound\Csharp-BaseSound\Properties\AssemblyInfo.cs ... 35 lines.Files From c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\Csharp-SoundSceneObject.csproj:c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\SoundSceneObject.csc:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\Properties\AssemblyInfo.csProcessing c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\SoundSceneObject.cs ... 75 lines.Processing c:\src\Csharp-moeClient2\..\Csharp-SoundSceneObject\Csharp-SoundSceneObject\Properties\AssemblyInfo.cs ... 35 lines.Solution c:\src\Csharp-moeClient2\Csharp-moeClient2.sln ... 17501 lines.
(17500 lines? and ~5000 of those are fmod and a good percentage of the rest are comments/includes/whitespace? Pitiful!)
[edit: oh, and it's my first time ever dealing with xml, so you'll forgive me if there's a quicker/cleaner way to pickout the Compile Include="" bits...]