Imports System
Imports EnvDTE
Imports EnvDTE80
Imports System.Diagnostics

Public Module Chapter08

    Sub GetSolution()
        Dim solution As EnvDTE.Solution
        solution = DTE.Solution
    End Sub

    Sub CreateAndSaveSolution()
        DTE.Solution.Create("C:\", "Solution")
        DTE.Solution.SaveAs("C:\Solution.sln")
    End Sub

    Sub OpenSolution()
        Dim promptResult As vsPromptResult
        'Offer to save any open and modified files:
        promptResult = DTE.ItemOperations.PromptToSave
        'If the user pressed anything but the Cancel button,
        ' then open a solution file from disk:
        If promptResult <> vsPromptResult.vsPromptResultCancelled Then
            DTE.Solution.Open("C:\Solution.sln")
        End If
    End Sub

    Sub EnumProjects()
        Dim project As EnvDTE.Project
        For Each project In DTE.Solution
            MsgBox(project.UniqueName)
        Next
    End Sub

    Sub EnumProjects2()
        Dim project As EnvDTE.Project
        For Each project In DTE.Solution.Projects
            MsgBox(project.UniqueName)
        Next
    End Sub

    Sub FindSelectedProjects()
        Dim selectedProjects As Object()
        Dim project As EnvDTE.Project
        selectedProjects = DTE.ActiveSolutionProjects
        For Each project In selectedProjects
            MsgBox(project.UniqueName)
        Next
    End Sub

    Sub ProjectTemplatePath()
        Dim solution2 As EnvDTE80.Solution2
        Dim CSConsoleTemplatePath As String

        solution2 = CType(DTE.Solution, EnvDTE80.Solution2)
        CSConsoleTemplatePath = solution2.GetProjectTemplate("ConsoleApplication.zip", "CSharp")
        MsgBox(CSConsoleTemplatePath)
    End Sub

    Sub UserProjectTemplatePath()
        Dim projectTemplatePath As String
        projectTemplatePath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData)
        projectTemplatePath = System.IO.Path.Combine(projectTemplatePath, "Microsoft\VisualStudio\8.0\ProjectTemplatesCache")
        'projectTemplatesPath contains the path for all templates, now add to 
        '  the path using information specific to the template to find:
        projectTemplatePath = System.IO.Path.Combine(projectTemplatePath, "Visual Basic\MyTemplate.zip\MyTemplate.vstemplate")
    End Sub

    Sub EnumTopLevelProjectItems()
        Dim projItem As EnvDTE.ProjectItem
        Dim projectProjectItems As EnvDTE.ProjectItems
        Dim project As EnvDTE.Project

        'Find the first project in a solution:
        project = DTE.Solution.Projects.Item(1)
        'Retrieve the collection of project items:
        projectProjectItems = project.ProjectItems
        'Walk the list of items in the collection:
        For Each projItem In projectProjectItems
            MsgBox(projItem.Name)
        Next
    End Sub

    Sub EnumProjectItems(ByVal projItems As EnvDTE.ProjectItems)
        Dim projItem As EnvDTE.ProjectItem
        'Find all the ProjectItem objects in the given collection:
        For Each projItem In projItems
            MsgBox(projItem.Name)
            'And walk any items the current item may contain:
            EnumProjectItems(projItem.ProjectItems)
        Next
    End Sub

    Sub EnumProject()
        Dim project As EnvDTE.Project
        'Find the first project in a solution:
        project = DTE.Solution.Projects.Item(1)
        EnumProjectItems(project.ProjectItems)
    End Sub

    Sub FindBitmap()
        Dim project As EnvDTE.Project
        Dim projectProjectItems As EnvDTE.ProjectItems
        Dim resourcesProjectItem As EnvDTE.ProjectItem
        Dim resourcesProjectItems As EnvDTE.ProjectItems
        Dim bitmapsProjectItem As EnvDTE.ProjectItem
        Dim bitmapsProjectItems As EnvDTE.ProjectItems
        Dim bitmapProjectItem As EnvDTE.ProjectItem

        'Get the project:
        project = DTE.Solution.Item(1)
        'Get the list of items in the project:
        projectProjectItems = project.ProjectItems
        'Get the item for the Resources folder:
        resourcesProjectItem = projectProjectItems.Item("Ressourcen")
        'Get the collection of items in the Resources folder:
        resourcesProjectItems = resourcesProjectItem.ProjectItems
        'Get the item for the Bitmaps folder:
        bitmapsProjectItem = resourcesProjectItems.Item("Bitmaps")
        'Get the collection of items in the Bitmaps folder:
        bitmapsProjectItems = bitmapsProjectItem.ProjectItems
        'Get the item for the Bitmap1.bmp file:
        bitmapProjectItem = bitmapsProjectItems.Item("Bitmap1.bmp")
        MsgBox(bitmapProjectItem.Name)
    End Sub

    Sub FindItem()
        Dim projectItem As EnvDTE.ProjectItem
        projectItem = DTE.Solution.FindProjectItem("Connect.cs")
    End Sub

    Sub FindItemWithFolder()
        Dim projectItem As EnvDTE.ProjectItem
        projectItem = DTE.Solution.FindProjectItem("MyAddin1\Connect.cs")
    End Sub

    Sub FindItemWithFullPath()
        Dim projectItem As EnvDTE.ProjectItem
        projectItem = _
            DTE.Solution.FindProjectItem("C:\Addins\MyAddin1\Connect.cs")
    End Sub

    Sub AddExistingItem()
        DTE.ItemOperations.AddExistingItem("C:\file.txt")
    End Sub

    Sub ProjectItemTemplatePath()
        Dim solution2 As EnvDTE80.Solution2
        Dim VBModuleTemplatePath As String

        solution2 = CType(DTE.Solution, EnvDTE80.Solution2)
        VBModuleTemplatePath = solution2.GetProjectItemTemplate("Module.zip", "VisualBasic")
        MsgBox(VBModuleTemplatePath)
    End Sub

    Sub UserProjectItemTemplatePath()
        Dim projectItemTemplatePath As String
        projectItemTemplatePath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData)
        projectItemTemplatePath = System.IO.Path.Combine(projectItemTemplatePath, "Microsoft\VisualStudio\8.0\ItemTemplatesCache")
        'projectItemTemplatePath contains the path for all templates, 
        'now add to the path
        '  using information specific to the template to find:
        projectItemTemplatePath = System.IO.Path.Combine(projectItemTemplatePath, "Visual Basic\MyTemplate.zip\MyTemplate.vstemplate")
    End Sub

    Sub GetVSProject()
        Dim project As EnvDTE.Project
        Dim vsproject As VSLangProj.VSProject
        project = DTE.Solution.Projects.Item(1)
        vsproject = CType(project.Object, VSLangProj.VSProject)
    End Sub

    Sub EnumReferences()
        Dim proj As EnvDTE.Project
        Dim vsproj As VSLangProj.VSProject
        Dim references As VSLangProj.References
        Dim reference As VSLangProj.Reference
        proj = DTE.Solution.Projects.Item(1)
        vsproj = proj.Object
        references = vsproj.References
        For Each reference In references
            MsgBox(reference.Name)
        Next
    End Sub

    Sub AddReferenceToAssembly()
        Dim vsproj As VSLangProj.VSProject
        Dim proj As EnvDTE.Project
        proj = DTE.Solution.Projects.Item(1)
        vsproj = CType(proj.Object, VSLangProj.VSProject)
        vsproj.References.Add("C:\Programme\Gemeinsame Dateien\Microsoft Shared\MSEnv\PublicAssemblies\extensibility.dll")
    End Sub

    Sub AddProjectReference()
        Dim vsproj As VSLangProj.VSProject
        Dim proj As EnvDTE.Project
        'Find the project the reference will be added to:
        proj = DTE.Solution.Projects.Item(1)
        vsproj = CType(proj.Object, VSLangProj.VSProject)
        'Find the referenced project:
        proj = DTE.Solution.Projects.Item(2)
        'Make the project to project reference:
        vsproj.References.AddProject(proj)
    End Sub

    Sub AddCOMReference()
        Dim vsproj As VSLangProj.VSProject
        Dim proj As EnvDTE.Project
        proj = DTE.Solution.Projects.Item(1)
        vsproj = CType(proj.Object, VSLangProj.VSProject)
        vsproj.References.AddActiveX("{22D6F304-B0F6-11D0-94AB-0080C74C7E95}", 1, 0)
    End Sub

    Sub AddTerraServerWebRef()
        Dim vsProj As VSLangProj.VSProject
        Dim serviceURL As String
        'Set the URL to the TerraServer web service
        serviceURL = "http://terraserver.microsoft.com/TerraService2.asmx"
        'Find the VSProject for a project
        vsProj = DTE.Solution.Projects.Item(1).Object
        'Add the web reference
        vsProj.AddWebReference(serviceURL)
    End Sub

    Sub AddSystemXMLImport()
        Dim vsProj As VSLangProj.VSProject
        vsProj = DTE.Solution.Projects.Item(1).Object
        vsProj.Imports.Add("System.Xml")
    End Sub

    Sub WalkVSProjectProperties()
        Dim project As EnvDTE.Project
        Dim properties As EnvDTE.Properties
        Dim [property] As EnvDTE.Property
        Dim owp As InsideVSNET.Utilities.OutputWindowPaneEx
        owp = New InsideVSNET.Utilities.OutputWindowPaneEx(DTE, "Project properties")
        project = DTE.Solution.Projects.Item(1)
        properties = project.Properties
        For Each [property] In properties
            owp.WriteLine("Name: " + [property].Name)
            owp.WriteLine("Value: " + [property].Value.ToString())
            owp.WriteLine("Type: " + [property].Value.GetType().FullName)
            owp.WriteLine()
        Next
    End Sub


    Sub SetProjectIcon()
        Dim project As EnvDTE.Project
        Dim [property] As EnvDTE.Property
        Dim projectPath As String
        project = DTE.Solution.Projects.Item(1)
        'Get the Property object for the icon:
        [property] = project.Properties.Item("ApplicationIcon")
        'Construct the path to the icon based off of the 
        ' project path:
        projectPath = project.FullName
        projectPath = System.IO.Path.GetDirectoryName(projectPath)
        projectPath = projectPath + "\Icon.ico"
        'Set the icon for the project:
        [property].Value = projectPath
    End Sub

    Sub FindMiscFilesProject()
        Dim project As EnvDTE.Project
        Dim projects As EnvDTE.Projects
        projects = DTE.Solution.Projects
        project = projects.Item(EnvDTE.Constants.vsMiscFilesProjectUniqueName)
    End Sub

    Sub CreateSolutionFolder()
        Dim solution2 As EnvDTE80.Solution2
        solution2 = CType(DTE.Solution, EnvDTE80.Solution2)
        solution2.AddSolutionFolder("My Folder")
    End Sub

    Sub CreateSolutionFolder2()
        Dim solution2 As EnvDTE80.Solution2
        Dim project As EnvDTE.Project
        Dim solutionFolder As EnvDTE80.SolutionFolder
        solution2 = CType(DTE.Solution, EnvDTE80.Solution2)
        project = solution2.AddSolutionFolder("MyFolder")
        solutionFolder = CType(project.Object, EnvDTE80.SolutionFolder)
        solutionFolder.AddSolutionFolder("My Other Folder")
    End Sub

    Sub ProjectAdd()
        Dim project As EnvDTE.Project
        Dim solutionFolder As EnvDTE80.SolutionFolder
        Dim solution2 As EnvDTE80.Solution2

        solution2 = CType(DTE.Solution, EnvDTE80.Solution2)
        project = solution2.AddSolutionFolder("MyFolder")
        solutionFolder = project.Object
        solutionFolder.AddFromFile("C:\Project\ConsoleApplication1.csproj")
    End Sub

    Sub NewProjectAdd()
        Dim project As EnvDTE.Project
        Dim solutionFolder As EnvDTE80.SolutionFolder
        Dim solution2 As EnvDTE80.Solution2
        Dim CSConsoleTemplatePath As String

        solution2 = CType(DTE.Solution, EnvDTE80.Solution2)
        project = solution2.AddSolutionFolder("MyFolder")
        solutionFolder = project.Object

        CSConsoleTemplatePath = solution2.GetProjectTemplate("ConsoleApplication.zip", "CSharp")
        solutionFolder.AddFromTemplate(CSConsoleTemplatePath, "C:\Projects\TestProject", "NewProject")
    End Sub

    Sub FindProjectInSolutionFolder()
        Dim slnFolderProject As Project
        Dim containedProject As Project
        Dim projectAsAProjectItem As ProjectItem

        'Find the solution folder. This code expects one folder and 
        '  no other items within the solution
        slnFolderProject = DTE.Solution.Projects.Item(1)

        'Find the project item for the project in the folder
        projectAsAProjectItem = slnFolderProject.ProjectItems.Item(1)

        'Convert the project item into a Project
        containedProject = projectAsAProjectItem.Object
        MsgBox(containedProject.Name)
    End Sub

    Sub FindParentProject()
        'First, find the project nested in the solution folder:
        Dim nestedProject As Project
        Dim solutionFolder As Project

        solutionFolder = DTE.Solution.Projects.Item(1)
        nestedProject = solutionFolder.ProjectItems.Item(1).Object

        'Now, find the solution folder parent of the nested project
        Dim parentProjectItem As ProjectItem
        Dim parentProject As Project
        parentProjectItem = nestedProject.ParentProjectItem
        parentProject = parentProjectItem.ContainingProject

        'Make sure the parent project and the solution folder are the same
        MsgBox(parentProject.UniqueName = solutionFolder.UniqueName)
    End Sub

    Sub FindUnmodeledProjects()
        Dim project As EnvDTE.Project
        For Each project In DTE.Solution.Projects
            If (project.Kind = EnvDTE.Constants.vsProjectKindUnmodeled) Then
                MsgBox(project.Name + " is unmodeled")
            End If
        Next
    End Sub

    Sub ChangeProjectConfiguration()
        Dim solutionBuild As EnvDTE.SolutionBuild
        Dim solutionCfgs As EnvDTE.SolutionConfigurations
        Dim solutionCfg As EnvDTE.SolutionConfiguration
        Dim solutionContext As EnvDTE.SolutionContext
        'Find the debug solution configuration:
        solutionBuild = DTE.Solution.SolutionBuild
        solutionCfgs = solutionBuild.SolutionConfigurations
        solutionCfg = solutionCfgs.Item("Debug")
        'Retrieve the solution context for the first project:
        solutionContext = solutionCfg.SolutionContexts.Item(1)
        'Change the debug solution context to build the
        ' Release project configuration:
        solutionContext.ConfigurationName = "Release"
        'Reset the build flag for this context:
        solutionContext.ShouldBuild = True
    End Sub

    Sub SetStartupProjects()
        Dim startupProjects(1) As Object
        startupProjects(0) = DTE.Solution.Projects.Item(1).UniqueName
        startupProjects(1) = DTE.Solution.Projects.Item(2).UniqueName
        DTE.Solution.SolutionBuild.StartupProjects = startupProjects
    End Sub

    Sub SetStartupProject()
        Dim startupProject As String
        startupProject = DTE.Solution.Projects.Item(1).UniqueName
        DTE.Solution.SolutionBuild.StartupProjects = startupProject
    End Sub

    Sub Depends()
        Dim projectDep As EnvDTE.BuildDependency
        Dim project As EnvDTE.Project
    Dim owp As New InsideVSNET.Utilities.OutputWindowPaneEx(DTE, "Build dependencies")

        For Each projectDep In DTE.Solution.SolutionBuild.BuildDependencies
            Dim reqProjects As Object()

            owp.Write("The project ")
            owp.Write(projectDep.Project.Name)
            owp.WriteLine(" relies on:")
            reqProjects = projectDep.RequiredProjects
            If (reqProjects.Length = 0) Then
                owp.WriteLine(vbTab + "<None>")
            Else
                For Each project In reqProjects
                    owp.WriteLine(vbTab + project.Name)
                Next
            End If
            owp.WriteLine()
        Next
    End Sub

    Sub SetDependencies()
        Dim buildDependencies As EnvDTE.BuildDependencies
        Dim buildDependency As EnvDTE.BuildDependency
        Dim project As EnvDTE.Project

        Dim winFormUniqueName As String
        Dim userControlUniqueName As String
        Dim classLibUniqueName As String

        'Gather up the unique name of each project
        For Each project In DTE.Solution.Projects
            If (project.Name = "WinForm") Then
                winFormUniqueName = project.UniqueName
            ElseIf (project.Name = "UserControl") Then
                userControlUniqueName = project.UniqueName
            ElseIf (project.Name = "ClassLib") Then
                classLibUniqueName = project.UniqueName
            End If
        Next

        buildDependencies = DTE.Solution.SolutionBuild.BuildDependencies
        For Each buildDependency In buildDependencies
            If (buildDependency.Project.Name = "WinForm") Then
                buildDependency.RemoveAllProjects()
                'Add all projects except the WinForm
                ' project as a dependency:
                buildDependency.AddProject(userControlUniqueName)
                buildDependency.AddProject(classLibUniqueName)
            ElseIf (buildDependency.Project.Name = "UserControl") Then
                buildDependency.RemoveAllProjects()
                'Add a dependency to the ClassLib project:
                buildDependency.AddProject(classLibUniqueName)
            End If
        Next
    End Sub

    Sub RetrieveDebugWin32Configuration()
        Dim config As Configuration
        Dim project As EnvDTE.Project
        project = DTE.Solution.Projects.Item(1)
        config = project.ConfigurationManager.Item("Debug", "Win32")
    End Sub

    Sub SetManagedExtensionsProperty()
        Dim configManager As ConfigurationManager
        Dim configs As Configurations
        Dim config As Configuration
        Dim project As EnvDTE.Project
        project = DTE.Solution.Projects.Item(1)
        configManager = project.ConfigurationManager
        configs = configManager.Platform("Win32")
        For Each config In configs
            Dim prop As EnvDTE.Property
            prop = config.Properties.Item("ManagedExtensions")
            prop.Value = True
        Next
    End Sub

    Sub SwapOptimizationSettings()
        Dim project As EnvDTE.Project
        Dim configManager As EnvDTE.ConfigurationManager
        Dim configs As EnvDTE.Configurations
        Dim config As EnvDTE.Configuration
        Dim props As EnvDTE.Properties

        'Find the ConfigurationManager for the project:
        project = DTE.Solution.Projects.Item(1)
        configManager = project.ConfigurationManager

        'Get the debug configuration manager
        configs = configManager.ConfigurationRow("Debug")
        'Walk each configuration in the debug configuration row
        For Each config In configs
            Dim optimize As Boolean
            'Get the Optimize property for the configuration
            props = config.Properties
            optimize = props.Item("Optimize").Value
            'Negate the value
            props.Item("Optimize").Value = Not optimize
        Next

        'Repeat for the release configuration
        configs = configManager.ConfigurationRow("Release")
        For Each config In configs
            Dim optimize As Boolean
            'Get the Optimize property for the configuration
            props = config.Properties
            optimize = props.Item("Optimize").Value
            'Negate the value
            props.Item("Optimize").Value = Not optimize
        Next

    End Sub

    Sub SolutionGlobals()
        Dim globals As EnvDTE.Globals
        globals = DTE.Solution.Globals
    End Sub

    Sub ProjectGlobals()
        Dim globals As EnvDTE.Globals
        globals = DTE.Solution.Projects.Item(1).Globals
    End Sub


