As a PowerShell newbie, I've finally been able to write a PowerShell script to patch my Delphi projects files. There is just one weird thing : Powershell Outputs a string that is used as an argument to a method call :
function PatchProject($ProjectFile) {
# Write-Host "Processing " $ProjectFile
[xml]$xml = Get-Content -Path $ProjectFile
# We need a XmlNamespaceManager to process XPath Queries
[System.Xml.XmlNamespaceManager] $nsm = New-Object System.Xml.XmlNamespaceManager $xml.NameTable
$nsm.AddNamespace("ns", "http://schemas.microsoft.com/developer/msbuild/2003");
$changed = $false
If ($xml.Project.SelectSingleNode('ns:PropertyGroup[not(@Condition)]/ns:MyProjectRoot', $nsm) -eq $null) {
# Create new variable node
$my_root = $xml.CreateElement('MyProjectRoot', $xml.Project.NamespaceURI)
###########
###########
$my_root.set_InnerText('P:\MyProject') # "P:\MyProject" is printed on the console, why ?!?
###########
###########
# Find first <PropertyGroup> and append <MyProjectRoot>...</MyProjectRoot> to it
$pg = $xml.Project.SelectSingleNode('ns:PropertyGroup[not(@Condition)]', $nsm);
$pg.AppendChild($my_root)
$changed = $true
}
If ($xml.Project.SelectSingleNode('ns:Import[@Project="$(MyProjectRoot)\ide\Delphi.VersionInfo.targets"]', $nsm) -eq $null) {
# Add a node <Import Project="..." Condition="..." />
$import = $xml.CreateElement('Import', $xml.Project.NamespaceURI)
$import.SetAttribute('Condition', "`$(FileVersion)!='' and Exists('`$(MyProjectRoot)\ide\Delphi.VersionInfo.targets')")
$import.SetAttribute('Project', "`$(MyProjectRoot)\ide\Delphi.VersionInfo.targets")
# Find last <Import .../>
$last_import = $xml.Project.SelectSingleNode('ns:Import[last()]', $nsm)
# Insert this node after the very last <Import... />
$xml.Project.InsertAfter($import, $last_import)
$changed = $true
}
If ($changed -eq $true) {
# Set Project MSBUILD ToolsVersion
$xml.Project.SetAttribute('ToolsVersion', '4.0')
# Write preserving Delphi indentation settings
$settings = New-Object System.Xml.XmlWriterSettings
$settings.OmitXmlDeclaration = $true
$settings.Indent = $true
$settings.IndentChars = " "
$writer = [System.XML.XmlWriter]::Create($ProjectFile, $settings)
$xml.Save($writer)
$writer.Close()
$xml = $null
# Reformat file to match Delphi syntax
$lines=@(Get-Content -Path $ProjectFile)
$newlines = @()
foreach ($line in $lines) {
$new_line = $line -Replace " />", "/>"
$newlines += $new_line
}
$newlines | Set-Content -Encoding UTF8 -Path $ProjectFile
}
# Write-Host "Processed " $ProjectFile
}
Write-Host "Finding .dproj..."
$files = Get-ChildItem -Path .\ -Filter *.dproj -Recurse -File -Name
Write-Host "Patching .dproj..."
$files | ForEach-Object { PatchProject $_ }
The same unwanted output happens when I use the InnerText
property instead of the set_InnerText()
accessor.
$my_root.InnerText = 'P:\MyProject'
I upgraded my PowerShell to version 7.1.
I'm wondering whether it could be a debug output from System.Xml.Element.set_InnerText()
... ? Or is this a known side effect of PowerShell ? Or did I missed something ?
Solution
As explained in comments the solution is to suppress implicit output by assigning this method call into $null
:
$null = $my_root.set_InnerText('P:\MyProject')