Archives
-
Enumerating projects in a Visual Studio solution
People writing add-ins for Visual studio probably have come across the nightmare of the Visual studio object model to go through the projects within a solution. I had to get the list of projects in a solution, and for each solution its output path in the current configuration. Although I need the code in C# later on, the best way to check out how to program against the Visual Studio object model is within the Macro IDE of Visual Studio (Tools->Macros->Macros IDE).
Although the question seems quite straightforward, the trouble begins when you have Solution Folders containing projects. The Solution object has a property called Projects, but Solution Folders are also seen as Projects. A project has project items. A project item can be a folder, a file, or... a project. You have to see it to believe the mess.
After a lot of trial and error I got to a solution where I check if a project item has its ConfigurationManager property set, if this is the case, it must be a project. Not sure if this is the best approach, but it works for me. For example for the following project structure using Solution Folders:
I get the following output:
And the code to accomplish this (paste in Macros IDE):
Sub SolutionProjects() Dim project As EnvDTE.Project Write("--------- DUMP OF ALL PROJECTS IN CURRENT SOLUTION -------------") Try If Not DTE.Solution.IsOpen Then Write("There is no solution open.") Else For Each project In DTE.Solution.Projects NavProj(project) Next End If Catch ex As System.Exception Write(ex.ToString) End Try End Sub Sub NavProj(ByVal proj As Project) Dim outputPathProperty As EnvDTE.Property Dim outputPath As String If Not (proj.ConfigurationManager Is Nothing) Then ' It's a project! outputPathProperty = _ proj.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPath") If outputPathProperty Is Nothing Then outputPath = "<no output path set>" Else outputPath = outputPathProperty.Value End If Write("### Project: " + proj.Name + ", OutputPath: " + outputPath) Else NavProjItems(proj.ProjectItems) End If End Sub Sub NavProjItems(ByVal projItems As ProjectItems) Dim projectItem As EnvDTE.ProjectItem
<span style="color: rgb(0,0,255)">If</span> <span style="color: rgb(0,0,255)">Not</span> (projItems <span style="color: rgb(0,0,255)">Is</span> <span style="color: rgb(0,0,255)">Nothing</span>) <span style="color: rgb(0,0,255)">Then
For Each projectItem In projItems If Not (projectItem.SubProject Is Nothing) Then ' Recurse, can be an Enterprise project in ' Visual Studio .NET 2002/2003 or a solution folder in VS 2005 NavProj(projectItem.SubProject) End If Next End If End Sub
Sub Write(ByVal s As String) Dim out As OutputWindowPane = GetOutputWindowPane("MACRO OUTPUT", True) out.OutputString(s) out.OutputString(vbCrLf) End Sub
Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane Dim win As Window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput) If show Then win.Visible = True Dim ow As OutputWindow = win.Object Dim owpane As OutputWindowPane Try owpane = ow.OutputWindowPanes.Item(Name) Catch e As System.Exception owpane = ow.OutputWindowPanes.Add(Name) End Try owpane.Activate() Return owpane End Function -
Great list of links to info on Visual Studio extensibility
Writing add-ins and packages for Visual Studio is a whole different kind of sport. I stumbled across a great list of resources that can get you started: http://www.mztools.com/resources_vsnet_addins.htm
-
VS 2005 image library - all the icons you need !
I am busy writing a toolwindow extension for Visual Studio 2005, and I needed some icons for my toolbar in the same style as Visual Stuido 2005. In search of this I stumbled accross the VS2005ImageLibrary, a zip file containing all the icons you need!
Path: X:\Program Files\Microsoft Visual Studio 8\Common7\VS2005ImageLibrary
-
PowerShell - Windows PowerShell In Action - Bruce Payette
I have done a lot of coding in Windows PowerShell last months, and my biggest help next to some of the great weblogs on PowerShell like the weblog of The PowerShell Guy and the PowerShell team., was an early access version of the Windows PowerShell in Action e-book. Today I got the final e-book version, and it got even better! You can now preorder the book at Amazon, it will be available real soon. If you are serious about PowerShell: get this book!! It will get 5-* ratings on Amazon, I'm sure!
-
PowerShell - function return values implementing IEnumerable are decomposed into an array
In this blog post I wrote about (by me) unexpected implicit type conversion on return values of functions which is actually really cool: all types returned that implement the IEnumerable interface are decomposed in an array of the elements that are enumerated in the IEnumerable type. This collection of elements is returned "on the pipeline". This decompositioning goes one level deep (a pipeline is linear). So if an array of values is returned, the values don't get decomposed. An array with a single element can be returned as follows: ,$element.
An example follows below with two functions: foo where the return value gets decomposed into an array, and bar where we stoped the decompositioning by returning the element in an array:
function foo
{
$arraylist = new-Object System.Collections.ArrayList
[void]$arraylist.Add("one")
[void]$arraylist.Add("two")
[void]$arraylist.Add("three")
return $arraylist # implicit conversion to array
}
function bar
{
$arraylist = new-Object System.Collections.ArrayList
[void]$arraylist.Add("one")
[void]$arraylist.Add("two")
[void]$arraylist.Add("three")
return ,$arraylist
}
foo | foreach ($_) {Write-Host "foo value (with type: $($_.GetType()) in pipe: $_" }
bar | foreach ($_) {Write-Host "bar value (with type: $($_.GetType()) in pipe: $_" }
This results in:foo value (with type: System.String in pipe: one
foo value (with type: System.String in pipe: two
foo value (with type: System.String in pipe: three
bar value (with type: System.Collections.ArrayList in pipe: one two three -
PowerShell - referencing files relative to the currently executing script
I often have the situation that that I want to do a relative reference to a script file from another script file. This works ok if we execute the referencing script file from its current location, but what if that script is referenced as well. Ok, a bit vague, an example:
Folder c:\test contains script X.ps1
Folder c:\test\sub contains script Y.ps1
Folder c:\test\sub contains script Z.ps1The initially executing script is: C:\test\X.ps1
The scripts are defined as follows:
C:\test\X.ps1:
./sub/Y.ps1
Write-Host "X"C:\test\sub\Y.ps1:
./Z.ps1 # this one not found, because the current folder is c:\test, not c:\test\sub
Write-Host "Y"C:\test\sub\Z.ps1:
Write-Host "Z"I have this problem if Y.ps1 and Z.ps1 are part of a utility library, and X.ps1 is one of the calling scripts. A good example is the psexpect library from www.codeplex.com where I had exactly this problem.
The PowerShell guy (/\/\o\/\/) came to the rescue with the following solution:
Split-Path -Path $MyInvocation.MyCommand.Path -Parent
We can rewrite our scripts as follows:
C:\test\X.ps1:
$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Write-Host "Script X: script folder=$executingScriptDirectory"
& "$executingScriptDirectory/sub/Y.ps1"
Write-Host "X"C:\test\sub\Y.ps1:
$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Write-Host "Script Y: script folder=$executingScriptDirectory"
& "$executingScriptDirectory/Z.ps1"
Write-Host "Y"C:\test\sub\Z.ps1:
Write-Host "Z"- The start script C:\test\X.ps1 can now be executed from any location.
- The library script C:\test\sub\Y.ps1 can be utilized by any script.
Note that this code must be executed in the body of the script, and not from within a function!!
The one strange thing that puzzles me now is why PowerShell Analyzer gives the following exception:
--------------------------------------------------------------------------------
POWERSHELL EXCEPTION
EXCEPTION TYPE:System.Management.Automation.CmdletInvocationException
MESSAGE:Cannot find drive. A drive with name '$executingScriptDirectory = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent
Write-Host "Script X' does not exist.
POSITION:
At line:1 char:39
+ $executingScriptDirectory = Split-Path <<<< -Path $MyInvocation.MyCommand.Definition -Parent
--------------------------------------------------------------------------------So many words to explain a problem and solve an issue that was so easy in cmd.exe, ~dp0 did the job!
-
PowerShell - Strange implicit type conversion
PowerShell is great, but sometimes it has some strange quircks that can cost you a lot of time to solve. My latest "obstacle" was the following situation:
function ArgsToArrayList {
$al = new-object System.Collections.ArrayList
$args | foreach { [void] $al.add($_) }
$al
}$x = ArgsToArrayList 1 2 3 4 5
write-Host "5 entries, type: " $x.GetType()
$x = ArgsToArrayList
write-Host "0 entries, is null: " ($x -eq $null)I expect the function ArgsToArrayList to always return an object of type System.Collections.ArrayList, independent of the number of arguments passed. I was wrong.
PowerShell converts the return value of the function ArgsToArrayList from System.Collections.ArrayList to System.Object[] when it contains entries, and to $null when the arraylist is empty.
So the output of the above code is:
5 entries, type: System.Object[]
0 entries, is null: TrueBeats me...
-
VS.NET 2005 Tool Window for testing XPath expressions - XPathmania
I had to define some XPath expressions to query information from an XML document. I couldn't find any standard support for this in Visual Studio 2005, but after some searching I stumbled accross XPathmania, a tool window developed by Don Xml. Works like a breeze! See below. See this blog entry for more information. Download it here. Source code is available as well.
-
Console2 - a great Windows console window enhancer for cmd.exe and PowerShell
Through a discussion thread on the PowerShell Community Extensions forum at Codeplex I found Console2, a great tool that enhances the working experience with Windos console window that is normally used by Cmd.exe and PowerShell. You can resize the window dynamically, do normal text selections (use shift+mouse), have tabs, and do all kind of style configurations.See the discussion thread for information on configuration for PowerShell. Check it out!