在 IDE 中启动生成
自定义项目系统必须使用 IVsBuildManagerAccessor 开始生成过程。本主题介绍这样做的原因并概述具体过程。
并行生成和线程
Visual Studio 允许需要干预的并行生成访问常见资源。项目系统可以异步运行生成,但此类系统不能从提供给生成管理器的回调中调用生成函数。
如果项目系统修改环境变量,它必须将生成的 NodeAffinity 设置为 OutOfProc。这意味着不能使用宿主对象,因为它们需要进程内节点。
使用 IVSBuildManagerAccessor
下面的代码概括了项目系统可用于启动生成的方法:
public bool Build(Project project, bool isDesignTimeBuild)
{
// Get the accessor from the IServiceProvider interface for the
// project system
IVsBuildManagerAccessor accessor =
serviceProvider.GetService(typeof(SVsBuildManagerAccessor)) as
IVsBuildManagerAccessor;
bool releaseUIThread = false;
try
{
if(accessor != null)
{
// Claim the UI thread under the following conditions:
// 1. The build must use a resource that uses the UI thread
// or,
// 2. The build requires the in-proc node AND waits on the
// UI thread for the build to complete
if(NeedsUIThread)
{
int result = accessor.ClaimUIThreadForBuild();
if(result != S_OK)
{
// Not allowed to claim the UI thread right now
return false;
}
releaseUIThread = true;
}
if(isDesignTimeBuild)
{
// Start the design time build
int result = accessor.BeginDesignTimeBuild();
if(result != S_OK)
{
// Not allowed to begin a design-time build at
// this time. Try again later.
return false;
}
}
}
bool buildSucceeded = false;
// perform project-system specific build set up tasks
// Create your BuildRequestData
// This assumes a IHostServices variable (hostServices) set
// to your host services. If you don't use a project instance
// (you build from a file for example) then use another
// constructor.
BuildRequestData requestData = new
BuildRequestData(project.CreateProjectInstance(),
"myTarget", hostServices,
BuildRequestData.BuildRequestDataFlags.None);
// Mark your your submission as Pending
BuildSubmission submission =
BuildManager.DefaultBuildManager.
PendBuildRequest(requestData);
// Register the loggers in BuildLoggers
if (accessor != null)
{
foreach (ILogger logger in BuildLoggers)
{
accessor.RegisterLogger(submission.SubmissionId,
logger);
}
}
BuildResult buildResult = submission.Execute();
return buildResult;
}
// Clean up resources
finally
{
if(accessor != null)
{
// Unregister the loggers, if necessary.
accessor.UnregisterLoggers(submission.SubmissionId);
// Release the UI thread, if used
if(releaseUIThread)
{
accessor.ReleaseUIThreadForBuild();
}
// End the design time build, if used
if(isDesignTimeBuild)
{
accessor.EndDesignTimeBuild();
}
}
}
}
请参见
其他资源
IVsBuildManagerAccessor