End Module

Namespace InsideVSNET
    Namespace Utilities

        Class OutputWindowPaneEx
            Dim pane As OutputWindowPane
            Dim dte As EnvDTE.DTE

            Public Sub New(ByVal application As _DTE)
                dte = application
                InitPane("(Default)")
            End Sub

            Public Sub New(ByVal application As _DTE, ByVal windowName As String)
                dte = application
                InitPane(windowName)
            End Sub

            Private Sub InitPane(ByVal windowName As String)
                Dim win As Window = dte.Windows.Item(Constants.vsWindowKindOutput)
                Dim window As OutputWindow = CType(win.Object, OutputWindow)

                Try
                    pane = window.OutputWindowPanes.Item(windowName)
                Catch
                    pane = window.OutputWindowPanes.Add(windowName)
                End Try
            End Sub

            Public Sub WriteLine()
                pane.OutputString(vbLf)
            End Sub

            Public Sub WriteLine(ByVal format As String, ByVal args As Object())
                pane.OutputString(String.Format(format, args) + vbLf)
            End Sub

            Public Sub WriteLine(ByVal text As String)
                pane.OutputString(text + vbLf)
            End Sub

            Public Sub WriteLine(ByVal obj As Object)
                pane.OutputString(obj.ToString() + vbLf)
            End Sub

            Public Sub Write(ByVal format As String, ByVal args As Object())
                pane.OutputString(String.Format(format, args))
            End Sub

            Public Sub Write(ByVal text As String)
                pane.OutputString(Text)
            End Sub

            Public Sub Write(ByVal obj As Object)
                pane.OutputString(obj.ToString())
            End Sub

        End Class

    End Namespace

End Namespace