|
|
Comments and Discussions
|
|
 |

|
I'm getting the following error when trying to run this code. All the permisssions to the Temp folder seems OK. I also see the .dot file being created.
Errror: : The system cannot find the specified file
Line :Process.Start(progFilePath+@"\Graphviz2.28\bin\dotty.exe", filename);
|
|
|
|

|
Graphviz2.28 should be installed in the same disk partition as WINDOWS.
|
|
|
|

|
how can u search for value in a grid......Plz anybody help me
|
|
|
|

|
This is really good article. In a couple of weeks I will use it in one of my projects.
|
|
|
|

|
I wrote a javascript thingy that parses a solution file and creates a graph with the dot tool from the graphviz suite; here it is:
/*****************************************************************************
* 2011 SES
*****************************************************************************/
///////////////////////////////////////////////////////////////////////////////
/** @file
* @brief Parse a solution file and create a project depencency graph using dot.
*
* This script parses a Microsoft Visual Studio solution file and draws
* project depencency graphs from it. It uses the dot tool of the graphviz
* application to render the graph.
*
* @param solution
* Microsoft Visual Studio solution file (*.sln).
* @param in
* Include filter. If the project file name contains this string its dependencies
* are evaluated. Multiple file filter must be separated by semicolons.
* Filters are case sensitive.
* @param out
* Exclude filter. If the project file name contains this string its dependencies
* are not evaluated. Multiple file filter must be separated by semicolons.
* Filters are case sensitive.
* @param format
* Output file format. Default 'png'. This option is passed to the dot application.
* Supported formats are ps, png, gif and svg. See the documentation on the dot program.
* The extension of the output file is made equal to the format.
* @param keep
* If specified, the .dot file is not destroyed after the dot tool has been run.
* @param dot
* Full name of the dot application that creates the graph. Optional.
*
* @example
* cscript //nologo //E:jscript project-dependencies.js /solution:"test.sln"
* cscript //nologo //E:jscript project-dependencies.js /solution:test.sln /in:"\lib\;MyProject" /out:Test /keep
*
* @author Skolnik
* @date January 18 2011
*
* References:
* http://www.graphviz.org/Documentation.php
* http://www.graphviz.org/doc/info/attrs.html
* www.graphviz.org/Documentation/dotguide.pdf
* http://unicode.org/faq/utf_bom.html#bom4
*/
///////////////////////////////////////////////////////////////////////////////
var g_solutionFile = ""; // arg 'solution'
var g_includeFilter = []; // arg 'in'
var g_excludeFilter = []; // arg 'out'
var g_outputFormat = "png"; // arg 'format'
var g_keepDot = false; // arg 'keep'
var g_dotApp = "c:\\Program Files\\ATT\\Graphviz\\bin\\dot.exe"; // arg 'dot'
var g_fso = null; ///< File system object (Scripting.FileSystemObject).
var g_shell = null; ///< Shell (WScript.Shell).
var g_logLevel = "INFO"; ///< Either "TRACE", "DEBUG", "INFO" or "ERROR"
///////////////////////////////////////////////////////////////////////////////
/**
* Extend the string type; stip off leading and trailing spaces.
*/
///////////////////////////////////////////////////////////////////////////////
String.prototype.trim = function()
{
return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
///////////////////////////////////////////////////////////////////////////////
/**
* Log a message.
* @param level [in] Message type. Must be either TEST, DEBUG, INFO, WARNING or ERROR.
* @param message [in] Message to show.
*/
///////////////////////////////////////////////////////////////////////////////
function Log(level, message)
{
if ((g_logLevel == "DEBUG") && (level == "TRACE"))
{
return;
}
if ((g_logLevel == "INFO") && ((level == "TRACE") || (level == "DEBUG")))
{
return;
}
if ((g_logLevel == "ERROR") && ((level == "TRACE") || (level == "DEBUG") || (level == "INFO")))
{
return;
}
WScript.Echo(level + ": " + message);
}
///////////////////////////////////////////////////////////////////////////////
/**
* Log a message and abort script.
* @param message [in] Abort reason.
*/
///////////////////////////////////////////////////////////////////////////////
function Die(message)
{
Log("ERROR", message);
Log("INFO", "Aborting script.");
WScript.Quit(3);
}
///////////////////////////////////////////////////////////////////////////////
/**
* Run the application.
*
* The data is not piped inline because its too big, which will confuse gnuplot.
* This is probably due to the buffer size allocated for stdin, which is 4k
* (as far as I know).
*
* @param app [in] Application to execute.
* @param args [in] Application arguments.
*/
///////////////////////////////////////////////////////////////////////////////
function Exec(app, args)
{
try
{
var code = g_shell.Run("\"" + app + "\" " + args, 0, true);
if (code != 0)
{
Die("Failed to run '" + app + "'; " + code);
}
}
catch (e)
{
Die("Failed to run '" + app + "'; " + e.description);
}
}
///////////////////////////////////////////////////////////////////////////////
/**
* Parse the command line arguments and Die if there is any error in it.
*
* The arguments are assigned to global variables.
*/
///////////////////////////////////////////////////////////////////////////////
function ParseCommandLine()
{
// --- Input directory ----------------------------------------------------
if ( WScript.Arguments.Named.Exists("solution") )
{
g_solutionFile = WScript.Arguments.Named.Item("solution");
}
if (g_solutionFile == null) Die("No solution file specified");
if (g_solutionFile.length <= 0) Die("No solution file specified");
if (!g_fso.FileExists(g_solutionFile)) Die("Solution file does not exist '" + g_solutionFile + "'");
// --- include filter -----------------------------------------------------
if ( WScript.Arguments.Named.Exists("in") )
{
var filter = WScript.Arguments.Named.Item("in");
if (filter == null) Die("No exclude filter specified");
if (filter.length > 0) g_includeFilter = filter.split(";");
}
// --- exclude filter -----------------------------------------------------
if ( WScript.Arguments.Named.Exists("out") )
{
var filter = WScript.Arguments.Named.Item("out");
if (filter == null) Die("No exclude filter specified");
if (filter.length > 0) g_excludeFilter = filter.split(";");
}
// --- output format ------------------------------------------------------
if ( WScript.Arguments.Named.Exists("format") )
{
g_outputFormat = WScript.Arguments.Named.Item("format");
if (g_outputFormat == null) Die("No output format specified");
g_outputFormat = g_outputFormat.trim();
if (g_outputFormat.length <= 0) Die("No output format specified");
}
// --- keep dot file ------------------------------------------------------
if ( WScript.Arguments.Named.Exists("keep") )
{
g_keepDot = true;
}
// --- Dot application ----------------------------------------------------
if (WScript.Arguments.Named.Exists("dot") )
{
g_dotApp = WScript.Arguments.Named.Item("dot");
}
if (g_dotApp == null) Die("No dot application specified");
if (!g_fso.FileExists(g_dotApp)) Die("Application not found '" + g_dotApp + "'");
}
///////////////////////////////////////////////////////////////////////////////
/**
* Check if the specified file matches the includeFilter/excludeFilter.
*/
///////////////////////////////////////////////////////////////////////////////
function PassesFilter(file)
{
if (g_includeFilter.length <= 0)
{
if (g_excludeFilter.length <= 0)
{
return true;
}
else
{
var ii;
for (ii = 0; ii < g_excludeFilter.length; ii++)
{
if (file.indexOf(g_excludeFilter[ii]) >= 0)
{
return false;
}
}
return true;
}
}
else
{
var ii;
for (ii = 0; ii < g_includeFilter.length; ii++)
{
if (file.indexOf(g_includeFilter[ii]) >= 0)
{
if (g_excludeFilter.length <= 0)
{
return true;
}
else
{
var jj;
for (jj = 0; jj < g_excludeFilter.length; jj++)
{
if (file.indexOf(g_excludeFilter[jj]) >= 0)
{
return false;
}
}
return true;
}
}
}
return false;
}
}
///////////////////////////////////////////////////////////////////////////////
/**
* Class to store project identifier, name and path.
*/
///////////////////////////////////////////////////////////////////////////////
function Project(id, name, path)
{
this.id = id;
this.name = name;
this.path = path;
}
/// Converts this instance to a String.
Project.prototype.toString = function ()
{
return this.name + " " + this.path + " (" + this.id + ")";
}
///////////////////////////////////////////////////////////////////////////////
// Main
///////////////////////////////////////////////////////////////////////////////
// Create objects
g_fso = new ActiveXObject("Scripting.FileSystemObject");
g_shell = new ActiveXObject("WScript.Shell");
// Parse commandline arguments
ParseCommandLine();
var solutionName = g_fso.GetBaseName(g_solutionFile);
var outputFile = "project-dependencies-" + solutionName;
var dotFile = outputFile + ".dot";
outputFile = outputFile + "." + g_outputFormat;
Log("DEBUG", "Solution file : " + g_solutionFile);
Log("DEBUG", "Output file : " + outputFile);
Log("DEBUG", "Include filter : [" + g_includeFilter + "] (length " + g_includeFilter.length + ")");
Log("DEBUG", "Exclude filter : [" + g_excludeFilter + "] (length " + g_excludeFilter.length + ")");
// --- Create project list index on the project id ----------------------------
var lineNr = 0;
var firstLine = true;
var projectsList = new ActiveXObject("Scripting.Dictionary");
var xStartProject = /^\s*Project\s*\(\s*\"\{[A-F0-9\-]{36}\}\"\s*\)\s*=\s*\"(\S+)\"\s*,\s*\"(.*\.(vcproj|csproj))\"\s*,\s*\"\{([A-F0-9\-]{36})\}\"\s*$/i;
var solutionHandle = g_fso.OpenTextFile(g_solutionFile, 1);
while (!solutionHandle.AtEndOfStream)
{
lineNr += 1;
var line = solutionHandle.ReadLine();
line = line.trim();
if (line.length <= 0)
{
// Skip empty lines
continue;
}
if (firstLine)
{
firstLine = false;
var xFirstLine = /Microsoft\s+Visual\s+Studio\s+Solution\s+File\s*,\s*Format\s+Version\s+\d+[,\.]\d+/i
if (!xFirstLine.test(line))
{
if (lineNr != 1)
{
Die("File is not a valid solution file (" + g_solutionFile + ")");
}
// First line might be UTF byte order marker (bom); try next line as well
firstLine = true;
}
continue;
}
if (xStartProject.test(line))
{
var items = line.match(xStartProject);
var id = items[4];
var project = new Project(id, items[1], items[2]);
projectsList.add(id, project);
Log("TRACE", project);
}
}
solutionHandle.Close();
if (projectsList.Count <= 1)
{
Die("Only " + projectsList.Count + " projects found in file '" + g_solutionFile + "'");
}
Log("INFO", "Solution '" + g_solutionFile + "' contains " + projectsList.Count + " projects");
// --- Look up project dependencies -------------------------------------------
Log("INFO", "Writing file '" + dotFile + "'");
var dotHandle = g_fso.CreateTextFile(dotFile, true);
dotHandle.WriteLine("//");
dotHandle.WriteLine("// Generated by " + "project-dependencies.js");
dotHandle.WriteLine("// Creation date " + Date());
dotHandle.WriteLine("// Solution file " + g_solutionFile);
dotHandle.WriteLine("// Filters in/out [" + g_includeFilter + "] / [" + g_excludeFilter + "]");
dotHandle.WriteLine("//");
dotHandle.WriteLine("digraph ProjectDependencyGraph {");
dotHandle.WriteLine("rankdir=LR;");
dotHandle.WriteLine("node [fontname=\"Arial\",fontsize=10,shape=box,fillcolor=\"#E3E4FA\",style=filled];");
dotHandle.WriteLine("edge [arrowhead=open,fontname=\"Arial\",fontsize=10];");
lineNr = 0;
projectId = "";
parsingDependencies = false;
solutionHandle = g_fso.OpenTextFile(g_solutionFile, 1);
while (!solutionHandle.AtEndOfStream)
{
lineNr += 1;
var line = solutionHandle.ReadLine();
line = line.trim();
if (line.length <= 0)
{
// Skip empty lines
continue;
}
// Find out which projects dependencies we're parsing
if (projectId.length <= 0)
{
if (xStartProject.test(line))
{
var items = line.match(xStartProject);
var id = items[4];
if (PassesFilter(items[2]))
{
projectId = id;
Log("TRACE", "Project " + items[1] + " passed filter (" + items [2] + ")");
}
else
{
Log("TRACE", "Skipping project " + items[1] + " (" + items [2] + ")");
}
}
}
else
{
var xEndProject = /^\s*EndProject\s*$/i;
if (xEndProject.test(line))
{
projectId = "";
continue;
}
}
if (projectId.length <= 0) continue;
var parentProject = projectsList(projectId);
if (!parsingDependencies)
{
var xStartDependencies = /^\s*ProjectSection\s*\(\s*ProjectDependencies\s*\)\s*=\s*postProject\s*$/i;
if (xStartDependencies.test(line))
{
Log("TRACE", "line " + lineNr + "; start parsing dependencies of project " + parentProject.name);
parsingDependencies = true;
}
continue;
}
else
{
var xEndDependencies = /^\s*EndProjectSection\s*$/i;
if (xEndDependencies.test(line))
{
Log("TRACE", "line " + lineNr + "; end parsing dependencies of project " + parentProject.name);
parsingDependencies = false;
continue;
}
}
if (!parsingDependencies) continue;
var xDependency = /^\s*\{([A-F0-9\-]{36})\}\s*=\s*\{[A-F0-9\-]{36}\}\s*$/i;
if (!xDependency.test(line)) Die("Failed to match dependency on line " + lineNr + "; \"" + line + "\"");
var id = line.match(xDependency)[1];
childProject = projectsList(id);
//Log("TRACE", "Project " + parentProject.name + " depends on project " + childProject.name);
dotHandle.WriteLine("\"" + parentProject.name + "\" -> \"" + childProject.name + "\"");
}
solutionHandle.Close();
dotHandle.WriteLine("}");
dotHandle.Close();
Log("INFO", "Running dot...");
var arguments = "-T " + g_outputFormat + " -o \"" + outputFile + "\" \"" + dotFile + "\"";
Log("DEBUG", g_dotApp + " " + arguments);
Exec(g_dotApp, arguments);
if (!g_keepDot)
{
try
{
g_fso.DeleteFile(dotFile);
}
catch (e)
{
Log("WARNING", "Failed to delete file '" + dotFile + "'; " + e.description);
}
}
Log("INFO", "Done (" + outputFile + ")");
|
|
|
|

|
This was something I had just decided to build for my own dependency analysis needs. Glad I decided to do a quick search for code I could use as a starting point. I'm interested in seeing those changes that the previous commenter added. Perhaps you could post that code along with yours if you don't have time to add the changes?
Thanks for sharing!
|
|
|
|

|
Hmmm, I really dropped the ball there, in getting those changes into the article.
Could you email me directly, and I'll email you the code directly that dgaudian sent me.
Marc
|
|
|
|

|
Thanks for this nice tool.
I made a few minor changes for our special needs - are you interested receiving the changes back?
- Delayed population of left treeview on expansion of nodes (for large solutions with many dependencies)
- Check boxes before the nodes to exclude Projects from rendering
- Colors for different project types (libraries, exes, winexes)
- Small optical and layout enhancements
Greetings,
Dirk
|
|
|
|

|
dgaudian wrote: are you interested receiving the changes back?
Certainly! I'd like to update the article then, and I'd be happy to give you credit or make you a co-author on the article. You can email directly and marc[dot]clifton[at]gmail[dot]com.
Thanks!
Marc
|
|
|
|

|
I do not seem to be able to download the ZIP for this article. Is anyone else having problems?
|
|
|
|

|
Still working for me. Email me directly, and I'll email you the zip file (it'll have to be wrapped in a rar though for me to send it through gmail)
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|

|
Hello,
I have XDoucument object which contains the XMLFile data,
I wanted to bind this XDocument data to a treeview in vb.net 3.5?
Regards,
Mukhthar Saleem
|
|
|
|

|
Nice, I like it.
Just a small bug, I think.
Line 174 of Form1.cs...
TreeNode tn2 = new TreeNode(pdep.Name + " (" + p.TargetVersion + ")");
needs to be
TreeNode tn2 = new TreeNode(pdep.Name + " (" + pdep.TargetVersion + ")");
|
|
|
|

|
Johan Fourie wrote: Nice, I like it.
Just a small bug, I think.
Oops! Thanks for spotting that!
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|

|
Umm, I don't see an actual graph in your screenshots - are you just showing TreeView controls? It would be better to actually show a proper graph, I think.
|
|
|
|

|
Dmitri Nesteruk wrote: Umm, I don't see an actual graph in your screenshots - are you just showing TreeView controls? It would be better to actually show a proper graph, I think.
The term "graph" refers to anything that shows the relationship between entities. For example, the term "object graph" is often used to describe the object hierarchy expressed in XAML.
A TreeView meets the definition of a graph:
a diagram representing a system of connections or interrelations among two or more things by a number of distinctive dots, lines, bars, etc.
because it is a diagram of interrelations using a number of distinctive lines.
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|

|
I actually meant something like this[^]. By the way, to generate this image, I used your source code and Graphviz. So I guess I'm answering my own question, in a way.
Thanks for the article!
|
|
|
|

|
Dmitri Nesteruk wrote: I actually meant something like this[^]. By the way, to generate this image, I used your source code and Graphviz.
Sweet. Want to share your code?
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|
|

|
Btw, feel free to add this stuff to your article - I think people might actually find this useful, if a bit scary. And, speaking of which, I actually got the idea for using this tool from someone who uses it to visualize IoC containers. Which is another very useful option if you're into IoC/DI.
|
|
|
|

|
Dmitri Nesteruk wrote: Btw, feel free to add this stuff to your article - I think people might actually find this useful, if a bit scary.
Thanks! Yes, scary indeed, seeing all the intertwined dependencies.
Dmitri Nesteruk wrote: And, speaking of which, I actually got the idea for using this tool from someone who uses it to visualize IoC containers. Which is another very useful option if you're into IoC/DI.
That's a great idea! I've been working with both CAB and Spring.NET, and the dependencies can get quite difficult to follow.
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|

|
We have only 177 projects, but with many dependencies.
Your utility works, but is very slow to the point of not being useful.
After examining it with a performance profiler, I found that virtually all the time is being spent in populating nodes for the treeview: Form1.PopulateNewLevel() (recursively).
Maybe it could be improved by building the initial tree in memory, and only showing nodes that the user expands "on demand", rather than constructing the entire tree view in one hit. Is this not how Windows Explorer works?
|
|
|
|

|
ZTransform wrote: Maybe it could be improved by building the initial tree in memory, and only showing nodes that the user expands "on demand", rather than constructing the entire tree view in one hit.
I was thinking about that as a future refinement. Look for it soon (give me a week or so.)
Thanks for investigating where the bottleneck is--I rather figured that might be a problem, given my experience recently with some XSD recursion issues on an unrelated project.
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|

|
As the author of one of the tools (dependencyvisualizer.codeplex.com) that "create an unreadable smear of boxes and lines, because they were never designed to handle a solution with 50 or more projects." I do see the need for an alternative view for large solutions. (I just never have gotten around to provide it..)
While you can easily parse the .csproj file manually (and other msbuild compatible files for that matter), there is an object model available in Microsoft.Build.* assemblies.
I tried the project and got the following exception:
System.ArgumentException was unhandled
Message="An item with the same key has already been added."
Source="mscorlib"
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
at ProjectDependencyGraph.Project.Read(String filename) in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Project.cs:line 57
at ProjectDependencyGraph.Form1.ParseSolution(String filename) in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Form1.cs:line 32
at ProjectDependencyGraph.Form1.btnLoadSolution_Click(Object sender, EventArgs e) in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Form1.cs:line 183
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at ProjectDependencyGraph.Program.Main() in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Edit: and if try to fix that with an if (!referencedProjects.ContainsKey(projRef.Name))
I get the following:
System.Collections.Generic.KeyNotFoundException was unhandled
Message="The given key was not present in the dictionary."
Source="mscorlib"
StackTrace:
at System.ThrowHelper.ThrowKeyNotFoundException()
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at ProjectDependencyGraph.Form1.ParseSolution(String filename) in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Form1.cs:line 40
at ProjectDependencyGraph.Form1.btnLoadSolution_Click(Object sender, EventArgs e) in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Form1.cs:line 183
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at ProjectDependencyGraph.Program.Main() in C:\Download\ProjectDependencyGraph\ProjectDependencyGraph\ProjectDependencyGraph\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
|
|
|
|

|
sdahlbac wrote: As the author of one of the tools (dependencyvisualizer.codeplex.com) that "create an unreadable smear of boxes and lines
Busted!
There's no error handling at all, and yes, two projects with the same name is a problem (if that wasn't in the limitations, it needs to be--I knew I forgot something!)
I'm putting together another release which sorts the projects and adds a synchronize feature. I'll add some error checking, see what's involved in supporting multiple projects, and also look at Microsoft.Build.
Thanks for the great feedback--watch for updates!
Marc
Will work for food.
Interacx
I'm not overthinking the problem, I just felt like I needed a small, unimportant, uninteresting rant! - Martin Hart Turner
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Review your project dependencies.
| Type | Article |
| Licence | CPOL |
| First Posted | 17 Jun 2009 |
| Views | 79,624 |
| Downloads | 2,188 |
| Bookmarked | 91 times |
|
|