假设我将自定义目标添加到csproj文件中。有没有办法从visual studio运行该目标?我不希望它成为预建或后构建步骤,我只是希望能够从visual studio运行这个目标(及其依赖项)。
答案 0 :(得分:39)
使用自定义外部工具有一种简单的方法(尽管不是很令人满意)。
假设您的项目文件有以下修改:
<Target Name="CalledFromIde">
<Error Text="Called from the IDE!" />
</Target>
转到工具|外部工具并添加如下:
Title: Called from IDE
Command: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
Arguments: $(ProjectDir)$(ProjectFileName) /t:CalledFromIde
Initial directory: $(ProjectDir)
Use Output window: checked
运行它会产生输出:
Build FAILED.
"F:\Code\CsProject\CsProject.csproj" (CalledFromIde target) (1) ->
(CalledFromIde target) ->
F:\Code\CsProject\CsProject.csproj(57,5): error : Called from the IDE!
您正在做的是将MSBuild称为外部工具并让它直接运行目标。您必须提供MSBuild的完整路径,因为IDE不会保留与其创建的构建环境相同的属性。
您可以通过确定设置Tools.ExternalCommand#中的#命令来将其挂钩到快捷方式。
如果您正在寻找更复杂的解决方案,那么它会更复杂一些。简而言之(对于VS2010):
1)创建VS Addin(文件|新建|项目|其他项目类型|可扩展性| Visual Studio加载项)。我不确定您是否必须安装VS SDK才能获得此功能,它可以在扩展管理器中使用。
在向导中选择以下选项: - Microsoft Visual Studio 2010 - 是的,创建一个“工具”菜单项 - 应用程序启动时加载 - 我的加载项永远不会提供模态UI,并且可以与命令行构建一起使用。
2)添加对Microsoft.Build和Microsoft.Build.Framework
的引用3)在Connect.cs文件中找到Exec的实现
4)用以下代码替换它:
public void Exec(
string commandName,
vsCommandExecOption executeOption,
ref object varIn,
ref object varOut,
ref bool handled)
{
handled = false;
if (executeOption != vsCommandExecOption.vsCommandExecOptionDoDefault)
return;
if (commandName != "BuildAddin.Connect.BuildAddin")
return;
var doc = _applicationObject.ActiveDocument;
var projectItem = doc.ProjectItem;
var project = projectItem.ContainingProject;
var evalProject =
Microsoft.Build.Evaluation.ProjectCollection
.GlobalProjectCollection.LoadProject(project.FullName);
var execProject = evalProject.CreateProjectInstance();
bool success = execProject.Build("CalledFromIde", null);
var window = _applicationObject.Windows.Item(Constants.vsWindowKindOutput);
var output = (OutputWindow)window.Object;
OutputWindowPane pane = output.OutputWindowPanes.Add("BuildAddin");
pane.OutputString(success ? "built /t:CalledFromIde" : "build failed");
handled = true;
return;
}
5)调试时更好的自定义目标,因为上一个错误:
<Target Name="CalledFromIde">
<WriteLinesToFile File="CalledFromIde.txt" Lines="Called from the IDE!" />
</Target>
6)上面的代码没有错误检查以简洁,你会希望更清洁,因为它将在IDE中运行。插件将在“工具”菜单上放置一个菜单项。如上所述,它只是查找包含当前活动编辑器文档的项目,无论您正在烹饪什么,都需要更好的管道。
此技术从IDE中获取构建引擎实例,并使其在项目的单独实例上执行构建。
答案 1 :(得分:5)
如果您在Visual Studio中运行构建,则在构建期间将有一个VisualStudioDir的构建变量。
仅执行VS构建会话执行此操作:
<Target Name="Test" BeforeTargets="Build" Condition="'$(VisualStudioDir)' != ''>
</Target>
要仅在VS之外的构建中执行,请执行以下操作:
<Target Name="Test" BeforeTargets="Build" Condition="'$(VisualStudioDir)' == ''>
</Target>
您需要以两种方式之一包含自定义目标文件。
通过添加导入
编辑项目文件以包含自定义目标文件<Imports Project="CustomBuildTasks.Targets"><Imports/>
答案 2 :(得分:3)
您不必使用Exec进行编码,尽管这是一种方法。更简单的方法是执行以下操作:
将DefaultTargets="Build"
属性更改为您创建的自定义目标,比如说"All"
:
DefaultTargets="All"
然后在您的自定义&#34; All&#34; target,您可以使用DependsOnTargets属性,如下所示:
"<Target Name="All" DependsOnTargets="ZipOutputFiles;Build">
</Target>"
然后,这将构建并输出zip文件到您的自定义"All"
目标中。
答案 3 :(得分:0)
前段时间,我遇到了同样的问题,因此决定编写VS加载项。 试试吧:
https://github.com/Serg046/MsBuildTaskExplorer
https://marketplace.visualstudio.com/items?itemName=saaseev.MsBuildTaskExplorer