156

I'm currently migrating a big solution (~70 projects) from VS 2005 + .NET 2.0 to VS 2008 + .NET 3.5. Currently I have VS 2008 + .NET 2.0.

The problem is that I need to move projects one by one to new .NET framework ensuring that no .NET 2.0 project references .NET 3.5 project. Is there any tool that would give me a nice graph of project dependencies?

GregD
  • 6,860
  • 5
  • 34
  • 61
Migol
  • 8,161
  • 8
  • 47
  • 69

17 Answers17

194

I needed something similar, but didn't want to pay for (or install) a tool to do it. I created a quick PowerShell script that goes through the project references and spits them out in a yuml.me friendly-format instead:

Function Get-ProjectReferences ($rootFolder)
{
    $projectFiles = Get-ChildItem $rootFolder -Filter *.csproj -Recurse
    $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }

    $projectFiles | ForEach-Object {
        $projectFile = $_ | Select-Object -ExpandProperty FullName
        $projectName = $_ | Select-Object -ExpandProperty BaseName
        $projectXml = [xml](Get-Content $projectFile)

        $projectReferences = $projectXml | Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Name' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text"

        $projectReferences | ForEach-Object {
            "[" + $projectName + "] -> [" + $_ + "]"
        }
    }
}

Get-ProjectReferences "C:\Users\DanTup\Documents\MyProject" | Out-File "C:\Users\DanTup\Documents\MyProject\References.txt"
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Danny Tuppeny
  • 40,147
  • 24
  • 151
  • 275
  • 5
    awesome. I took this and extended it to go through all sub projects, then extended it again to take a sln file instead to map the whole project. Thanks – Jon Mar 27 '13 at 17:03
  • What versions of Visual Studio does this work with ? Also, to visualize C++ instead of C# projects, is it enough to change the .csproj file suffix to .vcproj ? Working with VS 2005 here and I get an empty result file... – ssc May 10 '13 at 14:32
  • 1
    It was written against a 2010 project for C#, but you could probably tweak it really easily by looking at the XML inside a C++ project and adjusting the code :-) – Danny Tuppeny May 11 '13 at 10:24
  • 6
    @ssc There's slightly updated code posted on my blog that might be easier to tweak: http://blog.dantup.com/2012/05/free-dependency-graph-generation-using-powershell-and-yuml – Danny Tuppeny May 11 '13 at 10:25
  • 5
    If you're using Powershell 2.0 you will need to append `=$true` to the `Mandatory` and `ValueFromPipeline` parameters – MoMo Mar 18 '14 at 18:00
  • Your script works fine but only if all projects under a root folder, in your case Myproject. I have structure as my library projects arent under the website root folder. how can i define or relate a second folder? I cant figure it out – Emil Oct 26 '16 at 10:18
  • @batmaci What fails? Is it that in some places of the output you end up with relative paths and others not? If so, you might just need to do some manipulation (`Split-Path -Leaf`?) on the paths before outputting. – Danny Tuppeny Nov 06 '16 at 12:20
  • @Jon would've been nice if you post it as answer to help the community back – sm_ Feb 06 '17 at 06:30
  • 1
    @SirajMansour I already had, see http://stackoverflow.com/a/25995787/6486 – Jon Feb 07 '17 at 10:54
  • can you enhance that to analyse an entire sln file? – Tobias Knauss Jun 29 '17 at 09:37
93

Update: ReSharper since version 8 has built-in 'View Project Dependencies' feature.

ReSharper version prior to 8 has Internal feature to show dependency graphs in using yFiles viewer. See quick manual in the bottom of the post.

enter image description here

Howto

  1. Install yEd tool from here.
  2. Run VS with /resharper.internal command line argument.
  3. Go to ReSharper/Internal/Show Dependencies.
  4. Specify projects that you want to include to the 'big picture'.
  5. Uncheck 'Exclude terminal nodes...' unless you need it.
  6. Press 'Show'.
  7. Use hierarchical layout in yEd (Alt+Shift+H)
  8. Provide feedback =)
Mark Schultheiss
  • 32,614
  • 12
  • 69
  • 100
Shkredov S.
  • 2,097
  • 16
  • 8
