Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
 
Project
("{00000000-0000-0000-0000-000000000000}") = "Test Projects", "TestProjects", "{5FAF487E-B913-4D46-983E-CB13FDF36FCB}" 
EndProject
 
Project
("{11111111-1111-1111-1111-111111111111}")= "ProjPropHelperAPI", "ProjPropHelperAPI\ProjPropHelperAPI.vcxproj", "{22222222-2222-2222-2222-222222222222}" 
EndProject 
 
Project
("{33333333-3333-3333-3333-333333333333}") = "ProjectPropertiesHelperAPI", "ProjectPropertiesHelperAPI\ProjectPropertiesHelperAPI.csproj", "{66666666-6666-6666-6666-666666666666}"     
    ProjectSection(ProjectDependencies) = postProject         
    {44444444-4444-4444-4444-444444444444} = {44444444-4444-4444-4444-444444444444}    
    {55555555-5555-5555-5555-555555555555} = {55555555-5555-5555-5555-555555555555}
    EndProjectSection 
EndProject 
 
I can read the Project Names, their GUIDs and Paths using the solution mentioned in this answer. The name, guid and path is accessed using
 
Type.GetType().GetProperty("ProjectGuid", BindingFlags.NonPublic | BindingFlags.Instance); 
 
I need to parse the ProjectDependencies Tab shown in the above .sln extract. I want to know if the ProjectDependencies values can be obtained similar to ProjectName, ProjectGuid and RelativePath properties?
 
P.S. Well, I dont really mind as long as I get the project dependencies, by whatever means (not necessarily by Reflection as shown in the c# snippet above). Any ideas are welcome.
 
Thanks in advance!!
Posted 7-Sep-12 5:49am
aromore427
Edited 7-Sep-12 6:07am
v4
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

There are can be at least two completely different things which may give different results. It depends on what you really need. (It's a good idea to start all questions from explanation of your ultimate purpose.)
 
First one is: you can extract dependency information as it is prescribed in the solution file. This does not reflect real dependency, it only shows what the author of the solution thinks what should depend on what (plus dependencies Visual Studio was able to figure out automatically). This way does not require the projects to be built, and you don't need the target assemblies to be in place. To do it, all you need is just the ability to parse simple data from text (a text of a .SLN file) and apply some logic. You can create few different solutions for samples, to see how the file is structured. Unlike XML-based MSBuild project file format, the format of the .SLN files is not really documented. [EDIT] Even though the .SLN file format is probably not documented, you can use access data not directly, but using the solution document interface EnvDTE80.Solution2; please see Solution 2. [END EDIT]
 
The second thing is: you can build all the solution (so you will need all projects to be buildable) and perform the analysis of dependencies based on the compiled binary assemblies using Reflection. This is a pretty simple thing. Here is what you need:
Load some assembly to be analyzed based on the file name of its main executable module:
http://msdn.microsoft.com/en-us/library/1009fa28.aspx[^].
 
When this is done, obtain all referenced assemblies:
http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getreferencedassemblies.aspx[^].
 
For each referenced assembly, load it using the assembly name object obtained for each referenced assembly on the previous step:
http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.aspx[^].
 
Load each of referenced assemblies by their respective instanced of System.Reflection.AssemblyName:
http://msdn.microsoft.com/en-us/library/x4cw969y.aspx[^].
 
Do it all recursively to produce the whole dependency graph. Easy enough.
 
—SA
  Permalink  
v3
Comments
Espen Harlinn at 7-Sep-12 19:03pm
   
5'ed!
Sergey Alexandrovich Kryukov at 7-Sep-12 19:19pm
   
Thank you, Espen.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Apart from what Sergey mentions, you could look at the
Solution2 interface[^] and the Project interface[^]
 
Controlling Projects and Solutions[^]
 
It's a lot of info to wade through, but what you're looking for is there somewhere.
 
Best regards
Espen Harlinn
  Permalink  
Comments
Sergey Alexandrovich Kryukov at 7-Sep-12 19:24pm
   
Ah, you've fixed my answer where I failed to advise using solution interface. Of course, my 5.
--SA
Espen Harlinn at 8-Sep-12 6:15am
   
Thank you, Sergey :-D
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

If you go parsing the files, you may do the following:
  1. parse the sln file for all Project...ProjectEnd entries
  2. from these entries take the GUID and the path (if it ends on \.\w+proj)
  3. from these entries also take the ProjectSection(ProjectDependencies) = postProject (if it exists and store the contained GUIDs as dependencies)
  4. parse each proj file for <ProjectReference>...</ProjectReference> and take all contained <Project>...</Project> entries as GUID to the dependent project
  5. do a topological sort on the dependencies
 
The steps above respect the fact that Visual Studio may store dependency information at two locations: in the solution and in the project file. It also takes care of the fact that some project entries in the sln file are not real projects (they may be folders and solution items).
 
For the DAG/topological sort, see Directed Acyclic Graphs[^]
 
Cheers
Andi
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

Here is what i did...
 
var filePath = @"C:\Users\xyz\Documents\Visual Studio 2010\Projects\test\test.sln"         
var slnLines = File.ReadAllLines(filePath);      
var projGuid = new List<string>();         
 
for(var i=0; i<slnlines.length;)
{             
    if (slnLines[i].Contains(@"ProjectSection(ProjectDependencies)"))                 
        while (!slnLines[i+1].Contains("EndProjectSection"))
        {                     
            var temp = (slnLines[i+1].Split(new[]{'=', '\n', '\t', ' '},2,StringSplitOptions.RemoveEmptyEntries));
            if(temp.ElementAt(0) == temp.ElementAt(1))
                projGuid.Add(temp.ElementAt(0));
            i++;
        }
}
 
using (var file = new StreamWriter(@"C:\Users\xyz\Desktop\Results.txt"))
{
    foreach (var pGuid in projGuid)
    {
        file.WriteLine(pGuid);
    }
}
 
Thanks!!
  Permalink  
v2
Comments
Andreas Gieriet at 10-Sep-12 14:58pm
   
That will only catch the explicitly set dependencies. There are also dependencies defined within the project files: dependencies by adding a reference to a sibling project of the solution (they do not appear in the above mentioned dependency list).
Cheers
Andi
PS: I did fix some formatting in your code example (replacing the < and > by &lt; and &gt;).
aromore at 10-Sep-12 15:24pm
   
@andreas: Thanks fr the edits!!
 
D u mean the references indicated as <ProjectReference> in the .csproj file?
Andreas Gieriet at 10-Sep-12 16:11pm
   
Yes. See my solution #3. You don't get the overal dependency sequence by simply collecting the individual dependencies - you need to do a topological sort on the collected data (in order to get a build sequence).
E.g. make a solution with 4 csproj files (app, lib, apptest, libtest), include proj references in
- app --> lib
- apptest --> app
- apptest --> lib
- libtest --> lib
Save all.
You will not see any dependency list in the sln file.
If you inspect the dependency list from within VS2010, you will see correct dependencies, and a meaningful build sequence.
Cheers
Andi

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 8,284
1 Sergey Alexandrovich Kryukov 7,327
2 DamithSL 5,614
3 Manas Bhardwaj 4,986
4 Maciej Los 4,920


Advertise | Privacy | Mobile
Web01 | 2.8.1411023.1 | Last Updated 10 Sep 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100