我正在尝试在程序包管理器控制台中使用powershell来编写从解决方案中删除项目的脚本,并且我遇到了非常困难的时间。
我可以通过
轻松添加项目PM> $dte.Solution.AddFromFile("C:\Dev\Project1.csproj")
现在我想要删除一个项目,但无法正常工作。
我尝试过很多方面,包括:
PM> $project1 = Get-Project "Project1Name"
PM> $dte.Solution.Remove($project1)
>
Cannot convert argument "0", with value: "System.__ComObject", for "Remove" to
type "EnvDTE.Project": "Cannot convert the "System.__ComObject" value of type
"System.__ComObject#{866311e6-c887-4143-9833-645f5b93f6f1}" to type
"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'.
我尝试了其他组合,但我显然在转动轮子。我很感激任何建议。
答案 0 :(得分:5)
是的,我知道我已经迟到了,但我刚刚为我们写过的内部NuGet包解决了同样的问题,我想我已经找到了怎么做。
事实上,微软已经(帮助)离开了删除方法unimplemented,正如我们发现的那样,尝试在Remove界面上调用Solution2方法会引发令人兴奋的无数错误视情况而定!
然而,我发现直接调用Remove中定义的SolutionClass方法确实有效(尽管它被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));
经过一天的各种迭代(许多与问题中的那些非常相似)和不同程度的成功(取决于我是在包管理器内执行,从安装脚本内部还是在调试器内执行),上面是什么我发现最可靠。
需要注意的一点是,因为反映的方法在EnvDTE.SolutionClass
中定义,传递EnvDTE._Solution
或EnvDTE80.Solution2
会引发Type mismatch
错误,所以很遗憾您无法获取$solution
cmdlet(通常是我首选的方法)的Get-Interface
对象。尽可能在[EnvDTE.SolutionClass]
进行投射显然是可取的,但我再次发现这样做有不同程度的成功。因此上面略显草率$solution = $dte.Solution
。
希望这对其他人有用!
答案 1 :(得分:1)
看起来像是“删除”而不是“删除”。见MSDN article
Project prj = dte.Solution.Projects.Item(1);
prj.Delete();