0

作为一个 PowerShell 新手,我终于能够编写一个 PowerShell 脚本来修补我的 Delphi 项目文件。只有一件奇怪的事情:Powershell 输出一个字符串,用作方法调用的参数:

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 $_ }

当我使用InnerText属性而不是set_InnerText()访问器时,会发生相同的不需要的输出。

$my_root.InnerText = 'P:\MyProject'

我将我的 PowerShell 升级到了 7.1 版。

我想知道它是否可能是...的调试输出System.Xml.Element.set_InnerText()?或者这是 PowerShell 的已知副作用?还是我错过了什么?

解决方案

正如评论中所解释的,解决方案是通过将此方法调用分配给来抑制隐式输出$null

$null = $my_root.set_InnerText('P:\MyProject')
4

0 回答 0