Jump to content
  • entries
  • comments
  • views

Holy Tool Batman!

Sign in to follow this  


I know this probably isn't very impressive, but I have some source to a little utility I'd like to share. I've been itching a little bit for a nice automated way to do line counts for an entire VS solution. Sure, line counts are silly, and it's hard to determine what's an actual line of code (as opposed to line of comment or whitespace)... but I don't care about that. I'm just looking for something to do that I can do and get done. If it helps me better half-assedly judge my progress, great. ~90 minutes later and it's done-ish.

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;
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();

string DirName = Path.GetDirectoryName(ProjectPath);
List<string> rtn = new List<string>();

if (Verbose) {
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) {

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) {

foreach (string arg in args) {
if (arg == "-v" || arg == "-verbose") {
Verbose = true;

file = args[args.GetLength(0) - 1];


foreach (string project in ProjectPaths(file)) {
foreach (string code in CodePaths(project)) {
loc += LinesOfCode(code);
if (Verbose) {
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:

Processing 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...]
Sign in to follow this  


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!