51

Have you tried NDepend? It'll shows you the dependencies and you can also analyze the usability of your classes and methods.

Their website:

http://ndepend.com

Eriawan Kusumawardhono
  • 4,796
  • 4
  • 46
  • 49
  • 4
    original poster didn't say ndepend was free and it solves the problem. – krystan honour Jun 02 '17 at 11:02
  • 7
    It may have been free at the time of writing this answer, but now it's not. – Levente Koncz Jan 07 '20 at 15:07
  • 1
    @patrick-from-ndepend-team please don't directly edit my answer and open a new answer instead. – Eriawan Kusumawardhono Apr 29 '20 at 04:16
  • Ok @EriawanKusumawardhono sorry if it is a problem for you. This way readers get more details straight and this improves the answer usefulness, do you want I remove the extra details and screenshots? – Patrick from NDepend team Apr 29 '20 at 08:54
  • 3
    @PatrickfromNDependteam the extra details and screenshots are OK. but since this is originally my answer, it looks like your edit somehow makes me I look like work at NDepend. Please add new answer with your edit, and also emphasize your new answer is addition to my answer. Thanks before :) – Eriawan Kusumawardhono Jun 16 '20 at 07:47
  • @EriawanKusumawardhono I start the edit with "To complete the Eriawan answer..." and finish with "...Disclaimer: I work at NDepend" what else would you like? thanks :) – Patrick from NDepend team Jun 17 '20 at 09:02
  • Too much of a coincidence I get here researching for a problem with NopCommerce, but without using nopcommerce as keyword, and you use NopCommerce as example... – Pablo Recalde Jun 29 '21 at 15:26
  • @EriawanKusumawardhono your images are copied here: https://newbedev.com/dependency-graph-of-visual-studio-projects – Mark Schultheiss Dec 01 '21 at 22:37
  • 3
    Interesting seeing commercial parties like NDepend hijacking highly voted answers to plug their products. Surprised that StackOverflow allows this kind of thing. – andrerav Mar 25 '22 at 15:19
  • @andrerav Other answers propose screenshots but not this one. Since dependency graph is a visual thing by essence we added an NDepend picture on an answer that already mentioned NDepend exclusively with explanations that we are working on the product and that the picture can help visualize "Dependency graph of Visual Studio projects" the reader can obtain. This is the whole point of this Q/A what kind of graph one can obtain to visualize .NET projects. Sorry you see this as "hijacking" an answer, this doesn't reflect our intent. – Patrick from NDepend team Jun 16 '22 at 15:21
43

Made the powershell scripts .etc. posted here into a dotnet tool.

Try DependenSee

to install

  • Make sure you have dotnet 5 runtime installed

  • Make sure you have dotnet 6 runtime installed

  • run dotnet tool install dependensee --global

  • once installed, run dependensee "path/to/root/of/csproj/files" "path/to/output.html"

  • By default it doesn't include nuget packages, but can be enabled with -P switch

  • to see all options, run dependensee with no args.

HTML output looks like this

DependenSee Graph

For Continuous Integration Scenarios

There are command line options allowing you to output XML or JSON for further processing, either writing them to a file or writing to Standard Output allowing to pipe the output to other command line tools without touching the filesystem if necessary.

Madushan
  • 6,977
  • 31
  • 79
  • 2
    Nice tool, simple to use and works in an instant. Only problem is that for solutions with "wilder" project dependencies, the graph can become quite confusing, and in some places the arrows are so close to each other that they are indistinguishable – TostMaster Mar 08 '21 at 07:35
  • 3
    This is by far the simplest and best actual solution if you just want to see project dependencies, which was my case. Good job! – LoRdPMN Mar 09 '21 at 13:48
  • This is awesome. Thank you! – Jéf Bueno Nov 19 '21 at 12:44
  • 1
    I used it on a 109-project framework 4.8 sln with good results. Interactive HTML is very nice. – cskwg Feb 28 '22 at 09:51
32

You can get a project dependency graph easily using Visual Studio 2010 Ultimate, scan to 5 minutes into this video to see how: http://www.lovettsoftware.com/blogengine.net/post/2010/05/27/Architecture-Explorer.aspx

