【问题标题】:Replace multi-line text(code) in file using powershell 2使用powershell 2替换文件中的多行文本(代码)
【发布时间】:2015-03-23 23:59:41
【问题描述】:

我正忙于创建一个仅在内部使用的 Nuget 包,它安装其他包作为依赖项,Ninject 就是其中之一。

安装后,会在项目的 App_Start 文件夹中添加一个 NinjectWebCommon.cs 文件。我的自定义包需要通过以下方式修改该文件:(仅显示部分代码)

//code above removed... 
using Ninject;
using Ninject.Web.Common;
//modified this part already - refer to block quote 1 on how i did it
using mylibrary.whatever;
//code below removed...

我设法通过以下方式使用 install.ps1(根据 Nuget 包约定)插入“使用 mylibrary.whatever”行,尽管不是那么复杂(对 powershell 的经验很少):

引用 1:
$p = 获取项目;
$p = 分割路径 $p.filename;
$p += "\App_Start\NinjectWebCommon.cs";
(获取内容 $p)| foreach-object {$_ -replace "使用 Ninject.Web.Common;", "使用 Ninject.Web.Common;`r`n 使用 mylibrary.whatever;"} |设置内容 $p;

现在添加 1 行就可以了。

我的问题在于更改此部分...

// code above removed...
private static void RegisterServices(IKernel kernel)
{
}
// code below removed...

到这个...

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
}
// code below removed...

更复杂一点的是,这个 NinjectWebCommon.cs 文件可以通过 x 数量的内部 Nuger 包以相同的方式进行更改。所以

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
}
// code below removed...

也可以变成

// code above removed...
private static void RegisterServices(IKernel kernel)
{
    kernel.Load(new mylibrarymodule());
    kernel.Load(new myotherlibrarymodule());
    kernel.Load(new anotherlibrarymodule());
}
// code below removed...

任何帮助将不胜感激,因为 powershell 不是我的强项之一......

【问题讨论】:

    标签: powershell visual-studio-2013 powershell-2.0 nuget-package


    【解决方案1】:

    在我的 install.ps1 中通过大量的 T&E 最终解决了这个问题:

    install.ps1 在我的 Nuget 包中:

    #Get the file:
    $p = get-project;
    $p = Split-path $p.filename;
    $p += "\App_Start\NinjectWebCommon.cs";
    
    # Do the first insert
    $regex = new-object Text.RegularExpressions.Regex "using Ninject.Web.Common;", ('singleline');
    
    set-content $p $regex.Replace((get-content $p) -join "`n", "using Ninject.Web.Common;`n`tusing mylibrary.whatever;")
    
    # Do second insert
    $regex = new-object Text.RegularExpressions.Regex "private static void RegisterServices\(IKernel kernel\)\s*\{", ('singleline','multiline');
    
    set-content $p $regex.Replace((get-content $p) -join "`n", "private static void RegisterServices(IKernel kernel)`n`t`t{`n`t`t`tkernel.Load(new myclass_in_mylibrary.whatever());")
    

    归功于:

    Matt Ward 的回答 here
    Stej的回答here

    下一个挑战是在文件被编辑后允许完全卸载文件,因为如果文件被修改,Nuget 不允许卸载... *sigh...

    【讨论】:

      【解决方案2】:

      我对 ps 也很陌生,必须进行一些搜索和测试才能得出这个结论:

      $fileName="C:\tmp\YourFileName"
      $searchString="Primary search string here" #In your case it's: "private static void RegisterServices(IKernel kernel)"
      $searchStrFound=0
      
      (Get-Content $fileName) | 
      Foreach-Object {
          #Send each line to output
          $_
          if ($_ -match $searchString)
          {
              #We found the actual search string
              $searchStrFound=1
          }
          if ($searchStrFound=1 -And $_ -match "\{")
          #If search string is already found and current line is {
          {
              "Insert your text here"
              "Insert Line 2 here"
              "Insert whatever here..."
              $searchStrFound=0 #Reset value to 0 so that you won't change anything else
          }
      } | Set-Content $fileName
      

      我用你的方法试过了

      // code above removed...
      private static void RegisterServices(IKernel kernel)
      {
      }
      // code below removed...
      

      示例,它工作得很好。

      希望对你有帮助

      /ut

      【讨论】:

      • 感谢@uTe1sT 的回答,但它在完整文件中添加了多个插入。您可以通过安装 Ninject.web 数据包来测试这一点,并尝试在 App_Start 目录中的 NinjectWebCommon.cs 文件上执行此操作。昨天我确实设法获得了一个可行的解决方案,并为其他人的需求添加了答案...看到您的可行版本会很有趣,因为我不知道 |解决方案一直有效,谢谢! :-)
      【解决方案3】:

      我实际上会推荐另一种方式:不要覆盖该文件,创建您自己的 MyNinjectBindings 并通过自述文件指示开发人员手动将调用添加到您的代码中,以便它注册您的绑定。

      这样,如果您的包更新,MyNinjectBindings 也会更新,但开发人员可能添加到 NinjectWebCommon.cs 的自定义代码仍然存在。

      我认为这是一种侵入性较小且更灵活的方式。

      谢谢

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-10-06
        • 2021-01-12
        • 1970-01-01
        • 2015-03-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-02
        相关资源
        最近更新 更多