通过包管理器控制台从溶液中取出项目 [英] Remove project from solution via Package Manager Console

查看:221
本文介绍了通过包管理器控制台从溶液中取出项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想包管理器控制台中使用PowerShell脚本删除一个项目从解决方案,我有一个令人惊讶的日子不好过。

我可以很容易地通过

添加项目

  PM>  $ dte.Solution.AddFromFile(C:\\开发\\ Project1.csproj)  

现在我想删除一个项目,并不能得到任何工作。

我已经尝试了一些事情,包括:

  PM>  $ PROJECT1 =获取项目Project1Name
PM> $ dte.Solution.Remove($ PROJECT1)
>无法转换参数为0,与价值:系统.__ ComObject,为删除,以
键入EnvDTE.Project:不能转换型的系统.__ ComObject的价值
系统.__ ComObject#{866311e6-c887-4143-9833-645f5b93f6f1}键入
EnvDTE.Project。

  PM>  $项目=获取接口$ PROJECT1([EnvDTE.Project])
PM> $ dte.Solution.Remove($项目)无法转换参数为0,与价值:系统.__ ComObject,为删除,以
键入EnvDTE.Project:不能转换型的系统.__ ComObject的价值
NuGetConsole.Host.PowerShell.Implementation.PSTypeWrapper键入
EnvDTE.Project。

  PM>  $项目= [EnvDTE.Project]($ PROJECT1)无法将类型的系统.__ ComObject的价值
系统.__ ComObject#{866311e6-c887-4143-9833-645f5b93f6f1}键入
EnvDTE.Project。

  PM>  $ solution2 =获取接口$ dte.Solution([EnvDTE80.Solution2])
PM> $ solution2.Remove($ PROJECT1)异常调用删除和1的说法(S):异常调用
的InvokeMethod和3的说法(S):对象必须实现IConvertible

  PM>  $ DTE2 =获取接口$ DTE([EnvDTE80.DTE2])
PM> $ dte2.Solution.Remove($项目)方法调用失败,因为[System.Object的[]中不包含的方法
名为删除。

我也试过其他的组合,但我清楚我的纺轮。我AP preciate任何建议。


解决方案

好吧,我知道我迟到了,但我刚刚解决这个同样的问题,因为我们已经写了一个内部​​的NuGet包,我想我已经找到了如何做到这一点。

事实上,微软有(有益)离开了删除方法未实现,当我们同时拥有发现,试图调用的上的法 =nofollow的> Solution2 接口抛出根据上下文错误的一个令人兴奋的无数!

不过我发现是直接调用删除 SolutionClass 定义方法不实际工作(尽管它被微软记录为内部使用。但是,嘿,当所有其他选项耗尽...)。唯一的缺点是,运行时绑定有时也似乎未能解决方法重载,产生错误:

 无过载方法'删除'需要1参数

所有这一切都意味着,是时候让我们反思蜡笔出来!在code是这样的:

  $ removeMethod = [EnvDTE.SolutionClass] .GetMethod(删除);
$液= $ dte.Solution;
$的文档,删除=($ solution.Projects |其中projectname当量<凡是>);
$ removeMethod.Invoke(

解决方案

,@($的文档,删除));

各代的一天后(很多非常类似于那些在问题),并不同程度的成功(取决于我是否包管理器内部执行,从内安装脚本或调试器中),上面是什么我发现是最可靠的。

有一点需要注意的是,由于反射的方法是在 EnvDTE.SolutionClass 定义的,它传递一个 EnvDTE._Solution EnvDTE80.Solution2 抛出一个类型不匹配错误,所以很遗憾你不能获得你的

解决方案

获取接口 cmdlet的(这通常是我的preferred法)的对象。做演员到 [EnvDTE.SolutionClass] 尽可能显然是preferable,但同样我发现不同程度的成功这样做。因此,稍有马虎 $液= $ dte.Solution 以上。

希望这是对别人有用!

I am trying to use powershell within the Package Manager Console to script the removal of a project from a solution and I am having a surprisingly hard time.

I can easily add a project by

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

Now I want to be remove a project and can't get anything to work.

I have tried a number of things including:

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'.

I have tried other combinations, but I am clearly spinning my wheels. I appreciate any suggestions.

解决方案

Right, I know I'm late to the party but I've just been tackling this same issue for an internal NuGet package we've been writing, and I think I've found how to do it.

Indeed Microsoft have (helpfully) left the Delete method unimplemented, and as we have both found, attempting to call the Remove method on the Solution2 interface throws an exciting myriad of errors depending on context!

However what I have found is that directly invoking the Remove method defined in SolutionClass does actually work (despite its being documented by Microsoft as internal use only. But hey, when every other option is exhausted...). The only catch is that the runtime binder also sometimes seems to fail to resolve the method overload, producing the error:

No overload for method 'Remove' takes 1 arguments

All of which means that it's time to get our reflection crayons out! The code looks like this:

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

After a day of various iterations (many closely resembling those in the question) and varying degrees of success (depending on whether I was executing inside the package manager, from inside the install script or within a debugger), the above is what I have found to be most reliable.

One thing to note is that because the reflected method is defined in EnvDTE.SolutionClass, passing it a EnvDTE._Solution or EnvDTE80.Solution2 throws a Type mismatch error, so unfortunately you cannot obtain your $solution object by the Get-Interface cmdlet (which is usually my preferred method). Doing the cast to [EnvDTE.SolutionClass] wherever possible is obviously preferable, but again I've found varying degrees of success in doing so. Hence the slightly sloppy $solution = $dte.Solution above.

Hope this is useful to someone else!

这篇关于通过包管理器控制台从溶液中取出项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