7

パッケージ マネージャー コンソール内で powershell を使用して、ソリューションからプロジェクトを削除するスクリプトを作成しようとしていますが、驚くほど苦労しています。

プロジェクトを簡単に追加できます

PM> $dte.Solution.AddFromFile("C:\Dev\Project1.csproj")

今、私はプロジェクトを削除したいのですが、何も機能しません。

私は次のような多くのことを試しました:

PM> $project1 = Get-Project "Project1Name"
PM> $dte.Solution.Remove($project1)>

引数 "0" を値 "System.__ComObject" で "Remove" に変換できません
type "EnvDTE.Project": "型の "System.__ComObject" 値を変換できません
「System.__ComObject#{866311e6-c887-4143-9833-645f5b93f6f1}」と入力
"EnvDTE.Project"."
PM> $project = Get-Interface $project1 ([EnvDTE.Project])
PM> $dte.Solution.Remove($project)

Cannot convert argument "0", with value: "System.__ComObject", for "Remove" to
type "EnvDTE.Project": "Cannot convert the "System.__ComObject" value of type
"NuGetConsole.Host.PowerShell.Implementation.PSTypeWrapper" to type
"EnvDTE.Project"."
PM> $project = [EnvDTE.Project] ($project1)

Cannot convert the "System.__ComObject" value of type
"System.__ComObject#{866311e6-c887-4143-9833-645f5b93f6f1}" to type
"EnvDTE.Project".
PM> $solution2 = Get-Interface $dte.Solution ([EnvDTE80.Solution2])
PM> $solution2.Remove($project1)

Exception calling "Remove" with "1" argument(s): "Exception calling
"InvokeMethod" with "3" argument(s): "Object must implement IConvertible.""
PM> $dte2 = Get-Interface $dte ([EnvDTE80.DTE2])
PM> $dte2.Solution.Remove($project)

Method invocation failed because [System.Object[]] doesn't contain a method
named 'Remove'.

他の組み合わせも試しましたが、明らかに車輪が回っています。提案をいただければ幸いです。

4

2 に答える 2

5

パーティーに遅れていることは承知していますが、私たちが作成している内部 NuGet パッケージで同じ問題に取り組んでおり、その方法を見つけたと思います。

実際、Microsoft は (助けになったように) Delete メソッドを未実装のままにしており、両方が発見したように、 Solution2インターフェイスでRemoveメソッドを呼び出そうとすると、コンテキストに応じて刺激的な無数のエラーがスローされます!

ただし、私が見つけたのは、 SolutionClassで定義されているRemoveメソッドを直接呼び出すと、実際に機能することです (Microsoft によって内部使用のみとして文書化されていますが、他のすべてのオプションが使い果たされた場合...)。唯一の問題は、ランタイム バインダーもメソッドのオーバーロードの解決に失敗し、エラーが発生する場合があることです。

No overload for method 'Remove' takes 1 arguments

つまり、反射クレヨンを出す時が来たということです。コードは次のようになります。

$removeMethod = [EnvDTE.SolutionClass].GetMethod("Remove");
$solution = $dte.Solution;
$toremove = ($solution.Projects | where ProjectName -eq "<whatever>");
$removeMethod.Invoke($solution, @($toremove));

さまざまな反復 (多くは問題のものに非常に似ています) とさまざまな程度の成功 (パッケージ マネージャー内で実行していたか、インストール スクリプト内から実行しているか、デバッガー内で実行しているかによって異なります) の 1 日の後、上記は私が見つけたものです。最も信頼できること。

注意すべきことの 1 つは、反映されたメソッドが で定義されているため、EnvDTE.SolutionClassそれを渡すEnvDTE._SolutionかエラーをEnvDTE80.Solution2スローするため、残念ながらコマンドレット (通常はこれが私の好みの方法です) でオブジェクトをType mismatch取得できないことです。可能な限りキャストを行うことは明らかに望ましいことですが、繰り返しになりますが、そうすることでさまざまな程度の成功が見られました。したがって、上記は少しずさんです。$solutionGet-Interface[EnvDTE.SolutionClass]$solution = $dte.Solution

これが他の誰かに役立つことを願っています!

于 2015-02-12T17:15:18.563 に答える