【问题标题】:How Do You Change an Existing File Via a NuGet Package Install?如何通过 NuGet 包安装更改现有文件?
【发布时间】:2012-04-26 20:35:39
【问题描述】:

是否可以更改通过 NuGet 包存在的文件的内容?意思是,假设您创建了一个全新的 MVC3 网站。您想要安装将更新主页的 NuGet 包。也许更改欢迎消息,然后更改布局以包含您创建的一些新视图,并更新主控制器以包含返回新视图的方法。这将如何实现?

【问题讨论】:

    标签: nuget nuget-package


    【解决方案1】:

    安装 NuGet 包后,您可以手动修改所需的任何文件。只需在 VS(或使用其他编辑器)中编辑它们。关于 NuGet 包的唯一区别是,如果您卸载/更新包,则不会删除您修改过的文件,因为在原始包文件和您的文件之间检测到更改。会提到这是日志。

    更新:

    NuGet 支持在包安装期间通过.transform and .pp files 修改项目文件。但这有局限性,.transform 文件将内容添加到配置文件(它们无法编辑),而 .pp 文件用于新的源代码文件。

    您可以在 PowerShell 中使用 EnvDte CodeModel 修改现有源代码(即 install.ps1)。虽然它有点复杂。

    【讨论】:

    • 这不是我的意思。我的意思是您可以通过安装本身更改文件吗?例如,我听说您可以更改 NuGet 包中的 web.config。比如,一些指令或脚本等?我想您可以通过脚本更改任何文件,但是有一些典型的方法吗?因此,当您安装一个软件包时,您会添加一些新文件,但您现有的一些文件会被更改。例如,可能会更改 default.aspx 的内容。明白我的意思了吗?
    • 现在知道了,我在上面更新了我的答案。简而言之,nuget 已经支持 .pp/.transform 文件中的常见简单场景。 NuGet 不支持修改现有代码,将通过 powershell 脚本完成。我会查看 CodeModel,但找不到简单的示例。
    • 我看到了关于拥有文件的东西——我认为是 pp 文件——你会留下变量而不是命名空间之类的东西,它会从项目文件等中获取它,但是实体框架如何包,例如,添加 web.config 节点?有脚本吗?
    • 他们的包内容中有一个“Web.config.transform”文件。基本上当 NuGet 安装包时,它会将 Web.config.transform 文件内容与 web.config 合并。 (和 app.config.transform 到 app.config)
    【解决方案2】:

    如果您在 NuGet 包资源管理器中打开 JQuery NuGet 包(或者只是解压缩包)并查看 install.ps1 和 common.ps1,那么您可以看到一个示例,其中它们自动将一行添加到 _references.js JQuery 以便 JQuery API 将显示在 IntelliSense 中。

    但是,是的,自动更新代码(尤其是人们可以编辑的代码)是一个相当复杂的过程。 JQuery 示例涉及在更新之前使用正则表达式查找现有引用,所有这些都是在已知位置向特定文件添加/更新单行注释(如果它不应该破坏构建出错了,因为它只是一个评论)。

    我希望看到更多示例,甚至是用于 OP 请求之类的辅助函数库。

    这是来自 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
    }
    

    【讨论】:

    • 谢谢!一个非常“你好,世界!”的例子。
    猜你喜欢
    • 2013-02-15
    • 1970-01-01
    • 2015-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    • 1970-01-01
    相关资源
    最近更新 更多