0

I am trying to write a NuGet package init.ps1 script that will modify one value of a .targets file (XML) and save the document. The script does everything successfully without error, but when I check the document it has not been changed.

Here is the script:

Param($installPath, $toolsPath, $package)

$proj = Get-Project
$pack = $package

# Detect if the project installing the NuGet package is a web application and
# alters an xml element value in the .targets value to prevent duplication
# of application resources when published.

if ($proj.ExtenderNames -contains "WebApplication") {
    # Begin to build neccessary path strings to find the .targets file.
    # The targets file is currently located in
    # \packages\packageName.packageVersion\build\packageName.targets.
    $packageName = [string]$pack.Id

    $packageRootDir = $installPath

    # packageName.Version\build
    $packageBuildFolderPath = Join-Path $packageRootDir "build"

    # packageName.Version\build\packageName
    $targetsFilePath = Join-Path $packageBuildFolderPath ($packageName + ".targets")
    "$targetsFilePath"

    if (Test-Path $targetsFilePath) {
        # If the targets file path has correctly located the file then
        # we edit the targets file to alter the CopyToOutputDirectory element.

        # Load the targets file as an xml object
        $xml = New-Object System.Xml.XmlDocument
        $xml.Load($targetsFilePath)
        "xml loaded"
        # Search each ItemGroup element for the one containing a Content element.
        foreach ($group in $xml.Project.ItemGroup) {
            $nodeExists = $group.Content.CopyToOutputDirectory

            if ($nodeExists) {
                "$nodeExists"
                # Edits the value when we find the correct node
                $nodeExists = "Never"
                "$nodeExists"
            }
        }
        "xml modified"

        # Save the updated document to the correct place.
        $savePath = [string]$targetsFilePath
        "$savePath"
        $xml.Save($savePath)
        "xml Saved to $savePath"
    }
}

And here is the Package Manager Output from the beginning to end of the script block:

Executing script file 'path to tools/Init.ps1'
'correct path to package/build/package.targets'
xml loaded
Always
Never
xml modified
'correct path to package/build/package.targets'
xml Saved to 'correct path to package/build/package.targets'
Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
BHigzz
  • 45
  • 1
  • 5

1 Answers1

1

Your code modifies the value of the variable $nodeExists, but not the XML node that value came from. You can verify that by taking a look at the actual XML data after the loop:

$xml.Save([Console]::Out)

To actually modify the value of the node change your code to something like this:

foreach ($group in $xml.Project.ItemGroup) {
    if ($group.Content.CopyToOutputDirectory) {
        $group.Content.CopyToOutputDirectory = 'Never'
    }
}

or like this:

$xml.SelectNodes('//Content/CopyToOutputDirectory') | ForEach-Object {
    $_.'#text' = 'Never'
}

Note that the latter requires a namespace manager if your XML uses namespaces.

Ansgar Wiechers
  • 193,178
  • 25
  • 254
  • 328
  • Thank you for the reply, this was indeed one of the issues. A different issue I was having was in VS 2012 the init.ps1 script would be called, and then the .targets file was copied over so it would overwrite it; but that is not within the scope of this question. – BHigzz Sep 25 '17 at 19:31