views:

239

answers:

3

I have a software project which consists of multiple Project files and multiple Solution files. The Solution files have a one-to-many relationship with the Project files, and a given Project file may appear in multiple different solution files.

Is there any good/spiffy way to come up with a map of the relationships between the Solution files and the Project files? Either through VS or a utility of some sort.

What I'd like to do is say "hey, in this directory and its subdirectories there are a number of Solution files and Project files - please tell me which Solutions use which Projects and map it out for me"

I realize the net effect could be produced by opening up every Solution file and inspecting it but I'm looking for an automated, repeatable action.

EDIT: I'm afraid I also have Solution/Project combos dating back to VS2003, so I need to map those as well.

A: 

A simple python (perl?) script with a couple of well places regular expressions.
Every project has it's own GUID. finding the mapping is just a matter of finding the GUIDS of the projects and looking them up in the solution files.

shoosh
+1  A: 

Both project files and solution files are text files. Project files don't know about their solution, so we'll have to look in the solutions for their projects.

A project entry in the solution file looks like this:

Project("{9AC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ProjectName", "ProjectDirectory\ProjectFileName.vcproj","{9A95F635-B74F-4640-BBCF-E324D0972CA9}"
EndProject

So you can see, we can grab the project name and the relative path to the project file.

Using your favorite scripting language you could do something like the following. (Example in ruby)

require 'find'

def project_name(string)
  string =~ /= "(.+?)"/
  $1
end

#the script doesn't use this method but you may want it
def project_path(string)
  string =~ /, "(.+?)"/
  $1
end

def find_projects(path)
  puts "#{path} contains the following projects:"
  open(path).read.gsub(/Project\(.+?EndProject/m) do |match|
    puts project_name(match)
  end
  puts ""
end

#change File.dirname(__FILE__)) to the name of the directory you want to search.
Find.find(File.dirname(__FILE__)) do |path|
  if FileTest.directory?(path)
    if File.basename(path) =~ /^\../ # Directory name starts with .
      Find.prune       # Don't look any further into this directory.
    else
      next
    end
  elsif path =~ /\.sln$/
    find_projects(path)
  end
end
Gordon Wilson
+1  A: 

In addition to Gordon Wilson's post, you could try building the same thing in C#, and use QuickGraph and GraphViz to create a diagram showing the same thing.

QuickGraph can be used to create the graph structure in memory and to output a dot file, which Graphviz can load and create a nice looking diagram from. The docs on both sites should give you enough information to go off.

** edit ** See here for a small side project I started that does some of what you wanted. You could probably add anything you need in a few hours at most. Feel free to take it and use it however you want, just leave me a comment if you do please.

Jamie Penney