Может ли NuGet отредактировать файл конфигурации или добавить только его?
Я работаю над пакетом NuGet для своей компании, и одним из требований является возможность обновления некоторых наших конфигурационных файлов.
Я знаю, что можно добавить в конфигурационный файл, но можно ли его изменить?
Пример:
<add name="conn" connectionString="Data Source=.\;Initial Catalog=DB;Integrated Security=True" />
изменяется ниже
<add name="conn" connectionString="Data Source=.\;Initial Catalog=DB;User ID=ex;Password=example" />
Ответы
Ответ 1
Как и в случае с NuGet 2.6 и выше, вы можете фактически преобразовать файлы Web.config с использованием синтаксиса XDT, который используется для преобразований Web.config в Visual Studio.
См. http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations:
Поддержка XML-Document-Transform (XDT)
Начиная с NuGet 2.6, XDT поддерживается для преобразования XML файлов внутри проекта. Синтаксис XDT можно использовать в файлах .install.xdt и .uninstall.xdt в папке содержимого пакета, которая будет применяться во время установки пакета и удаления, соответственно.
Например, чтобы добавить MyNuModule в файл web.config, как показано выше, следующий раздел может быть использован в файле web.config.install.xdt:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>
<modules>
<add name="MyNuModule" type="Sample.MyNuModule" xdt:Transform="Insert" />
</modules>
</system.webServer>
</configuration>
С другой стороны, чтобы удалить только элемент MyNuModule во время удаления пакета, следующий файл может быть использован в файле web.config.uninstall.xdt:
<?xml version="1.0"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.webServer>
<modules>
<add name="MyNuModule" xdt:Transform="Remove" xdt:Locator="Match(name)" />
</modules>
</system.webServer>
</configuration>
Ответ 2
Преобразования NuGet не могут редактировать существующие значения. Но NuGet позволяет запускать сценарии Powershell при установке пакета, поэтому вы можете редактировать файл конфигурации таким образом.
Создайте файл Install.ps1 и используйте этот код:
# Install.ps1
param($installPath, $toolsPath, $package, $project)
$xml = New-Object xml
# find the Web.config file
$config = $project.ProjectItems | where {$_.Name -eq "Web.config"}
# find its path on the file system
$localPath = $config.Properties | where {$_.Name -eq "LocalPath"}
# load Web.config as XML
$xml.Load($localPath.Value)
# select the node
$node = $xml.SelectSingleNode("configuration/connectionStrings/add[@name='gveconn']")
# change the connectionString value
$node.SetAttribute("connectionString", "Data Source=.\;Initial Catalog=GVE;User ID=ex;Password=example")
# save the Web.config file
$xml.Save($localPath.Value)
Ответ 3
EDIT: Ответ теперь YES с NUGET 2.6 и выше.
Ответ: NO. С сайта nuget я нашел следующий ответ:
"Когда NuGet объединяет файл преобразования в файл конфигурации проекта, он только добавляет элементы или добавляет атрибуты к существующим элементам в файле конфигурации, он не меняет существующие элементы или атрибуты каким-либо другим способом."
http://docs.nuget.org/docs/creating-packages/configuration-file-and-source-code-transformations
Ответ 4
Да, это возможно, но вы должны включить файл install.ps1 в папку инструментов. А затем, когда вы получите свой пакет с сервера nuget, visual studio запускает сценарии Powershell.
Я использую этот script
# fileName can be App.Config Or Web.Config or something else
$fileName = "App.Config"
$file=$project.ProjectItems.Item($fileName)
if($file.Properties){
# Get localpath
$localPath = $file.Properties.Item("LocalPath")
if($localPath){
$localPath = $localPath.Value
}
}
if ($localPath -eq $null) {
Exit
}
#Load our config file as XML file
[xml]$file = Get-Content $localPath
if($file){
# Create node
$childNode = $file.CreateElement("add")
$childNode.SetAttribute("connectionString", "DataSource=.\;InitialCatalog=GVE;User ID=ex;Password=example")
#Get parent node
$node = $file.SelectSingleNode("configuration/connectionStrings")
#Insert our node into parent
$node.AppendChild($childNode)
$file.Save($localPath)
}