function Get-RunningDte { foreach ($progId in @('VisualStudio.DTE.17.0', 'VisualStudio.DTE.16.0')) { try { return [System.Runtime.InteropServices.Marshal]::GetActiveObject($progId) } catch { } } throw 'Could not get a running Visual Studio DTE instance.' } $path = Join-Path $PSScriptRoot 'MainShell.csproj' $xml = New-Object System.Xml.XmlDocument $xml.PreserveWhitespace = $true $xml.Load($path) $compileIncludes = @( 'Manual\ViewModel\DeviceIoViewModel.cs', 'DeviceMaintance\ViewModel\DeviceIoViewModel.cs', 'Manual\ViewModel\State\DeviceIoPageState.cs', 'DeviceMaintance\ViewModel\State\DeviceIoPageState.cs', 'Manual\View\DeviceIoView.xaml.cs', 'DeviceMaintance\View\DeviceIoView.xaml.cs' ) $pageIncludes = @( 'Manual\View\DeviceIoView.xaml', 'DeviceMaintance\View\DeviceIoView.xaml' ) foreach ($node in @($xml.SelectNodes("//*[local-name()='Compile']") | Where-Object { $compileIncludes -contains $_.GetAttribute('Include') })) { [void]$node.ParentNode.RemoveChild($node) } foreach ($node in @($xml.SelectNodes("//*[local-name()='Page']") | Where-Object { $pageIncludes -contains $_.GetAttribute('Include') })) { [void]$node.ParentNode.RemoveChild($node) } $compileAnchor = @($xml.SelectNodes("//*[local-name()='Compile']") | Where-Object { $_.GetAttribute('Include') -eq 'Manual\Model\OperateViewModelBase.cs' })[0] if ($null -eq $compileAnchor) { throw 'Could not find compile anchor.' } $ns = $xml.DocumentElement.NamespaceURI $compileGroup = $compileAnchor.ParentNode $deviceIoVmNode = $xml.CreateElement('Compile', $ns) $deviceIoVmNode.SetAttribute('Include', 'DeviceMaintance\ViewModel\DeviceIoViewModel.cs') $deviceIoStateNode = $xml.CreateElement('Compile', $ns) $deviceIoStateNode.SetAttribute('Include', 'DeviceMaintance\ViewModel\State\DeviceIoPageState.cs') $deviceIoViewCodeBehindNode = $xml.CreateElement('Compile', $ns) $deviceIoViewCodeBehindNode.SetAttribute('Include', 'DeviceMaintance\View\DeviceIoView.xaml.cs') $dependentUponNode = $xml.CreateElement('DependentUpon', $ns) $dependentUponNode.InnerText = 'DeviceIoView.xaml' [void]$deviceIoViewCodeBehindNode.AppendChild($dependentUponNode) $referenceNode = $compileAnchor foreach ($node in @($deviceIoVmNode, $deviceIoStateNode, $deviceIoViewCodeBehindNode)) { [void]$compileGroup.InsertAfter($node, $referenceNode) $referenceNode = $node } $pageAnchor = @($xml.SelectNodes("//*[local-name()='Page']") | Where-Object { $_.GetAttribute('Include') -eq 'DeviceMaintance\View\IOMonitorView.xaml' })[0] if ($null -eq $pageAnchor) { throw 'Could not find page anchor.' } $pageGroup = $pageAnchor.ParentNode $deviceIoPageNode = $xml.CreateElement('Page', $ns) $deviceIoPageNode.SetAttribute('Include', 'DeviceMaintance\View\DeviceIoView.xaml') $generatorNode = $xml.CreateElement('Generator', $ns) $generatorNode.InnerText = 'MSBuild:Compile' [void]$deviceIoPageNode.AppendChild($generatorNode) [void]$pageGroup.InsertAfter($deviceIoPageNode, $pageAnchor) $settings = New-Object System.Xml.XmlWriterSettings $settings.Indent = $true $settings.Encoding = New-Object System.Text.UTF8Encoding($true) $stringBuilder = New-Object System.Text.StringBuilder $stringWriter = New-Object System.IO.StringWriter($stringBuilder) $xmlWriter = [System.Xml.XmlWriter]::Create($stringWriter, $settings) $xml.Save($xmlWriter) $xmlWriter.Close() $stringWriter.Close() $newContent = $stringBuilder.ToString() $dte = Get-RunningDte $window = $dte.ItemOperations.OpenFile($path) Start-Sleep -Milliseconds 500 $document = $window.Document $textDocument = $document.Object('TextDocument') $editPoint = $textDocument.StartPoint.CreateEditPoint() $editPoint.Delete($textDocument.EndPoint) $editPoint.Insert($newContent) $document.Save() Write-Output 'MainShell.csproj updated through Visual Studio.'