Skip to content

Instantly share code, notes, and snippets.

@dedale
Last active December 19, 2022 13:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dedale/675ec80313f2a70266deb0ab78a0e2c6 to your computer and use it in GitHub Desktop.
Save dedale/675ec80313f2a70266deb0ab78a0e2c6 to your computer and use it in GitHub Desktop.
Custom MSBuild task with mutex
<!-- Replace -->
<MSBuild Projects="$(MSBuildProjectFullPath)"
Targets="Restore"
Properties="$(PackageRestoreProperties)"
BuildInParallel="true" />
<!-- With -->
<Import Project="...\MSBuildWithMutex.proj" />
<!-- ... -->
<Target Name="Restore...Packages" DependsOnTargets="CompileMSBuildWithMutex">
<!-- RestoreProjectPackages: $(MSBuildProjectFullPath) is a All.proj including all our projects with Traversal MSBuild SDK -->
<!-- RestoreBuildPackages: a Packages.props including all repo packages (e.g. tools) -->
<MSBuildWithMutex Projects="$(MSBuildProjectFullPath)"
Targets="Restore"
Properties="$(PackageRestoreProperties)"
BuildInParallel="true"
MutexName="MSBuildRestore_$(USERNAME)" />
</Target>
using System;
using System.Diagnostics;
using System.Threading;
using Microsoft.Build.Framework;
using Microsoft.Build.Tasks;
namespace Ded
{
public class MSBuildWithMutex : MSBuild
{
[Required]
public string MutexName { get; set; }
public override bool Execute()
{
var success = true;
var mutex = new Mutex(false, MutexName);
try
{
if (!mutex.WaitOne(0))
{
Log.LogMessage(MessageImportance.High, "Waiting for mutex '{0}'...", MutexName);
mutex.WaitOne(-1);
}
success = base.Execute();
}
catch (Exception e)
{
Log.LogError(e.ToString());
success = false;
}
finally
{
mutex.ReleaseMutex();
mutex.Dispose();
}
}
}
}
<Project ... >
<PropertyGroup>
<MSBuildWithMutexCs>$(MSBuildThisFileDirectory)\MSBuildWithMutex.cs</MSBuildWithMutexCs>
<MSBuildWithMutexOutputPath>...</MSBuildWithMutexOutputPath>
<MSBuildWithMutexDll>$(MSBuildWithMutexOutputPath)\Ded.MSBuildWithMutex.dll</MSBuildWithMutexDll>
</PropertyGroup>
<Target Name="CompileMSBuildWithMutex"
Inputs="$(MSBuildWithMutexCs);$(MSBuildThisFileFullPath)"
Outputs="$(MSBuildWithMutexDll)">
<ItemGroup>
<Sources Include="$(MSBuildWithMutexCs)" />
<References Include="$(MSBuildExtensionsPath32)\Current\Bin\Microsoft.Build.Framework.dll" />
<References Include="$(MSBuildExtensionsPath32)\Current\Bin\Microsoft.Build.Tasks.Core.dll" />
<References Include="$(MSBuildExtensionsPath32)\Current\Bin\Microsoft.Build.Utilities.Core.dll" />
</ItemGroup>
<MakeDir Directories="$(MSBuildWithMutexOutputPath)" Condition="!Exists('$(MSBuildWithMutexOutputPath)')" />
<Csc OutputAssembly="$(MSBuildWithMutexDll)"
TargetType="Library"
EmitDebugInformation="true"
Sources="@(Sources)"
References="@(References)"
WarningLevel="4"
TreatWarningAsErrors="true"
Optimize="true" />
<Message Text="MSBuildWithMutex -&gt; $(MSBuildWithMutexDll)" />
</Target>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment