【问题标题】:C#: Automated removal of unnecessary assembly references?C#:自动删除不必要的程序集引用?
【发布时间】:2011-01-28 18:37:14
【问题描述】:

我正在处理包含大量项目的大型代码库,每个项目都有少量(在某些情况下,大量)对其他项目的引用。随着时间的推移,对这个代码库进行了大量的重构,结果有许多程序集被一些项目引用,只是因为它们曾经包含一个已经转移到其他地方的类;那种东西。

ReSharper 有一个集成到 IDE 中的工具,允许用户查找实际使用给定项目的给定引用的代码,但是为了将其转化为解决方案,我们需要让一个人右键单击每个引用在每个项目中,然后实际检查没有使用然后删除它们,这不仅是一个漫长的过程,而且接近于折磨。

我希望能够自动执行此过程,以便我们只运行它并删除不必要的引用;然后,我们或许可以将其整合到某种常规流程中,以便发现被忽略的错误。

我想到的两个选项是 A) 如果可能的话,使用 Powershell 自动化 ReSharper,或者 B) 也许 Visual Studio 2010 架构依赖关系图可以处理这个问题,如果幸运的话,也许可以以可编写脚本的方式处理。

我的问题是:

  • 可以为 ReSharper 编写这样的脚本吗?
  • VS2010 架构是否提供以任何类型的批处理/自动方式删除未使用的引用?

【问题讨论】:

    标签: powershell automation resharper assembly-references


    【解决方案1】:

    你应该可以用简单的 powershell 来做到这一点:

    1) 使用您的解决方案加载 Visual Studio

    2) 编译整个解决方案

    3) 让VS运行并启动powershell.exe

    4) 从 ROT 中获取对仍在运行的 VS 的 DTE 实例的引用(重要 - 确保只有一个实例在运行 - 如果它被提升,powershell 也应该是):

    ps> $dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("visualstudio.dte")
    

    5) 通过枚举解决方案中的所有项目及其引用进行测试:

    ps> $dte.solution.projects | select @{l="name";e={$_.name}}, `
            @{l="references";e={$_.object.references|select -exp name}} | ft -auto
    

    ...转储所有项目名称和引用...

    6) 现在,编写一些脚本来遍历解决方案文件夹和项目

    7) 当你点击 bin\ 文件夹时,只加载反射加载程序集:

    $assembly = [reflection.assembly]::reflectiononlyload($dll)
    

    8) 在输出程序集中获取实际引用的程序集

    $refs = $assembly.getreferencedassemblies()
    

    9)将实际引用的程序集与项目中引用的程序集进行比较,并通过VS DTE对象模型删除冗余的程序集

    # example
    $currentproj.object.references.item("system.core").remove()
    $currentproj.save()
    

    10) 利润!

    这是可行的,因为 .net 仅链接代码中实际引用的程序集。抱歉,我无法发布完整的工作示例,但这应该足以让您入门。

    -奥辛

    【讨论】:

    • 现在已经很晚了,但我会在本周末尝试在我的博客 (www.nivot.org) 上写一个完整的工作示例
    • 5) 不返回任何内容。没有可用的属性references
    【解决方案2】:

    不是完整的解决方案,但请查看 Resolve csproj dependencies when projects are dependent on assemblies from bin as wellHow to find wrong assembly dependencies via PowerShell。有一种方法可以找到对其他项目的引用以及如何在程序集中找到引用。

    第二部分与 Oisin 提出的相同。第一个略有不同 - 它从 csproj 文件中获取引用(作为 xml 文件并以这种方式处理)。

    至少把它当作一种灵感;)

    【讨论】:

      【解决方案3】:

      我按照@x0n 的说明进行操作,但对我来说效果不佳。也许我错过了什么。我不得不承认,由于 COM 错误,我无法用ReflectionOnlyLoad 加载我的dlls。所以我给他们加载了LoadFileLoadFile 提供的程序集引用与我使用 Reflector 加载程序集时完全相同。最后,我的 PowerShell 脚本生成了一个列表,其中显示了项目中但程序集未加载的引用。从理论上讲,这些应该是“不必要的”引用。当我开始删除它们时,构建失败了。例如,在我的第一个项目中,缺少 4 个“不必要的”引用中的任何一个都会导致构建失败。例如,我浏览了 powershell 脚本的输出,它也列出了“System”。如果我删除它,编译器甚至不会抱怨一堆“using System;”,但在此之前它会失败 - 说明我需要因为接口而引用该程序集...... 顺便说一句,我们的项目不是玩具,它涉及 140 多个 dll(尽管其中几乎一半是 Test nUnit dll),我想我会做一些家务。 我的脚本(不会递归进入项目文件夹 - 一些项目包含更多 dll)所以也许有人可以使用它:

      `
      $dte = [System.Runtime.InteropServices.Marshal]::GetActiveObject("visualstudio.dte")

      $binfiles=Get-ChildItem C:\YourSourcePath\bin\debug
      $dlls=$binfiles | where { $_.extension -eq ".dll" -and $_.name -like "*YourCompanyName*" }
      
      foreach ($dll in $dlls) {
          foreach($prj in $dte.solution.projects) {
              if ($prj.Kind -eq "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") {
                  if ($prj.Properties.Item("OutputFileName").Value -eq $dll.Name) {
                      $loaded = [reflection.assembly]::LoadFile($dll.FullName)
                      $refs = $loaded.GetReferencedAssemblies()
                      Write "============="
                      Write $dll.Name
                      Write "-------------"
                      foreach($pref in $prj.Object.References) {
                          $found = 0
                          foreach($ref in $refs) {
                              if ($ref.Name -eq $pref.Name) {
                                  $found = 1
                                  break;
                              }
                          }
                          if ($found -eq 0) {
                              Write $pref.Name
                          }
                      }
                  }
              }
          }
      }
      

      `

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-10
        • 2011-09-26
        • 2012-04-20
        • 2010-09-13
        • 2013-07-25
        • 2019-12-26
        相关资源
        最近更新 更多