In Visual Studio 2010 Ultimate: Architecture | Generate Dependency Graph | By Assembly.

Richard
  • 106,783
  • 21
  • 203
  • 265
Chris Lovett
  • 245
  • 3
  • 2
  • @CJohnson You can do this for C and C++ code if you have [Visual Studio 2010 Feature Pack 2](http://msdn.microsoft.com/en-US/vstudio/ff655021.aspx). See also [How to: Generate Dependency Graphs for C and C++ Code](http://msdn.microsoft.com/en-us/library/vstudio/ff657798(v=vs.100).aspx) – Esther Fan - MSFT Mar 18 '13 at 20:04
  • 1
    Tried it, threw an exception. Apparently MS never tested it with anything beyond a few projects. Absolutely worthless in my opinion. – C.J. Jun 03 '13 at 09:15
  • 1
    Not only that, it's horribly slow too. I'd make this -10 if I could. I wrote my own project dependency walker (For our own build system) and it was lightning fast compared to the one in visual studio. – C.J. Jun 03 '13 at 09:20
  • @CJohnson I agree that it's slow and prone to throwing exceptions for large solutions, but it's still better than nothing. I got it to work by closing all applications, stopping some services and restarting Visual Studio. – WynandB Aug 21 '13 at 07:59
  • Large solutions for me is around 600 projects with millions of lines of code. No chance that stopping a few services is an acceptable work-around for me. – C.J. Sep 02 '13 at 11:52
  • 3
    The blog link is 404. Does the article still exist anywhere else? – ChrisW Feb 17 '21 at 10:01
23

I wrote a tool that might help you. VS Solution Dependency Visualizer analyzes project dependencies within a solution and create a dependency chart from this information, as well as a text report.

devio
  • 36,858
  • 7
  • 80
  • 143
  • What versions of Visual Studio and what kind of projects does this work with ? VS 2005 / C++ over here and the tool doesn't seem to do anything... – ssc May 10 '13 at 14:42
  • it definitely works with vs 2008/2010 and .csproj/.vbproj. didn't test with vs2005, but currently .vcproj files are not recognized – devio May 10 '13 at 17:14
  • This tool shows only the solution file after analyzing it :-(. Not my about 300 projects. – thersch Aug 02 '17 at 12:44
  • @thersch if you want me to have a look at it, please zip .sln and project files (so that the original directory structure is preserved), upload it on a file share, and contact me via my blog. thx – devio Aug 03 '17 at 06:08
9

I had a similar issue, but it was further complicated because several projects were referencing different versions of the same assembly.

To get an output that includes version information and checks for possible runtime assembly loading issues, I made this tool:

https://github.com/smpickett/DependencyViewer

(direct link to github release: https://github.com/smpickett/DependencyViewer/releases)

Pickett
  • 91
  • 1
  • 4
8

You can create a dependency graph of your projects in VS 2010 Ultimate. Architecture Explorer lets you browse your solution, select projects and the relationships that you want to visualize, and then create a dependency graph from your selection.

For more info, see the following topics:

How to: Generate Graph Documents from Code: http://msdn.microsoft.com/en-us/library/dd409453%28VS.100%29.aspx#SeeSpecificSource

How to: Find Code Using Architecture Explorer: http://msdn.microsoft.com/en-us/library/dd409431%28VS.100%29.aspx

RC download: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=457bab91-5eb2-4b36-b0f4-d6f34683c62a.

Visual Studio 2010 Architectural Discovery & Modeling Tools forum: http://social.msdn.microsoft.com/Forums/en-US/vsarch/threads

Esther Fan - MSFT
  • 8,276
  • 4
  • 27
  • 25
5

The Powershell solution is the best. I adapted it into a bash script that works on my machine (TM):

#!/bin/bash

for i in `find . -type f -iname "*.csproj"`; do
    # get only filename
    project=`basename $i`

    # remove csproj extension
    project=${project%.csproj}

    references=`cat $i | grep '<ProjectReference' | cut -d "\"" -f 2`
    for ref in $references; do
        # keep only filename (assume Windows paths)
        ref=${ref##*\\}

        # remove csproj extension
        ref=${ref%.csproj}

        echo "[ $project ] -> [ $ref ]"
    done

done
Community
  • 1
  • 1
Nikolaos Georgiou
  • 2,792
  • 1
  • 26
  • 32
5

To complete the eriawan answer on graphs generated by NDepend see screenshoots below. You can download and use the free trial edition of NDepend for a while.

More on NDepend Dependency Graph NDepend Dependency Graph

More on NDepend Dependency Matrix: NDepend Dependency Structure Matrix

Disclaimer: I am part of the tool team

Patrick from NDepend team
  • 13,237
  • 6
  • 61
  • 92
4

You can create a nice graph of the references in your projects. I've described the way I did it on my blog http://www.mellekoning.nl/index.php/2010/03/11/project-references-in-ddd/

Hace
  • 1,421
  • 12
  • 17
  • All you need to do is change the output to DGML for display inside VS: http://blogs.msdn.com/b/camerons/archive/2008/12/16/introduction-to-directed-graph-markup-language-dgml.aspx – Richard Sep 06 '10 at 15:10
3

If you simply want a dependency graph I've found this is one of the cleanest ways to get one:

Dependency Analyser

Kieran Benton
  • 8,739
  • 12
  • 53
  • 77
3

VS 2019 has renamed dependency graph module to Code Map

here is official documentation : https://learn.microsoft.com/en-us/visualstudio/modeling/map-dependencies-across-your-solutions?view=vs-2019

Steven J
  • 316
  • 2
  • 14
  • 4
    "To create and edit code maps, you need Visual Studio Enterprise edition. In Visual Studio Community and Professional editions, you can open diagrams that were generated in Enterprise edition, but you cannot edit them." – MatthewT Jul 25 '20 at 01:17
3

If you're looking for a way that doesn't require any external tools, you can navigate to a project's obj/project.assets.json file. This file is generated during build, and has a hierarchical JSON structure of the dependencies (both project references and nuget packages).

It's useful for answering questions like "why the hell is this project DLL being pulled into the build directory?"

Will
  • 2,086
  • 23
  • 30
2

I've checked all the answers but none of the options were satisfying to me so I wrote my own tool to preview project-project dependencies.

https://github.com/Audionysos/VSProjectReferencesViewer

It's early stage but it worked for my needs :)

1

This extended version of the PS Script from Danny Tuppeny shows both Project and External references:

Function Get-ProjectReferences($rootPath)
{
  $projectFiles = Get-ChildItem $rootPath -Filter *.csproj -Recurse
  $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }

  $projectFiles | ForEach-Object {
    $projectFile = $_ | Select-Object -ExpandProperty FullName
    $projectName = $_ | Select-Object -ExpandProperty BaseName
    $projectXml = [xml](Get-Content $projectFile)

    $projectReferences = $projectXml | Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Name' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text"
    $projectReferences | ForEach-Object {
        "PR:[" + $projectName + "]:[" + $_ + "]"
    }
  }

  $projectFiles | ForEach-Object {
    $projectFile = $_ | Select-Object -ExpandProperty FullName
    $projectName = $_ | Select-Object -ExpandProperty BaseName
    $projectXml = [xml](Get-Content $projectFile)

    $externalReferences = $projectXml | Select-Xml '//defaultNamespace:Reference/@Include' -Namespace $ns
    $externalReferences | ForEach-Object {
        "ER:[" + $projectName + "]:[" + $_ + "]"
    }

  }

}

Get-ProjectReferences "C:\projects" | Out-File "C:\temp\References.txt"

It will give a colon-separated file that can be opened and analysed in Excel.

Svein Terje Gaup
  • 1,424
  • 15
  • 29
1

This extended version of the PS Script from Danny Tuppeny shows references for both csproj and vcxproj files, and also supports

-Depth - maximum dependency chain length

-Like - prints only dependency chains starting with projects with name -like $Like

-UntilLike - cuts dependency chains on projects with name -like $UntilLike

-Reverse - prints reversed dependency chains ([proj] <- [referencing proj])

[CmdletBinding()]
param (
    [Parameter(Mandatory=$false)]
    [string]$RootFolder = ".",
    [Parameter(Mandatory=$false)]
    [string]$Like = "*",
    [Parameter(Mandatory=$false)]
    [string]$UntilLike = "*",
    [Parameter(Mandatory=$false)]
    [switch]$Reverse,
    [Parameter(Mandatory=$false)]
    [int]$Depth=1
)

$arrow = if ($script:Reverse) { "<-" } else { "->" }

Function PrintTree ($projectNameToProjectNameList, $projectName, $maxDepth = 1, $prefix = "")
{
    $print = $script:UntilLike -eq "*" -or $projectName -Like $script:UntilLike
    $stop = $projectNameToProjectNameList[$projectName].count -eq 0 -or $maxDepth -eq 0 -or ($script:UntilLike -ne "*" -and $projectName -Like $script:UntilLike)
    
    if ($stop) {
        if ($print) {
            $prefix + "[$projectName]"
        }
    } else {
        $prefix += "[$projectName] $arrow "
        --$maxDepth
        $projectNameToProjectNameList[$projectName] | % { PrintTree $projectNameToProjectNameList $_ $maxDepth $prefix }
    }
}

Function Get-ProjectReferences ($rootFolder)
{
    $projectFiles = Get-ChildItem $rootFolder -Filter *.csproj -Recurse
    $projectFiles += Get-ChildItem $rootFolder -Filter *.vcxproj -Recurse
    $ns = @{ defaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003" }
    
    $projectGuidToProjectName = @{}
    $projectNameToProjectReferenceGuidList = @{}

    $projectFiles | ForEach-Object {
        $projectFile = $_ | Select-Object -ExpandProperty FullName
        $projectName = $_ | Select-Object -ExpandProperty BaseName
        $projectXml = [xml](Get-Content $projectFile)
        
        $projectGuid = $projectXml | Select-Xml '//defaultNamespace:ProjectGuid' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text" | % { $_ -as [Guid] }
        $projectGuidToProjectName[$projectGuid] = $projectName

        $projectReferenceGuids = $projectXml | Select-Xml '//defaultNamespace:ProjectReference/defaultNamespace:Project' -Namespace $ns | Select-Object -ExpandProperty Node | Select-Object -ExpandProperty "#text" | % { $_ -as [Guid] }
        if ($null -eq $projectReferenceGuids) { $projectReferenceGuids = @() }
        $projectNameToProjectReferenceGuidList[$projectName] = $projectReferenceGuids
    }

    $projectNameToProjectReferenceNameList = @{}
    foreach ($projectName in $projectNameToProjectReferenceGuidList.keys) {
        $projectNameToProjectReferenceNameList[$projectName] = $projectNameToProjectReferenceGuidList[$projectName] | % { $projectGuidToProjectName[$_] } | sort
    }
    
    if ($script:Reverse) {
        $projectReferenceNameToProjectNameList = @{}
        foreach ($projectName in $projectNameToProjectReferenceNameList.keys) {
            foreach ($projectReferenceName in $projectNameToProjectReferenceNameList[$projectName]) {
                if (!$projectReferenceNameToProjectNameList.ContainsKey($projectReferenceName)) { $projectReferenceNameToProjectNameList[$projectReferenceName] = @() } 
                $projectReferenceNameToProjectNameList[$projectReferenceName] += $projectName
            }
        }

        foreach ($projectName in $projectReferenceNameToProjectNameList.keys -Like $script:Like) {
            PrintTree $projectReferenceNameToProjectNameList $projectName $script:Depth
        }
    } else {
        foreach ($projectName in $projectNameToProjectReferenceNameList.keys -Like $script:Like) {
            PrintTree $projectNameToProjectReferenceNameList $projectName $script:Depth
        }
    }
}

Get-ProjectReferences $RootFolder
Ilyan
  • 175
  • 6
  • BTW this doesn't work if you start in a directory with one csproj file! Can be fixed using $projectFiles = @() $projectFiles += Get-ChildItem $rootFolder -Filter *.csproj -Recurse Though it still doesn't actually print a full tree of dependencies the way I was expecting it to. – Dylan Nicholson Jun 26 '23 at 22:11