3

私は膨大な数のプロジェクトを持つ大規模なコード ベースで作業しています。各プロジェクトには、他への参照が少数 (場合によっては膨大) あります。時間の経過とともに、このコードベースに対して大幅なリファクタリングが行われました。その結果、他の場所に移動したクラスを含んでいたという理由だけで、一部のプロジェクトによって参照される多くのアセンブリが存在します。そのようなこと。

ReSharper には IDE に統合されたツールがあり、ユーザーは特定のプロジェクトの特定の参照を実際に使用するコードを見つけることができますが、これをソリューションに変えるには、すべてのプロジェクトのすべての参照を右クリックする必要があります。そして、実際に使用されていないことを確認してから削除します。これは長いプロセスであるだけでなく、拷問に近い.

このプロセスを自動化して、実行するだけで不要な参照が削除されるようにしたいと考えています。その後、何らかの通常のプロセスに統合して、見落とされた間違いを見つけられるようにすることができます。

私が考えた 2 つのオプションは、A) 可能であれば Powershell を使用して ReSharper を自動化するか、B) おそらく Visual Studio 2010 アーキテクチャの依存関係図でこれを処理でき、運が良ければスクリプト可能な方法で処理できるでしょう。

私の質問は次のとおりです。

  • ReSharper でこのようなスクリプトを作成できますか?
  • VS2010 アーキテクチャは、何らかのバッチ/自動化された方法で未使用の参照を削除できますか?
4

3 に答える 3

6

単純なpowershellだけでこれを行うことができるはずです:

1) Visual Studio にソリューションをロードする

2) ソリューション全体をコンパイルする

3) VS を実行したままにして、powershell.exe を開始します。

4) ROT から VS の DTE の実行中のインスタンスへの参照を取得します (重要 - 実行中のインスタンスが 1 つだけであることを確認してください - 昇格した場合は、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 がコードで実際に参照されているアセンブリのみをリンクするためです。申し訳ありませんが、完全に機能する例を投稿することはできませんが、始めるにはこれで十分です。

-オイシン

于 2011-01-29T05:41:37.040 に答える
1

@ x0nの指示に従いましたが、うまくいきませんでした。多分私は何かが欠けていました。COMエラーのためにをdllロードできなかったことを認める必要があります。ReflectionOnlyLoadだから私はそれらをロードしましたLoadFile。によって提供されるアセンブリ参照はLoadFile、Reflectorを使用してアセンブリをロードしたときとまったく同じでした。最後に、PowerShellスクリプトは、プロジェクトにはあるがアセンブリによってロードされていない参照を示すリストを生成しました。理論的には、これらは「不要な」参照であると考えられています。それらを削除し始めたとき、ビルドは失敗しました。たとえば、私の最初のプロジェクトの場合、4つの「不要な」参照のいずれかがないと、ビルドが失敗します。PowerShellスクリプトの出力をざっと見てみると、「System"も例です。これを削除しても、コンパイラは" "の束についても文句を言いませんusing System;が、その前に失敗します-インターフェイスのためにそのアセンブリを参照する必要があると述べています...ところで、私たちのプロジェクトはおもちゃ、それは140以上のdll(そのほとんど半分はテストnUnitdllです)を含み、私はいくつかのハウスキーピングを行うと思いました私のスクリプト(プロジェクトフォルダに再帰的には入りません-いくつかのプロジェクトにはより多くの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
                    }
                }
            }
        }
    }
}

`

于 2012-12-05T00:49:12.197 に答える
1

完全な解決策ではありませんが、プロジェクトが bin からのアセンブリにも依存している場合の csproj の依存関係の解決とPowerShell を介して間違ったアセンブリの依存関係を見つける方法 をご覧ください。他のプロジェクトへの参照を見つける方法と、アセンブリ内の参照を見つける方法があります。

2 番目の部分は、Oisin が提案したものと同じです。最初のものは少し異なります - csproj ファイルから参照を取得します (xml ファイルとして取得され、この方法で処理されます)。

少なくともインスピレーションとして受け取ってください ;)

于 2011-01-29T20:45:20.463 に答える