1 namespace Microsoft.Build.Tasks.Xaml 2 { 3 using System; 4 using System.Globalization; 5 using System.Runtime; 6 using System.Runtime.Remoting.Lifetime; 7 using XamlBuildTask; 8 9 internal static class XamlBuildTaskLeaseLifetimeHelper 10 { 11 const string RemotingLeaseLifetimeInMinutesEnvironmentVariableName = "XamlBuildTaskTimeoutInMinutes"; 12 13 // In order to take advantage of the XamlBuildTaskRemotingLeaseLifetimeInMinutes environment variable from an MSBuild 14 // project file (e.g. csproj file), the following needs to be added to that project file: 15 // 16 // After the initial "<Project ..." line: 17 // <UsingTask TaskName="MySetEnv" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" > 18 // <ParameterGroup> 19 // <Name Required="true" /> 20 // <Value Required="false" /> 21 // </ParameterGroup> 22 // <Task> 23 // <Code Type="Fragment" Language="cs">System.Environment.SetEnvironmentVariable(Name, Value);</Code> 24 // </Task> 25 // </UsingTask> 26 // 27 // And at the end of the project file, before the closing </Project> : 28 // 29 // <Target Name="BeforeBuild"> 30 // <MySetEnv Name="XamlBuildTaskTimeoutInMinutes" Value="24" /> 31 // </Target> 32 // <Target Name="AfterBuild"> 33 // <MySetEnv Name="XamlBuildTaskRemotingLeaseLifetimeInMinutes" Value="" /> 34 // </Target> 35 // 36 // This example uses a task name of "MySetEnv", but it that name could be anything desired. 37 // It also sets the timeout to 24 minutes, as defined as the Value specified to the MySetEnv task. 38 // The AfterBuild target is not required, but is probably desired so that the environment variable setting 39 // does not persist after the processing of this particular project file. 40 // The valid values for the environment variable are numbers between 1 and 2147483647 inclusive 41 // (positive 32-bit integers). Any other value will result in no change to the lease lifetime. SetLeaseLifetimeFromEnvironmentVariable(ILease lease)42 internal static void SetLeaseLifetimeFromEnvironmentVariable(ILease lease) 43 { 44 // We can only change the lease lifetime if we have an ILease and it is still in the Initial state. 45 if ((lease != null) && (lease.CurrentState == LeaseState.Initial)) 46 { 47 try 48 { 49 string remotingLeaseLifetimeInMinutesStringValue = Environment.GetEnvironmentVariable(RemotingLeaseLifetimeInMinutesEnvironmentVariableName); 50 if (!string.IsNullOrEmpty(remotingLeaseLifetimeInMinutesStringValue)) 51 { 52 int remotingLeaseLifetimeInMinutes = -1; 53 if (Int32.TryParse(remotingLeaseLifetimeInMinutesStringValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out remotingLeaseLifetimeInMinutes)) 54 { 55 // revert to the defauilt if the number specified is less than or equal to 0. 56 if (remotingLeaseLifetimeInMinutes > 0) 57 { 58 lease.InitialLeaseTime = TimeSpan.FromMinutes(remotingLeaseLifetimeInMinutes); 59 lease.RenewOnCallTime = TimeSpan.FromMinutes(remotingLeaseLifetimeInMinutes); 60 } 61 } 62 } 63 } 64 catch (Exception ex) 65 { 66 // simply ignore any exceptions that might have occurred and go with the default. We can't log it because 67 // we aren't initialized enough at this point. 68 if (Fx.IsFatal(ex)) 69 { 70 throw; 71 } 72 } 73 } 74 } 75 } 76 } 77 78