Is it possible to change the contents of a file that exists via a NuGet package? Meaning, let's say you make a brand new MVC3 website. You want to install a NuGet package that will update the home page. Maybe change the welcome message and then change the layout to include some new View you've created and update the Home Controller to include a method to return your new View. How would this be done?
2 回答
After you've installed the NuGet Package you can manually modify any files you want. Just edit them in VS (or with another editor). The only difference regarding NuGet packages is that your modified files won't be removed if you uninstall/update the package as changes are detected between the original package files and your files. There's going to be a mention of this is the logs.
Update:
NuGet has supports for modifying project files during a package installation through .transform and .pp files. But this has limitations, .transform files adds content to config files (they can't edit) while .pp files are for new source code files.
You can modify existing source code using EnvDte CodeModel in PowerShell (i.e. install.ps1). It's a bit more complex though.
If you open up the JQuery NuGet package in NuGet Package Explorer (or just unzip the package) and look at install.ps1 and common.ps1, then you can see an example where they automatically add a line to _references.js for JQuery so that the JQuery API will show up in IntelliSense.
But yes, it is a fairly complex process to automatically update code (especially code that people can edit). The JQuery example involves using a regular expression to look for an existing reference before updating it, and all this does is add/update a one-line comment to a particular file in a known location (and it shouldn't break the build if it goes wrong, since it is just a comment).
I would love to see more examples and even a library of helper functions for things like the OP's request.
Here's one function from common.ps1:
function AddOrUpdate-Reference($scriptsFolderProjectItem, $fileNamePattern, $newFileName) {
try {
$referencesFileProjectItem = $scriptsFolderProjectItem.ProjectItems.Item("_references.js")
}
catch {
# _references.js file not found
return
}
if ($referencesFileProjectItem -eq $null) {
# _references.js file not found
return
}
$referencesFilePath = $referencesFileProjectItem.FileNames(1)
$referencesTempFilePath = Join-Path $env:TEMP "_references.tmp.js"
if ((Select-String $referencesFilePath -pattern $fileNamePattern).Length -eq 0) {
# File has no existing matching reference line
# Add the full reference line to the beginning of the file
"/// <reference path=""$newFileName"" />" | Add-Content $referencesTempFilePath -Encoding UTF8
Get-Content $referencesFilePath | Add-Content $referencesTempFilePath
}
else {
# Loop through file and replace old file name with new file name
Get-Content $referencesFilePath | ForEach-Object { $_ -replace $fileNamePattern, $newFileName } > $referencesTempFilePath
}
# Copy over the new _references.js file
Copy-Item $referencesTempFilePath $referencesFilePath -Force
Remove-Item $referencesTempFilePath -Force
}