{"id":242,"date":"2011-02-23T10:54:03","date_gmt":"2011-02-23T09:54:03","guid":{"rendered":"http:\/\/dev.flauschig.ch\/wordpress\/?p=242"},"modified":"2011-02-23T11:22:07","modified_gmt":"2011-02-23T10:22:07","slug":"visualstudio-macro-project-references","status":"publish","type":"post","link":"http:\/\/dev.flauschig.ch\/wordpress\/?p=242","title":{"rendered":"VisualStudio Macro &#8211; Project References"},"content":{"rendered":"<p>Have you ever tried adding a new reference to lots of projects in a very large application? If you have, you know this already and if you haven&#8217;t, let me tell you: it gets old really fast&#8230; Open project, right click the project, click on &#8220;Add Reference&#8230;&#8221; and so on. As an inherently lazy demographic, this simply is not an options for us developers. So what do we do? We automate it with a VisualStudio macro.<\/p>\n<p><!--more--><\/p>\n<p>First of all: yes, its VB &#8211; deal with it.<\/p>\n<p>You can find the Macros IDE in the Tools menu of VS under Macros. There are some samples that come with VS and there is some code out there on the web, but what I want to show you is how you can automate project reference handling.<\/p>\n<p><code>DTE.Solution.Projects<\/code><\/p>\n<p>gives you a collection of project objects in your current solution. You can add projects with<\/p>\n<p>DTE.Solution.AddFromFile(projectFilePath)<\/p>\n<p>but to add a reference to a project, you need to get a handle on a VSProject while the projects in DTE.Solution.Projects are of type Project. To get a VSProject from a Project, simply do this<\/p>\n<p>Dim vsProject = CType(DTE.Solution.Projects.Item(1).Object, VSProject)<\/p>\n<p>Now you can add a reference to this project by doing this<\/p>\n<p>&#8216; add project reference to otherProject (of type Project)<br \/>\nvsProject.References.AddProject(otherProject)<br \/>\n&#8216; add file reference to assemblyPath<br \/>\nvsProject.References.Add(assemblyPath)<\/p>\n<p>To get a better picture of how you could use that. Here is some code of mine that I used to add a file reference to a bunch of projects. The macro first asks the user to select a target assembly and then a file containing a list of folder names (separated by newlines). For every entry in the folder list, the macro searches for a VB or C# project in that folder or a parent folder and if the project hasn&#8217;t already been processed, adds the project to the solution and adds the file reference.<\/p>\n<pre class=\"brush: vb; gutter: false; title: ; wrap-lines: false; notranslate\" title=\"\">\r\nPublic Module References\r\n\r\n    Public Sub CustomAddFileReference()\r\n\r\n        Dim log As TextWriter = New StringWriter()\r\n\r\n        If (DTE.Solution.Count &lt;&gt; 0) Then\r\n            MsgBox(&quot;Please close solution first&quot;)\r\n            Return\r\n        End If\r\n\r\n        DTE.Solution.Create(&quot;C:\\&quot;, &quot;automagic&quot;)\r\n\r\n        Dim openFileDialog As Forms.FileDialog = New Forms.OpenFileDialog\r\n        Dim winptr As WinWrapper = New WinWrapper\r\n        Dim target As String\r\n        Dim projects As Dictionary(Of String, Project) = New Dictionary(Of String, Project)()\r\n\r\n        openFileDialog.Filter = &quot;Assemblies (*.dll)|*.dll|All files (*.*)|*.*&quot;\r\n        openFileDialog.FilterIndex = 2\r\n        openFileDialog.Title = &quot;Select Target Assembly&quot;\r\n\r\n        If openFileDialog.ShowDialog(winptr) = Forms.DialogResult.OK Then\r\n            target = openFileDialog.FileName\r\n        End If\r\n\r\n        openFileDialog.Filter = &quot;All files (*.*)|*.*&quot;\r\n        openFileDialog.FilterIndex = 1\r\n        openFileDialog.Title = &quot;Select Project List&quot;\r\n\r\n        If openFileDialog.ShowDialog(winptr) = Forms.DialogResult.OK Then\r\n            Dim reader As StreamReader = File.OpenText(openFileDialog.FileName)\r\n            While (Not reader.EndOfStream)\r\n                Dim line As String = reader.ReadLine().Trim()\r\n                Dim projFile = FindProjectFile(line)\r\n\r\n                If (Not projFile Is Nothing AndAlso Not projects.ContainsKey(projFile)) Then\r\n                    log.WriteLine(projFile)\r\n\r\n                    Try\r\n                        Dim source As Project = DTE.Solution.AddFromFile(projFile)\r\n                        projects.Add(projFile, source)\r\n\r\n                        Dim vsProject = CType(source.Object, VSProject)\r\n                        vsProject.References.Add(target)\r\n                    Catch ex As Exception\r\n                        log.WriteLine(ex.ToString())\r\n                    End Try\r\n                End If\r\n\r\n            End While\r\n            reader.Dispose()\r\n        End If\r\n\r\n        Dim outputPane As OutputWindowPane = GetOutputWindowPane(&quot;Macros&quot;)\r\n        outputPane.OutputString(log.ToString())\r\n\r\n    End Sub\r\n\r\n    Private Function FindProjectFile(ByVal directory As String) As String\r\n        Dim path = directory\r\n        Dim project = Nothing\r\n        Dim ext = Nothing\r\n\r\n        While (project Is Nothing)\r\n            For Each child As String In System.IO.Directory.GetFiles(path)\r\n                ext = System.IO.Path.GetExtension(child)\r\n                If (ext = &quot;.vbproj&quot; OrElse ext = &quot;.csproj&quot;) Then\r\n                    Return child\r\n                End If\r\n            Next\r\n            path = System.IO.Path.GetFullPath(System.IO.Path.Combine(path, &quot;..&quot;))\r\n        End While\r\n\r\n        Return Nothing\r\n    End Function\r\n\r\n    Private Function GetOutputWindowPane(ByVal Name As String, Optional ByVal show As Boolean = True) As OutputWindowPane\r\n        Dim window As Window\r\n        Dim outputWindow As OutputWindow\r\n        Dim outputWindowPane As OutputWindowPane\r\n\r\n        window = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput)\r\n        If show Then window.Visible = True\r\n        outputWindow = window.Object\r\n        Try\r\n            outputWindowPane = outputWindow.OutputWindowPanes.Item(Name)\r\n        Catch e As System.Exception\r\n            outputWindowPane = outputWindow.OutputWindowPanes.Add(Name)\r\n        End Try\r\n        outputWindowPane.Activate()\r\n        Return outputWindowPane\r\n    End Function\r\n\r\n\r\nEnd Module\r\n\r\n'' This class is used to set the proper parent to any UI that you may display from within a macro.\r\n''  See the AddClassicComRef macro for an example of how this is used\r\nPublic Class WinWrapper\r\n    Implements System.Windows.Forms.IWin32Window\r\n\r\n    Overridable ReadOnly Property Handle() As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle\r\n        Get\r\n            Dim iptr As New System.IntPtr(DTE.MainWindow.HWnd)\r\n            Return iptr\r\n        End Get\r\n    End Property\r\nEnd Class\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Have you ever tried adding a new reference to lots of projects in a very large application? If you have, you know this already and if you haven&#8217;t, let me tell you: it gets old really fast&#8230; Open project, right click the project, click on &#8220;Add Reference&#8230;&#8221; and so on. As an inherently lazy demographic, &hellip; <\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[100,98,99],"class_list":{"0":"entry","1":"post","2":"publish","3":"author-executor","4":"has-more-link","5":"post-242","7":"format-standard","8":"category-programming","9":"post_tag-references","10":"post_tag-vs","11":"post_tag-vs-macros"},"acf":[],"views":3871,"_links":{"self":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/242"}],"collection":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=242"}],"version-history":[{"count":0,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/242\/revisions"}],"wp:attachment":[{"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=242"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/dev.flauschig.ch\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}