Working to get the collision stuff working with mesh groups

Put in the RomotingLite project to start on TigerSong
This commit is contained in:
larsbrubaker 2014-10-09 11:29:33 -07:00
parent 2783f79818
commit 2d3d26a68d
37 changed files with 3647 additions and 19 deletions

View file

@ -325,7 +325,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
UiThread.RunOnIdle((state) =>
{
EnterEdit();
EnterEditAndCreateSelectionData();
OpenFileDialogParams openParams = new OpenFileDialogParams(ApplicationSettings.OpenDesignFileParams, multiSelect: true);
@ -337,7 +337,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Button enterEdittingButton = textImageButtonFactory.Generate(LocalizedString.Get("Edit"));
enterEdittingButton.Click += (sender, e) =>
{
EnterEdit();
EnterEditAndCreateSelectionData();
};
enterEditButtonsContainer.AddChild(enterEdittingButton);
@ -485,7 +485,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
UiThread.RunOnIdle((state) =>
{
EnterEdit();
EnterEditAndCreateSelectionData();
});
}
@ -983,9 +983,92 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
}
void EnterEditAndCreateSelectionData()
{
if (enterEditButtonsContainer.Visible == true)
{
enterEditButtonsContainer.Visible = false;
}
if (MeshGroups.Count > 0)
{
processingProgressControl.Visible = true;
LockEditControls();
viewIsInEditModePreLock = true;
BackgroundWorker createSelectionDataBackgroundWorker = null;
createSelectionDataBackgroundWorker = new BackgroundWorker();
createSelectionDataBackgroundWorker.WorkerReportsProgress = true;
createSelectionDataBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
createSelectionDataBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(createSelectionDataBackgroundWorker_RunWorkerCompleted);
createSelectionDataBackgroundWorker.DoWork += new DoWorkEventHandler(createSelectionDataBackgroundWorker_DoWork);
createSelectionDataBackgroundWorker.RunWorkerAsync();
}
}
void createSelectionDataBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
BackgroundWorker backgroundWorker = (BackgroundWorker)sender;
asynchPlatingDataList.Clear();
asynchMeshGroupTransforms.Clear();
for (int i = 0; i < asynchMeshGroupsList.Count; i++)
{
PlatingMeshGroupData newInfo = new PlatingMeshGroupData();
asynchPlatingDataList.Add(newInfo);
MeshGroup meshGroup = asynchMeshGroupsList[i];
// remember where it is now
AxisAlignedBoundingBox startingBounds = meshGroup.GetAxisAlignedBoundingBox(asynchMeshGroupTransforms[i].TotalTransform);
Vector3 startingCenter = (startingBounds.maxXYZ + startingBounds.minXYZ) / 2;
ScaleRotateTranslate meshTransform = asynchMeshGroupTransforms[i];
// move the mesh to be centered on the origin
AxisAlignedBoundingBox meshBounds = meshGroup.GetAxisAlignedBoundingBox();
Vector3 meshCenter = (meshBounds.maxXYZ + meshBounds.minXYZ) / 2;
meshTransform.centering = Matrix4X4.CreateTranslation(-meshCenter);
// set the transform to position it where it was
meshTransform.translation = Matrix4X4.CreateTranslation(startingCenter);
asynchMeshGroupTransforms[i] = meshTransform;
PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroupsList, asynchMeshGroupTransforms, i, false);
// and create selection info
PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDataList, asynchMeshGroupsList, i);
if (asynchMeshGroupsList.Count > 1)
{
backgroundWorker.ReportProgress(50 + i * 50 / (asynchMeshGroupsList.Count - 1));
}
}
}
void createSelectionDataBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (WidgetHasBeenClosed)
{
return;
}
// remove the original mesh and replace it with these new meshes
PullMeshGroupDataFromAsynchLists();
UnlockEditControls();
if (pendingPartsToLoad.Count > 0)
{
LoadAndAddPartsToPlate(pendingPartsToLoad.ToArray());
}
Invalidate();
}
void createDiscreteMeshesBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
throw new NotImplementedException();
throw new NotImplementedException();
#if false
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
BackgroundWorker backgroundWorker = (BackgroundWorker)sender;
@ -1029,20 +1112,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
#endif
}
void EnterEdit()
{
if (enterEditButtonsContainer.Visible == true)
{
enterEditButtonsContainer.Visible = false;
}
if (pendingPartsToLoad.Count > 0)
{
LoadAndAddPartsToPlate(pendingPartsToLoad.ToArray());
}
viewControls3D.PartSelectVisible = true;
doEdittingButtonsContainer.Visible = true;
}
void createDiscreteMeshesBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (WidgetHasBeenClosed)
@ -1586,7 +1655,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
bool enterEditModeBeforeAddingParts = enterEditButtonsContainer.Visible == true;
if (enterEditModeBeforeAddingParts)
{
EnterEdit();
EnterEditAndCreateSelectionData();
}
else
{

View file

@ -0,0 +1,543 @@
<Activity mc:Ignorable="sad" x:Class="TfsBuild.Process" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mt="clr-namespace:Microsoft.TeamFoundation;assembly=Microsoft.TeamFoundation.Common" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwt="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Tracking;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mttbb="clr-namespace:Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities;assembly=Microsoft.TeamFoundation.TestImpact.BuildIntegration" xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mtvco="clr-namespace:Microsoft.TeamFoundation.VersionControl.Common;assembly=Microsoft.TeamFoundation.VersionControl.Common" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:sad="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:sad1="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:this="clr-namespace:TfsBuild;" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="BuildSettings" Type="InArgument(mtbwa:BuildSettings)" />
<x:Property Name="TestSpecs" Type="InArgument(mtbwa:TestSpecList)" />
<x:Property Name="BuildNumberFormat" Type="InArgument(x:String)" />
<x:Property Name="SolutionSpecificBuildOutputs" Type="InArgument(x:Boolean)" />
<x:Property Name="CleanWorkspace" Type="InArgument(mtbwa:CleanWorkspaceOption)" />
<x:Property Name="RunCodeAnalysis" Type="InArgument(mtbwa:CodeAnalysisOption)" />
<x:Property Name="SourceAndSymbolServerSettings" Type="InArgument(mtbwa:SourceAndSymbolServerSettings)" />
<x:Property Name="AgentSettings" Type="InArgument(mtbwa:AgentSettings)" />
<x:Property Name="AssociateChangesetsAndWorkItems" Type="InArgument(x:Boolean)" />
<x:Property Name="CreateWorkItem" Type="InArgument(x:Boolean)" />
<x:Property Name="MSBuildArguments" Type="InArgument(x:String)" />
<x:Property Name="MSBuildPlatform" Type="InArgument(mtbwa:ToolPlatform)" />
<x:Property Name="MSBuildMultiProc" Type="InArgument(x:Boolean)" />
<x:Property Name="PerformTestImpactAnalysis" Type="InArgument(x:Boolean)" />
<x:Property Name="CreateLabel" Type="InArgument(x:Boolean)" />
<x:Property Name="DisableTests" Type="InArgument(x:Boolean)" />
<x:Property Name="GetVersion" Type="InArgument(x:String)" />
<x:Property Name="PrivateDropLocation" Type="InArgument(x:String)" />
<x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
<x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
<x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
<x:Property Name="BuildProcessVersion" Type="x:String" />
</x:Members>
<this:Process.BuildSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildSettings()]</this:Process.BuildSettings>
<this:Process.DisableTests>[False]</this:Process.DisableTests>
<this:Process.TestSpecs>[New Microsoft.TeamFoundation.Build.Workflow.Activities.TestSpecList(New Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec("**\*test*.dll"))]</this:Process.TestSpecs>
<this:Process.BuildNumberFormat>["$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)"]</this:Process.BuildNumberFormat>
<this:Process.SolutionSpecificBuildOutputs>[False]</this:Process.SolutionSpecificBuildOutputs>
<this:Process.AssociateChangesetsAndWorkItems>[True]</this:Process.AssociateChangesetsAndWorkItems>
<this:Process.CreateWorkItem>[True]</this:Process.CreateWorkItem>
<this:Process.CleanWorkspace>[Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]</this:Process.CleanWorkspace>
<this:Process.MSBuildArguments>
<InArgument x:TypeArguments="x:String" />
</this:Process.MSBuildArguments>
<this:Process.RunCodeAnalysis>[Microsoft.TeamFoundation.Build.Workflow.Activities.CodeAnalysisOption.AsConfigured]</this:Process.RunCodeAnalysis>
<this:Process.MSBuildMultiProc>[True]</this:Process.MSBuildMultiProc>
<this:Process.MSBuildPlatform>[Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto]</this:Process.MSBuildPlatform>
<this:Process.PerformTestImpactAnalysis>[True]</this:Process.PerformTestImpactAnalysis>
<this:Process.SourceAndSymbolServerSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.SourceAndSymbolServerSettings(True, Nothing)]</this:Process.SourceAndSymbolServerSettings>
<this:Process.CreateLabel>[True]</this:Process.CreateLabel>
<this:Process.GetVersion>
<InArgument x:TypeArguments="x:String" />
</this:Process.GetVersion>
<this:Process.AgentSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }]</this:Process.AgentSettings>
<this:Process.Verbosity>[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]</this:Process.Verbosity>
<this:Process.Metadata>
<mtbw:ProcessParameterMetadataCollection>
<mtbw:ProcessParameterMetadata BrowsableWhen="EditingDefinition" Category="#300 Advanced" DisplayName="MSBuild Multi-Proc" Description="Enable MSBuid Multi-proc to build your solutions' projects in parallel, when possible, using all available processors on the build server." ParameterName="MSBuildMultiProc" />
<mtbw:ProcessParameterMetadata BrowsableWhen="EditingDefinition" Category="#300 Advanced" DisplayName="Solution Specific Build Outputs" Description="True will put build outputs into folders based on the solution name. False will put all build outputs into the same folder." ParameterName="SolutionSpecificBuildOutputs" />
</mtbw:ProcessParameterMetadataCollection>
</this:Process.Metadata>
<this:Process.SupportedReasons>All</this:Process.SupportedReasons>
<this:Process.BuildProcessVersion>11.0</this:Process.BuildProcessVersion>
<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
<Sequence mtbwt:BuildTrackingParticipant.Importance="None">
<Sequence.Variables>
<Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
<Variable x:TypeArguments="x:String" Name="DropLocation" />
</Sequence.Variables>
<mtbwa:GetBuildDetail DisplayName="Get the Build" Result="[BuildDetail]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<Sequence DisplayName="Update Drop Location" mtbwt:BuildTrackingParticipant.Importance="Low">
<mtbwa:InvokeForReason DisplayName="Update Build Number for Triggered Builds" Reason="Triggered">
<mtbwa:UpdateBuildNumber BuildNumberFormat="[BuildNumberFormat]" DisplayName="Update Build Number" />
</mtbwa:InvokeForReason>
<If Condition="[(Not String.IsNullOrEmpty(BuildDetail.DropLocationRoot)) AndAlso (BuildDetail.Reason And Microsoft.TeamFoundation.Build.Client.BuildReason.Triggered) = BuildDetail.Reason]" DisplayName="If Build Reason is Triggered" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence mtbwt:BuildTrackingParticipant.Importance="None">
<Assign x:TypeArguments="x:String" mtbwt:BuildTrackingParticipant.Importance="None" Value="[BuildDropProvider.CombinePaths(BuildDetail.DropLocationRoot, BuildDetail.BuildDefinition.Name, BuildDetail.BuildNumber)]" To="[DropLocation]" />
<mtbwa:SetBuildProperties DisplayName="Set Drop Location" DropLocation="[DropLocation]" PropertiesToSet="DropLocation" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</If.Then>
</If>
<If Condition="[(Not String.IsNullOrEmpty(PrivateDropLocation)) AndAlso BuildDetail.Reason = Microsoft.TeamFoundation.Build.Client.BuildReason.ValidateShelveset]" DisplayName="If Build Reason is ValidateShelveset" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence mtbwt:BuildTrackingParticipant.Importance="None">
<Assign x:TypeArguments="x:String" Value="[BuildDropProvider.CombinePaths(PrivateDropLocation, BuildDetail.BuildDefinition.Name, BuildDetail.BuildNumber)]" To="[DropLocation]" mtbwt:BuildTrackingParticipant.Importance="None" />
<mtbwa:SetBuildProperties DisplayName="Set Drop Location for Private Build" DropLocation="[DropLocation]" PropertiesToSet="DropLocation" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</If.Then>
</If>
</Sequence>
<mtbwa:AgentScope DisplayName="Run On Agent" MaxExecutionTime="[AgentSettings.MaxExecutionTime]" MaxWaitTime="[AgentSettings.MaxWaitTime]" ReservationSpec="[AgentSettings.GetAgentReservationSpec()]">
<mtbwa:AgentScope.Variables>
<Variable x:TypeArguments="mtbc:IBuildAgent" Name="BuildAgent" />
<Variable x:TypeArguments="mtvc:Workspace" Name="Workspace" />
<Variable x:TypeArguments="x:String" Name="BuildDirectory" />
<Variable x:TypeArguments="x:String" Default="[BuildDetail.BuildNumber]" Name="LabelName" />
<Variable x:TypeArguments="x:String" Name="WorkspaceName" />
<Variable x:TypeArguments="x:String" Name="SourcesDirectory" />
<Variable x:TypeArguments="x:String" Name="BinariesDirectory" />
<Variable x:TypeArguments="x:String" Name="TestResultsDirectory" />
</mtbwa:AgentScope.Variables>
<Sequence DisplayName="Initialize Variables" mtbwt:BuildTrackingParticipant.Importance="Low">
<mtbwa:GetBuildAgent DisplayName="Get the Agent" Result="[BuildAgent]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" Result="[BuildDirectory]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize Workspace Name" To="[WorkspaceName]" Value="[String.Format(&quot;{0}_{1}_{2}&quot;, BuildDetail.BuildDefinition.Id, Microsoft.TeamFoundation.LinkingUtilities.DecodeUri(BuildAgent.Uri.AbsoluteUri).ToolSpecificId, BuildAgent.ServiceHost.Name)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize Sources Directory" To="[SourcesDirectory]" Value="[String.Format(&quot;{0}\Sources&quot;, BuildDirectory)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize Binaries Directory" To="[BinariesDirectory]" Value="[String.Format(&quot;{0}\Binaries&quot;, BuildDirectory)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize TestResults Directory" To="[TestResultsDirectory]" Value="[String.Format(&quot;{0}\TestResults&quot;, BuildDirectory)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[Not BuildSettings.HasPlatformConfigurations]" DisplayName="If Not BuildSettings.HasPlatformConfigurations" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<AddToCollection x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="Use Default Platform Configuration" Collection="[BuildSettings.PlatformConfigurations]" Item="[Microsoft.TeamFoundation.Build.Workflow.Activities.PlatformConfiguration.Default]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<If Condition="[WorkspaceName.Length &gt; Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize]" DisplayName="If WorkspaceName &gt; MaxSize" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence mtbwt:BuildTrackingParticipant.Importance="None">
<mtbwa:WriteBuildWarning DisplayName="Write Workspace Size Warning" Message="[String.Format(&quot;The workspace name '{0}' exceeds the maximum allowed limit of '{1}' characters. Truncating it to match the maximum limit.&quot;, WorkspaceName, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize)]" />
<Assign x:TypeArguments="x:String" DisplayName="Truncate WorkspaceName to MaxSize" To="[WorkspaceName]" Value="[WorkspaceName.Substring(0, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize).TrimEnd()]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</If.Then>
</If>
</Sequence>
<Sequence DisplayName="Initialize Workspace" mtbwt:BuildTrackingParticipant.Importance="Low">
<mtbwa:DeleteDirectory Directory="[TestResultsDirectory]" DisplayName="Delete Test Results Directory" Recursive="[True]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[Not CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.None]" DisplayName="If Not CleanWorkspace = CleanWorkspaceOption.None" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:DeleteDirectory Directory="[BinariesDirectory]" DisplayName="Delete Binaries Directory" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.All" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Delete Workspace and Sources Directory" mtbwt:BuildTrackingParticipant.Importance="Low">
<mtbwa:DeleteWorkspace DeleteLocalItems="[True]" DisplayName="Delete Workspace" Name="[WorkspaceName]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:DeleteDirectory Directory="[SourcesDirectory]" DisplayName="Delete Sources Directory" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</If.Then>
</If>
<mtbwa:CreateWorkspace BuildDirectory="[BuildDirectory]" Comment="[&quot;Workspace Created by Team Build&quot;]" DisplayName="Create Workspace" Name="[WorkspaceName]" Result="[Workspace]" SourcesDirectory="[SourcesDirectory]" />
<If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.Outputs]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.Outputs" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" Values="[BuildSettings.PlatformConfigurations]" mtbwt:BuildTrackingParticipant.Importance="Low">
<ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
</ActivityAction.Argument>
<Sequence DisplayName="Clean Configuration">
<If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" Values="[BuildSettings.ProjectsToBuild]" mtbwt:BuildTrackingParticipant.Importance="Low">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
</ActivityAction.Argument>
<Sequence DisplayName="Clean Project" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localBuildProjectItem" />
</Sequence.Variables>
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Paths to Local Paths" Input="[serverBuildProjectItem]" Result="[localBuildProjectItem]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[System.IO.File.Exists(localBuildProjectItem)]" DisplayName="If File.Exists(Project)" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" MaxProcesses="[If (MSBuildMultiProc, 0, 1)]" OutDir="[BinariesDirectory]" Platform="[platformConfiguration.Platform]" Project="[localBuildProjectItem]" Targets="[New String() { &quot;Clean&quot; }]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
</If.Then>
</If>
</Sequence>
</ActivityAction>
</ForEach>
</If.Then>
</If>
</Sequence>
</ActivityAction>
</ForEach>
</If.Then>
</If>
<mtbwa:SyncWorkspace DisplayName="Get Workspace" VersionOverride="[GetVersion]" Workspace="[Workspace]">
<mtbwa:SyncWorkspace.RequestsFailed>
<ActivityAction x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)" Name="failedRequests" />
</ActivityAction.Argument>
<mtbwa:RetryRequests Behavior="[Microsoft.TeamFoundation.Build.Workflow.Activities.RetryBehavior.DoNotBatch]" DisplayName="Mark Requests for Retry" Requests="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</ActivityAction>
</mtbwa:SyncWorkspace.RequestsFailed>
</mtbwa:SyncWorkspace>
</Sequence>
<If Condition="[CreateLabel]" DisplayName="If CreateLabel" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Create and Set Label for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
<mtbwa:LabelWorkspace Comment="[&quot;Label Created by Team Build&quot;]" DisplayName="Create Label" Name="[LabelName]" Scope="[String.Format(&quot;$/{0}&quot;, BuildDetail.BuildDefinition.TeamProject)]" Workspace="[Workspace]" />
<mtbwa:SetBuildProperties DisplayName="Set Label on BuildDetail" LabelName="[String.Format(&quot;{0}@$/{1}&quot;, LabelName, BuildDetail.BuildDefinition.TeamProject)]" PropertiesToSet="LabelName" mtbwt:BuildTrackingParticipant.Importance="Low" />
</mtbwa:InvokeForReason>
</If.Then>
<If.Else>
<mtbwa:WriteBuildMessage DisplayName="Write Message" Message="Not Labeling sources" Importance="[Microsoft.TeamFoundation.Build.Client.BuildMessageImportance.High]" />
</If.Else>
</If>
<TryCatch DisplayName="Try Compile, Test, and Associate Changesets and Work Items" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Finally>
<Sequence DisplayName="Revert Workspace and Copy Files to Drop Location" mtbwt:BuildTrackingParticipant.Importance="Low">
<mtbwa:InvokeForReason DisplayName="Revert Workspace for Shelveset Builds" Reason="CheckInShelveset, ValidateShelveset">
<mtbwa:RevertWorkspace DisplayName="Revert Workspace" Workspace="[Workspace]" />
</mtbwa:InvokeForReason>
<If Condition="[Not String.IsNullOrEmpty(DropLocation)]" DisplayName="If DropLocation is Set" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:CopyDirectory DisplayName="Drop Files to Drop Location" Source="[BinariesDirectory]" Destination="[DropLocation]" />
</If.Then>
</If>
</Sequence>
</TryCatch.Finally>
<TryCatch.Try>
<Sequence mtbwt:BuildTrackingParticipant.Importance="None">
<Sequence.Variables>
<Variable x:TypeArguments="s:Exception" Name="compilationException" />
<Variable x:TypeArguments="scg:IList(mtvc:Changeset)" Name="associatedChangesets" />
<Variable x:TypeArguments="s:Boolean" Name="treatTestFailureAsBuildFailure" />
</Sequence.Variables>
<Parallel DisplayName="Compile, Test, and Associate Changesets and Work Items">
<TryCatch DisplayName="Try Compile and Test" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<Sequence DisplayName="Compile and Test">
<ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" Values="[BuildSettings.PlatformConfigurations]" mtbwt:BuildTrackingParticipant.Importance="Low">
<ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
</ActivityAction.Argument>
<Sequence DisplayName="Compile and Test for Configuration" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="outputDirectory" />
<Variable x:TypeArguments="x:String" Name="logFileDropLocation" />
</Sequence.Variables>
<Sequence DisplayName="Initialize Variables" mtbwt:BuildTrackingParticipant.Importance="Low">
<Assign x:TypeArguments="x:String" DisplayName="Create OutputDirectory Per Platform and Configuration" To="[outputDirectory]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BinariesDirectory, If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BinariesDirectory + &quot;\&quot; + platformConfiguration.Configuration, BinariesDirectory + &quot;\&quot; + platformConfiguration.Platform + &quot;\&quot; + platformConfiguration.Configuration))]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[Not String.IsNullOrEmpty(DropLocation)]" DisplayName="If DropLocation is Set" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Assign x:TypeArguments="x:String" DisplayName="Initialize LogFile Drop Location" To="[logFileDropLocation]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BuildDropProvider.CombinePaths(DropLocation, &quot;logs&quot;), If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BuildDropProvider.CombinePaths(DropLocation, &quot;logs&quot;, platformConfiguration.Configuration), BuildDropProvider.CombinePaths(DropLocation, &quot;logs&quot;, platformConfiguration.Platform, platformConfiguration.Configuration)))]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
</Sequence>
<If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" Values="[BuildSettings.ProjectsToBuild]" mtbwt:BuildTrackingParticipant.Importance="Low">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
</ActivityAction.Argument>
<TryCatch DisplayName="Try to Compile the Project" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<Sequence DisplayName="Compile the Project" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localProject" />
<Variable x:TypeArguments="x:String" Name="outputDirectoryPerProject" Default="[outputDirectory]" />
</Sequence.Variables>
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" Input="[serverBuildProjectItem]" Result="[localProject]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[SolutionSpecificBuildOutputs]" DisplayName="If Build Outputs are Solution-Specific" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Update Output Directory" mtbwt:BuildTrackingParticipant.Importance="Low">
<Assign x:TypeArguments="x:String" DisplayName="Set Solution-Specific Output Directory" To="[outputDirectoryPerProject]" Value="[System.IO.Path.Combine(outputDirectory, System.IO.Path.GetFileNameWithoutExtension(localProject))]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If DisplayName="If Output Directory Exists" Condition="[System.IO.Directory.Exists(outputDirectoryPerProject)]" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:WriteBuildWarning DisplayName="Write Duplicate Project Names Warning" Message="[String.Format(&quot;{0} conflicts with another solution/project. Build outputs for solutions/projects with the same name will be copied to the same directory. To separate the build outputs, change the name of one of the solutions/projects.&quot;, System.IO.Path.GetFileNameWithoutExtension(localProject))]" />
</If.Then>
</If>
</Sequence>
</If.Then>
</If>
<mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" LogFileDropLocation="[logFileDropLocation]" MaxProcesses="[If (MSBuildMultiProc, 0, 1)]" OutDir="[outputDirectoryPerProject]" Platform="[platformConfiguration.Platform]" Project="[localProject]" RunCodeAnalysis="[RunCodeAnalysis]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
</Sequence>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception">
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="ex" />
</ActivityAction.Argument>
<Sequence DisplayName="Handle Exception">
<Sequence.Variables>
<Variable x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)" Name="failedRequests" />
</Sequence.Variables>
<mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" DisplayName="Set CompilationStatus to Failed" PropertiesToSet="CompilationStatus" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[CreateWorkItem]" DisplayName="If CreateWorkItem" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Create Work Item for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
<mtbwa:OpenWorkItem AssignedTo="[BuildDetail.RequestedFor]" Comment="[&quot;This work item was created by TFS Build on a build failure.&quot;]" CustomFields="[New Dictionary(Of String, String) From { {&quot;System.Reason&quot;, &quot;Build Failure&quot;}, {&quot;Microsoft.VSTS.TCM.ReproSteps&quot;, &quot;Start the build using TFS Build&quot;}, {&quot;Priority&quot;, &quot;1&quot;}, {&quot;Severity&quot;, &quot;1 - Critical&quot;} }]" DisplayName="Create Work Item" Title="[String.Format(&quot;Build Failure in Build: {0}&quot;, BuildDetail.BuildNumber)]" Type="[&quot;Bug&quot;]" />
</mtbwa:InvokeForReason>
</If.Then>
</If>
<mtbwa:GetApprovedRequests DisplayName="Get Requests Approved for Check In" Result="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="None" />
<mtbwa:RetryRequests Behavior="[Microsoft.TeamFoundation.Build.Workflow.Activities.RetryBehavior.DoNotBatch]" DisplayName="Mark Requests for Retry" Requests="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<Rethrow DisplayName="Rethrow the exception so the build will stop" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</ActivityAction>
</ForEach>
</If.Then>
</If>
<If Condition="[Not DisableTests]" DisplayName="If Not DisableTests" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Run Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
<If Condition="[Not TestSpecs Is Nothing]" DisplayName="If Not TestSpecs Is Nothing" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="mtbwa:TestSpec" DisplayName="For Each TestSpec in TestSpecs" Values="[TestSpecs]" mtbwt:BuildTrackingParticipant.Importance="Low">
<ActivityAction x:TypeArguments="mtbwa:TestSpec">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="mtbwa:TestSpec" Name="spec" />
</ActivityAction.Argument>
<TryCatch DisplayName="Try Run Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<If Condition="[TypeOf spec Is Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec]" DisplayName="If spec Is AgileTestPlatformSpec" mtbwt:BuildTrackingParticipant.Importance="None">
<If.Then>
<Sequence DisplayName="Run Visual Studio Test Runner for Test Sources" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="mtbwa:AgileTestPlatformSpec" Name="agileTestPlatformAssembly" />
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="agileTestPlatformAssemblies" />
</Sequence.Variables>
<Assign x:TypeArguments="mtbwa:AgileTestPlatformSpec" DisplayName="Assign spec to agileTestPlatformAssembly" To="[agileTestPlatformAssembly]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:FindMatchingFiles DisplayName="Find Visual Studio Test Platform Test Assemblies" MatchPattern="[String.Format(&quot;{0}\{1}&quot;, outputDirectory, agileTestPlatformAssembly.AssemblyFileSpec)]" Result="[agileTestPlatformAssemblies]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[agileTestPlatformAssemblies.Count() &gt; 0]" DisplayName="If Visual Studio Test Platform Test Assemblies Found" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<If Condition="[agileTestPlatformAssembly.HasRunSettingsFile]" DisplayName="If agileTestPlatformAssembly.HasRunSettingsFile" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Find Run Settings File And Run Visual Studio Test Runner" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localRunSettings" />
</Sequence.Variables>
<mtbwa:GenerateRunSettings DisplayName="Generate Run Settings File" RunSettingsForTestRun="[agileTestPlatformAssembly.RunSettingsForTestRun]" Result="[localRunSettings]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:RunTests DisplayName="Run Visual Studio Test Runner for Test Sources" RunName="[agileTestPlatformAssembly.RunName]" Flavor="[platformConfiguration.Configuration]" Platform="[platformConfiguration.Platform]" TestSources="[agileTestPlatformAssemblies]" RunSettings="[localRunSettings]" TestCaseFilter="[agileTestPlatformAssembly.TestCaseFilter]" ExecutionPlatform="[agileTestPlatformAssembly.ExecutionPlatform]" />
</Sequence>
</If.Then>
<If.Else>
<mtbwa:RunTests DisplayName="Run Visual Studio Test Runner for Test Sources" RunName="[agileTestPlatformAssembly.RunName]" Flavor="[platformConfiguration.Configuration]" Platform="[platformConfiguration.Platform]" TestSources="[agileTestPlatformAssemblies]" TestCaseFilter="[agileTestPlatformAssembly.TestCaseFilter]" ExecutionPlatform="[agileTestPlatformAssembly.ExecutionPlatform]" />
</If.Else>
</If>
</If.Then>
</If>
</Sequence>
</If.Then>
<If.Else>
<If Condition="[TypeOf spec Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec]" DisplayName="If spec Is TestMetadataFileSpec" mtbwt:BuildTrackingParticipant.Importance="None">
<If.Then>
<Sequence DisplayName="Run MSTest for Metadata File">
<Sequence.Variables>
<Variable x:TypeArguments="mtbwa:TestMetadataFileSpec" Name="testMetadataFile" />
<Variable x:TypeArguments="x:String" Name="localTestMetadata" />
</Sequence.Variables>
<Assign x:TypeArguments="mtbwa:TestMetadataFileSpec" DisplayName="Assign spec to testMetadataFile" To="[testMetadataFile]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" Input="[testMetadataFile.MetadataFileName]" Result="[localTestMetadata]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:MSTest RunTitle="[testMetadataFile.RunName]" Category="[testMetadataFile.CategoryFilter]" DisplayName="Run MSTest for Metadata File" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testMetadataFile.MaximumPriority]" MinPriority="[testMetadataFile.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestLists="[testMetadataFile.TestLists]" TestMetadata="[localTestMetadata]" TestSettings="[String.Empty]" CommandLineArguments="[testMetadataFile.MSTestCommandLineArgs]" />
</Sequence>
</If.Then>
<If.Else>
<Sequence DisplayName="Run MSTest for Test Assemblies" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="mtbwa:TestAssemblySpec" Name="testAssembly" />
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="testAssemblies" />
<Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testFlavor" />
<Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testPlatform" />
</Sequence.Variables>
<Assign x:TypeArguments="mtbwa:TestAssemblySpec" DisplayName="Assign spec to testAssembly" To="[testAssembly]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestAssemblySpec)]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:FindMatchingFiles DisplayName="Find Test Assemblies" MatchPattern="[String.Format(&quot;{0}\{1}&quot;, outputDirectory, testAssembly.AssemblyFileSpec)]" Result="[testAssemblies]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[testAssemblies.Count() &gt; 0]" DisplayName="If Test Assemblies Found" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<If Condition="[testAssembly.HasTestSettingsFile]" DisplayName="If testAssembly.HasTestSettingsFile" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Find Test Settings File And Run MSTest" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localTestSettings" />
</Sequence.Variables>
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" Input="[testAssembly.TestSettingsFileName]" Result="[localTestSettings]" Workspace="[Workspace]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mtbwa:MSTest RunTitle="[testAssembly.RunName]" Category="[testAssembly.CategoryFilter]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" TestSettings="[localTestSettings]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" />
</Sequence>
</If.Then>
<If.Else>
<mtbwa:MSTest RunTitle="[testAssembly.RunName]" Category="[testAssembly.CategoryFilter]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" />
</If.Else>
</If>
</If.Then>
</If>
</Sequence>
</If.Else>
</If>
</If.Else>
</If>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception">
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="testException" />
</ActivityAction.Argument>
<Sequence DisplayName="Handle Test Run Exception">
<Sequence.Variables>
<Variable x:TypeArguments="scg:ICollection(mtbc:IQueuedBuild)" Name="failedRequests" />
</Sequence.Variables>
<If Condition="[Not (TypeOf testException Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestFailureException)]" DisplayName="If testException is NOT TestFailureException" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:WriteBuildError DisplayName="Write Test Failure Message" Message="[testException.Message]" />
</If.Then>
</If>
<mtbwa:SetBuildProperties DisplayName="Set TestStatus to Failed" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[spec.FailBuildOnFailure]" DisplayName="If spec.FailBuildOnFailure" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Assign x:TypeArguments="s:Boolean" DisplayName="Set treatTestFailureAsBuildFailure to True" To="[treatTestFailureAsBuildFailure]" Value="[True]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<mtbwa:GetApprovedRequests DisplayName="Get Requests Approved for Check In" Result="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="None" />
<mtbwa:RetryRequests Behavior="[Microsoft.TeamFoundation.Build.Workflow.Activities.RetryBehavior.DoNotBatch]" DisplayName="Mark Requests for Retry" Requests="[failedRequests]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</ActivityAction>
</ForEach>
</If.Then>
</If>
</Sequence>
</If.Then>
<If.Else>
<If Condition="[(Not TestSpecs Is Nothing) And (TestSpecs.Count > 0)]" DisplayName="If TestSpecs Is Not Nothing or Empty" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:WriteBuildWarning DisplayName="Write Warning" Message="No automated tests will be run for this build because tests have been disabled for this build definition. To enable these tests, edit this build definition and set the Disable Tests process parameter to false." />
</If.Then>
</If>
</If.Else>
</If>
</Sequence>
</ActivityAction>
</ForEach>
<If Condition="[BuildDetail.CompilationStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If CompilationStatus = Unknown" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" DisplayName="Set CompilationStatus to Succeeded" PropertiesToSet="CompilationStatus" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<If Condition="[BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If TestStatus = Unknown" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:SetBuildProperties DisplayName="Set TestStatus to Succeeded" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<If Condition="[treatTestFailureAsBuildFailure And (BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed)]" DisplayName="If TreatTestFailureAsBuildFailure And (TestStatus = Failed)" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:SetBuildProperties DisplayName="Set Status to Failed" PropertiesToSet="Status" Status="[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
</Sequence>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception">
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="compilationExceptionArgument" />
</ActivityAction.Argument>
<Assign x:TypeArguments="s:Exception" DisplayName="Save the Compilation Exception" To="[compilationException]" Value="[compilationExceptionArgument]" mtbwt:BuildTrackingParticipant.Importance="None" />
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
<If Condition="[AssociateChangesetsAndWorkItems]" DisplayName="If AssociateChangesetsAndWorkItems" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<If Condition="[CreateLabel]" DisplayName="If CreateLabel and AssociateChangesetsAndWorkItems" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Associate Changesets and Work Items for non-Shelveset Builds" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
<mtbwa:AssociateChangesetsAndWorkItems DisplayName="Associate Changesets and Work Items" Result="[associatedChangesets]" />
</mtbwa:InvokeForReason>
</If.Then>
<If.Else>
<mtbwa:WriteBuildWarning DisplayName="Write Associate Changesets and Work Items Warning" Message="Cannot Associate Changesets and Work Items because the Label Sources option is set to False." />
</If.Else>
</If>
</If.Then>
</If>
</Parallel>
<If Condition="[Not compilationException Is Nothing]" DisplayName="If a Compilation Exception Occurred" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Throw DisplayName="Rethrow Compilation Exception" Exception="[compilationException]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<Parallel DisplayName="Get Impacted Tests, Index Sources and Publish Symbols">
<If Condition="[PerformTestImpactAnalysis]" DisplayName="If PerformTestImpactAnalysis" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Get Impacted Tests" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="assemblies" />
</Sequence.Variables>
<mtbwa:FindMatchingFiles DisplayName="Find Build Outputs" MatchPattern="[String.Format(&quot;{0}\**\*.dll;{0}\**\*.exe&quot;, BinariesDirectory)]" Result="[assemblies]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<mttbb:GetImpactedTests Assemblies="[assemblies]" AssociatedChangesets="[associatedChangesets]" BinariesRoot="[BinariesDirectory]" Build="[BuildDetail]" CodeChanges="{x:Null}" DisplayName="Get Impacted Tests" ImpactedTests="{x:Null}" Workspace="[Workspace]" />
</Sequence>
</If.Then>
</If>
<If Condition="[SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Index Sources and Publish Symbols for Triggered Builds" Reason="Triggered">
<mtbwa:InvokeForReason.Variables>
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="symbolFiles" />
</mtbwa:InvokeForReason.Variables>
<mtbwa:FindMatchingFiles DisplayName="Find Symbol Files" MatchPattern="[String.Format(&quot;{0}\**\*.pdb&quot;, BinariesDirectory)]" Result="[symbolFiles]" mtbwt:BuildTrackingParticipant.Importance="Low" />
<If Condition="[SourceAndSymbolServerSettings.IndexSources]" DisplayName="If SourceAndSymbolServerSettings.IndexSources" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<TryCatch DisplayName="Try Index Sources" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<mtbwa:IndexSources DisplayName="Index Sources" FileList="[symbolFiles]" />
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception">
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
</ActivityAction.Argument>
<mtbwa:WriteBuildError DisplayName="Write Indexing Sources Error" Message="[exception.Message]" />
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</If.Then>
</If>
<If Condition="[SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.HasSymbolStorePath" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<TryCatch DisplayName="Try Publish Symbols" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<mtbwa:SharedResourceScope DisplayName="Synchronize Access to Symbol Store" MaxExecutionTime="[TimeSpan.Zero]" MaxWaitTime="[New TimeSpan(1, 0, 0)]" ResourceName="[SourceAndSymbolServerSettings.SymbolStorePath]" mtbwt:BuildTrackingParticipant.Importance="Low">
<mtbwa:PublishSymbols DisplayName="Publish Symbols" FileList="[symbolFiles]" ProductName="[BuildDetail.BuildDefinition.Name]" StorePath="[SourceAndSymbolServerSettings.SymbolStorePath]" Version="[BuildDetail.BuildNumber]" />
</mtbwa:SharedResourceScope>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception">
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
</ActivityAction.Argument>
<mtbwa:WriteBuildError DisplayName="Write Publishing Symbols Error" Message="[exception.Message]" />
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</If.Then>
</If>
</mtbwa:InvokeForReason>
</If.Then>
</If>
</Parallel>
</Sequence>
</TryCatch.Try>
</TryCatch>
</mtbwa:AgentScope>
<mtbwa:InvokeForReason DisplayName="Check In Gated Changes for CheckInShelveset Builds" Reason="CheckInShelveset">
<mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" />
</mtbwa:InvokeForReason>
</Sequence>
</Activity>

View file

@ -0,0 +1,602 @@
<Activity mc:Ignorable="sap" x:Class="TfsBuild.Process" this:Process.BuildSettings="[New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildSettings()]" this:Process.TestSpecs="[New Microsoft.TeamFoundation.Build.Workflow.Activities.TestSpecList(New Microsoft.TeamFoundation.Build.Workflow.Activities.TestAssemblySpec(&quot;**\*test*.dll&quot;))]" this:Process.BuildNumberFormat="[&quot;$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)&quot;]" this:Process.CleanWorkspace="[Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]" this:Process.RunCodeAnalysis="[Microsoft.TeamFoundation.Build.Workflow.Activities.CodeAnalysisOption.AsConfigured]" this:Process.SourceAndSymbolServerSettings="[New Microsoft.TeamFoundation.Build.Workflow.Activities.SourceAndSymbolServerSettings(True, Nothing)]" this:Process.AgentSettings="[New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }]" this:Process.AssociateChangesetsAndWorkItems="[True]" this:Process.CreateWorkItem="[True]" this:Process.DropBuild="[True]" this:Process.MSBuildPlatform="[Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto]" this:Process.PerformTestImpactAnalysis="[True]" this:Process.CreateLabel="[True]" this:Process.DisableTests="[False]" this:Process.Verbosity="[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]" this:Process.SupportedReasons="All" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mt="clr-namespace:Microsoft.TeamFoundation;assembly=Microsoft.TeamFoundation.Common" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwt="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Tracking;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mttbb="clr-namespace:Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities;assembly=Microsoft.TeamFoundation.TestImpact.BuildIntegration" xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mtvc1="clr-namespace:Microsoft.TeamFoundation.VersionControl.Common;assembly=Microsoft.TeamFoundation.VersionControl.Common" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:si="clr-namespace:System.IO;assembly=mscorlib" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:this="clr-namespace:TfsBuild" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="BuildSettings" Type="InArgument(mtbwa:BuildSettings)" />
<x:Property Name="TestSpecs" Type="InArgument(mtbwa:TestSpecList)" />
<x:Property Name="BuildNumberFormat" Type="InArgument(x:String)" />
<x:Property Name="CleanWorkspace" Type="InArgument(mtbwa:CleanWorkspaceOption)" />
<x:Property Name="RunCodeAnalysis" Type="InArgument(mtbwa:CodeAnalysisOption)" />
<x:Property Name="SourceAndSymbolServerSettings" Type="InArgument(mtbwa:SourceAndSymbolServerSettings)" />
<x:Property Name="AgentSettings" Type="InArgument(mtbwa:AgentSettings)" />
<x:Property Name="AssociateChangesetsAndWorkItems" Type="InArgument(x:Boolean)" />
<x:Property Name="CreateWorkItem" Type="InArgument(x:Boolean)" />
<x:Property Name="DropBuild" Type="InArgument(x:Boolean)" />
<x:Property Name="MSBuildArguments" Type="InArgument(x:String)" />
<x:Property Name="MSBuildPlatform" Type="InArgument(mtbwa:ToolPlatform)" />
<x:Property Name="PerformTestImpactAnalysis" Type="InArgument(x:Boolean)" />
<x:Property Name="CreateLabel" Type="InArgument(x:Boolean)" />
<x:Property Name="DisableTests" Type="InArgument(x:Boolean)" />
<x:Property Name="GetVersion" Type="InArgument(x:String)" />
<x:Property Name="PrivateDropLocation" Type="InArgument(x:String)" />
<x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
<x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
<x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
</x:Members>
<this:Process.MSBuildArguments>
<InArgument x:TypeArguments="x:String" />
</this:Process.MSBuildArguments>
<this:Process.GetVersion>
<InArgument x:TypeArguments="x:String" />
</this:Process.GetVersion>
<this:Process.Metadata>
<mtbw:ProcessParameterMetadataCollection />
</this:Process.Metadata>
<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="ShouldExpandAll">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Sequence sad:XamlDebuggerXmlReader.FileName="C:\vstf\lab26vsts\src\vset\SCM\BigBuild\templates\defaulttemplate.xaml" sap:VirtualizedContainerService.HintSize="1972,13038" mtbwt:BuildTrackingParticipant.Importance="None">
<Sequence.Variables>
<Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:GetBuildDetail DisplayName="Get the Build" sap:VirtualizedContainerService.HintSize="1950,22" mtbwt:BuildTrackingParticipant.Importance="Low" Result="[BuildDetail]" />
<Sequence DisplayName="Update Drop Location" sap:VirtualizedContainerService.HintSize="1950,1310" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:InvokeForReason DisplayName="Update Build Number for Triggered Builds" sap:VirtualizedContainerService.HintSize="611,146" Reason="Triggered">
<mtbwa:UpdateBuildNumber BuildNumberFormat="[BuildNumberFormat]" DisplayName="Update Build Number" sap:VirtualizedContainerService.HintSize="200,22" />
</mtbwa:InvokeForReason>
<If Condition="[DropBuild AndAlso (BuildDetail.Reason And Microsoft.TeamFoundation.Build.Client.BuildReason.Triggered) = BuildDetail.Reason]" DisplayName="If DropBuild And Build Reason is Triggered" sap:VirtualizedContainerService.HintSize="611,550" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence sap:VirtualizedContainerService.HintSize="486,449" mtbwt:BuildTrackingParticipant.Importance="None">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<If Condition="[String.IsNullOrEmpty(BuildDetail.DropLocationRoot)]" DisplayName="If DropLocationRoot is empty" sap:VirtualizedContainerService.HintSize="464,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Throw DisplayName="Throw EmptyDropLocationRootException" Exception="[New Microsoft.TeamFoundation.Build.Workflow.Activities.EmptyDropLocationRootException(BuildDetail.BuildDefinition.Name)]" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<mtbwa:SetBuildProperties DisplayName="Set Drop Location" DropLocation="[BuildDetail.DropLocationRoot + &quot;\&quot; + BuildDetail.BuildDefinition.Name + &quot;\&quot; + BuildDetail.BuildNumber]" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="DropLocation" />
<mtbwa:CreateDirectory Directory="[BuildDetail.DropLocation]" DisplayName="Create the Drop Location" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Normal" />
</Sequence>
</If.Then>
</If>
<If Condition="[DropBuild AndAlso BuildDetail.Reason = Microsoft.TeamFoundation.Build.Client.BuildReason.ValidateShelveset]" DisplayName="If DropBuild And Build Reason is ValidateShelveset" sap:VirtualizedContainerService.HintSize="611,410" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<If Condition="[Not String.IsNullOrEmpty(PrivateDropLocation)]" sap:VirtualizedContainerService.HintSize="464,309" mtbwt:BuildTrackingParticipant.Importance="None">
<If.Then>
<Sequence sap:VirtualizedContainerService.HintSize="231,208" mtbwt:BuildTrackingParticipant.Importance="None">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:SetBuildProperties DisplayName="Set Drop Location for Private Build" DropLocation="[PrivateDropLocation + &quot;\&quot; + BuildDetail.BuildDefinition.Name + &quot;\&quot; + BuildDetail.BuildNumber]" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="DropLocation" />
<mtbwa:CreateDirectory Directory="[BuildDetail.DropLocation]" DisplayName="Create the Drop Location" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" />
</Sequence>
</If.Then>
<If.Else>
<mtbwa:WriteBuildWarning sap:VirtualizedContainerService.HintSize="208,208" Message="The build outputs for this private build will not be copied to the drop location because the PrivateDropLocation is not set." />
</If.Else>
</If>
</If.Then>
</If>
</Sequence>
<mtbwa:AgentScope DisplayName="Run On Agent" sap:VirtualizedContainerService.HintSize="1950,11316" MaxExecutionTime="[AgentSettings.MaxExecutionTime]" MaxWaitTime="[AgentSettings.MaxWaitTime]" ReservationSpec="[AgentSettings.GetAgentReservationSpec()]">
<mtbwa:AgentScope.Variables>
<Variable x:TypeArguments="mtbc:IBuildAgent" Name="BuildAgent" />
<Variable x:TypeArguments="mtvc:Workspace" Name="Workspace" />
<Variable x:TypeArguments="x:String" Name="BuildDirectory" />
<Variable x:TypeArguments="x:String" Default="[BuildDetail.BuildNumber]" Name="LabelName" />
<Variable x:TypeArguments="x:String" Name="WorkspaceName" />
<Variable x:TypeArguments="x:String" Name="SourcesDirectory" />
<Variable x:TypeArguments="x:String" Name="BinariesDirectory" />
<Variable x:TypeArguments="x:String" Name="TestResultsDirectory" />
</mtbwa:AgentScope.Variables>
<Sequence DisplayName="Initialize Variables" sap:VirtualizedContainerService.HintSize="1928,1046" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:GetBuildAgent DisplayName="Get the Agent" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" Result="[BuildAgent]" />
<mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" Result="[BuildDirectory]" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize Workspace Name" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[WorkspaceName]" Value="[String.Format(&quot;{0}_{1}_{2}&quot;, BuildDetail.BuildDefinition.Id, Microsoft.TeamFoundation.LinkingUtilities.DecodeUri(BuildAgent.Uri.AbsoluteUri).ToolSpecificId, BuildAgent.ServiceHost.Name)]" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize Sources Directory" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[SourcesDirectory]" Value="[String.Format(&quot;{0}\Sources&quot;, BuildDirectory)]" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize Binaries Directory" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[BinariesDirectory]" Value="[String.Format(&quot;{0}\Binaries&quot;, BuildDirectory)]" />
<Assign x:TypeArguments="x:String" DisplayName="Initialize TestResults Directory" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[TestResultsDirectory]" Value="[String.Format(&quot;{0}\TestResults&quot;, BuildDirectory)]" />
<If Condition="[Not BuildSettings.HasPlatformConfigurations]" DisplayName="If Not BuildSettings.HasPlatformConfigurations" sap:VirtualizedContainerService.HintSize="464,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<AddToCollection x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="Use Default Platform Configuration" Collection="[BuildSettings.PlatformConfigurations]" Item="[Microsoft.TeamFoundation.Build.Workflow.Activities.PlatformConfiguration.Default]" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<If Condition="[WorkspaceName.Length &gt; Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize]" DisplayName="If WorkspaceName &gt; MaxSize" sap:VirtualizedContainerService.HintSize="464,309" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence sap:VirtualizedContainerService.HintSize="281,208" mtbwt:BuildTrackingParticipant.Importance="None">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:WriteBuildWarning sap:VirtualizedContainerService.HintSize="200,22" Message="[String.Format(&quot;The workspace name '{0}' exceeds the maximum allowed limit of '{1}' characters. Truncating it to match the maximum limit.&quot;, WorkspaceName, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize)]" />
<Assign x:TypeArguments="x:String" DisplayName="Truncate WorkspaceName to MaxSize" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[WorkspaceName]" Value="[WorkspaceName.Substring(0, Microsoft.TeamFoundation.VersionControl.Common.RepositoryConstants.MaxWorkspaceNameSize).TrimEnd()]" />
</Sequence>
</If.Then>
</If>
</Sequence>
<Sequence DisplayName="Initialize Workspace" sap:VirtualizedContainerService.HintSize="1928,1819" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:DeleteDirectory Directory="[TestResultsDirectory]" DisplayName="Delete Test Results Directory" sap:VirtualizedContainerService.HintSize="818,22" mtbwt:BuildTrackingParticipant.Importance="Normal" Recursive="[True]" />
<If Condition="[Not CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.None]" DisplayName="If Not CleanWorkspace = CleanWorkspaceOption.None" sap:VirtualizedContainerService.HintSize="818,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:DeleteDirectory Directory="[BinariesDirectory]" DisplayName="Delete Binaries Directory" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Normal" />
</If.Then>
</If>
<If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.All" sap:VirtualizedContainerService.HintSize="818,309" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Delete Workspace and Sources Directory" sap:VirtualizedContainerService.HintSize="281,208" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:DeleteWorkspace DeleteLocalItems="[True]" DisplayName="Delete Workspace" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" Name="[WorkspaceName]" />
<mtbwa:DeleteDirectory Directory="[SourcesDirectory]" DisplayName="Delete Sources Directory" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Normal" />
</Sequence>
</If.Then>
</If>
<mtbwa:CreateWorkspace BuildDirectory="[BuildDirectory]" Comment="[&quot;Workspace Created by Team Build&quot;]" DisplayName="Create Workspace" sap:VirtualizedContainerService.HintSize="818,22" Name="[WorkspaceName]" Result="[Workspace]" SourcesDirectory="[SourcesDirectory]" />
<If Condition="[CleanWorkspace = Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.Outputs]" DisplayName="If CleanWorkspace = CleanWorkspaceOption.Outputs" sap:VirtualizedContainerService.HintSize="818,919" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" sap:VirtualizedContainerService.HintSize="693,818" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.PlatformConfigurations]">
<ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
</ActivityAction.Argument>
<Sequence DisplayName="Clean Configuration" sap:VirtualizedContainerService.HintSize="663,715">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" sap:VirtualizedContainerService.HintSize="641,591" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" sap:VirtualizedContainerService.HintSize="516,490" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.ProjectsToBuild]">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
</ActivityAction.Argument>
<Sequence DisplayName="Clean Project" sap:VirtualizedContainerService.HintSize="486,387" mtbwt:BuildTrackingParticipant.Importance="Normal">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localBuildProjectItem" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Paths to Local Paths" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[serverBuildProjectItem]" Result="[localBuildProjectItem]" Workspace="[Workspace]" />
<If Condition="[System.IO.File.Exists(localBuildProjectItem)]" DisplayName="If File.Exists(Project)" sap:VirtualizedContainerService.HintSize="464,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" sap:VirtualizedContainerService.HintSize="269,100" OutDir="[BinariesDirectory]" Platform="[platformConfiguration.Platform]" Project="[localBuildProjectItem]" Targets="[New String() { &quot;Clean&quot; }]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
</If.Then>
</If>
</Sequence>
</ActivityAction>
</ForEach>
</If.Then>
</If>
</Sequence>
</ActivityAction>
</ForEach>
</If.Then>
</If>
<mtbwa:SyncWorkspace DisplayName="Get Workspace" sap:VirtualizedContainerService.HintSize="818,22" VersionOverride="[GetVersion]" Workspace="[Workspace]" />
</Sequence>
<If Condition="[CreateLabel]" DisplayName="If CreateLabel" sap:VirtualizedContainerService.HintSize="1928,309" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Create and Set Label for non-Shelveset Builds" sap:VirtualizedContainerService.HintSize="281,208" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
<mtbwa:LabelWorkspace Comment="[&quot;Label Created by Team Build&quot;]" DisplayName="Create Label" sap:VirtualizedContainerService.HintSize="200,22" Name="[LabelName]" Scope="[String.Format(&quot;$/{0}&quot;, BuildDetail.BuildDefinition.TeamProject)]" Workspace="[Workspace]" />
<mtbwa:SetBuildProperties DisplayName="Set Label on BuildDetail" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" LabelName="[String.Format(&quot;{0}@$/{1}&quot;, LabelName, BuildDetail.BuildDefinition.TeamProject)]" PropertiesToSet="LabelName" />
</mtbwa:InvokeForReason>
</If.Then>
</If>
<TryCatch DisplayName="Try Compile, Test, and Associate Changesets and Work Items" sap:VirtualizedContainerService.HintSize="1928,7898" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Finally>
<Sequence DisplayName="Revert Workspace and Copy Files to Drop Location" sap:VirtualizedContainerService.HintSize="1910,511" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:InvokeForReason DisplayName="Revert Workspace for Shelveset Builds" sap:VirtualizedContainerService.HintSize="464,146" Reason="ValidateShelveset, CheckInShelveset">
<mtbwa:RevertWorkspace DisplayName="Revert Workspace" sap:VirtualizedContainerService.HintSize="200,22" Workspace="[Workspace]" />
</mtbwa:InvokeForReason>
<If Condition="[DropBuild AndAlso Not String.IsNullOrEmpty(BuildDetail.DropLocation)]" DisplayName="If DropBuild And DropLocation is Set" sap:VirtualizedContainerService.HintSize="464,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:CopyDirectory Destination="[BuildDetail.DropLocation]" DisplayName="Copy Files to Drop Location" sap:VirtualizedContainerService.HintSize="269,100" Source="[BinariesDirectory]" />
</If.Then>
</If>
</Sequence>
</TryCatch.Finally>
<TryCatch.Try>
<Sequence sap:VirtualizedContainerService.HintSize="1910,7226" mtbwt:BuildTrackingParticipant.Importance="None">
<Sequence.Variables>
<Variable x:TypeArguments="s:Exception" Name="compilationException" />
<Variable x:TypeArguments="scg:IList(mtvc:Changeset)" Name="associatedChangesets" />
<Variable x:TypeArguments="x:Boolean" Name="treatTestFailureAsBuildFailure" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Parallel DisplayName="Compile, Test, and Associate Changesets and Work Items" sap:VirtualizedContainerService.HintSize="1888,5264">
<TryCatch DisplayName="Try Compile and Test" sap:VirtualizedContainerService.HintSize="1270,5218" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<Sequence DisplayName="Compile and Test" sap:VirtualizedContainerService.HintSize="1252,4850">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<ForEach x:TypeArguments="mtbwa:PlatformConfiguration" DisplayName="For Each Configuration in BuildSettings.PlatformConfigurations" sap:VirtualizedContainerService.HintSize="1230,4003" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.PlatformConfigurations]">
<ActivityAction x:TypeArguments="mtbwa:PlatformConfiguration">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="mtbwa:PlatformConfiguration" Name="platformConfiguration" />
</ActivityAction.Argument>
<Sequence DisplayName="Compile and Test for Configuration" sap:VirtualizedContainerService.HintSize="1200,3900" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="outputDirectory" />
<Variable x:TypeArguments="x:String" Name="logFileDropLocation" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Sequence DisplayName="Initialize Variables" sap:VirtualizedContainerService.HintSize="1178,387" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Assign x:TypeArguments="x:String" DisplayName="Initialize OutputDirectory" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[outputDirectory]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BinariesDirectory, If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BinariesDirectory + &quot;\&quot; + platformConfiguration.Configuration, BinariesDirectory + &quot;\&quot; + platformConfiguration.Platform + &quot;\&quot; + platformConfiguration.Configuration))]" />
<If Condition="[Not String.IsNullOrEmpty(BuildDetail.DropLocation)]" DisplayName="If DropLocation is Set" sap:VirtualizedContainerService.HintSize="464,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Assign x:TypeArguments="x:String" DisplayName="Initialize LogFile Drop Location" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" To="[logFileDropLocation]" Value="[If (platformConfiguration.IsEmpty Or BuildSettings.PlatformConfigurations.Count = 1, BuildDetail.DropLocation + &quot;\logs&quot;, If (platformConfiguration.IsPlatformEmptyOrAnyCpu, BuildDetail.DropLocation + &quot;\logs\&quot; + platformConfiguration.Configuration, BuildDetail.DropLocation + &quot;\logs\&quot; + platformConfiguration.Platform + &quot;\&quot; + platformConfiguration.Configuration))]" />
</If.Then>
</If>
</Sequence>
<If Condition="[BuildSettings.HasProjectsToBuild]" DisplayName="If BuildSettings.HasProjectsToBuild" sap:VirtualizedContainerService.HintSize="1178,1379" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="x:String" DisplayName="For Each Project in BuildSettings.ProjectsToBuild" sap:VirtualizedContainerService.HintSize="536,1278" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[BuildSettings.ProjectsToBuild]">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="serverBuildProjectItem" />
</ActivityAction.Argument>
<TryCatch DisplayName="Try to Compile the Project" sap:VirtualizedContainerService.HintSize="506,1175" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<Sequence DisplayName="Compile the Project" sap:VirtualizedContainerService.HintSize="488,387" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localProject" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[serverBuildProjectItem]" Result="[localProject]" Workspace="[Workspace]" />
<If Condition="[Not System.IO.File.Exists(localProject)]" DisplayName="If Local File Doesn't Exist" sap:VirtualizedContainerService.HintSize="464,201">
<If.Then>
<Throw DisplayName="Throw FileNotFoundException" Exception="[New System.IO.FileNotFoundException(String.Format(&quot;The file {0} could not be found.&quot;, localProject), localProject)]" sap:VirtualizedContainerService.HintSize="219,100" />
</If.Then>
<If.Else>
<mtbwa:MSBuild CommandLineArguments="[String.Format(&quot;/p:SkipInvalidConfigurations=true {0}&quot;, MSBuildArguments)]" Configuration="[platformConfiguration.Configuration]" DisplayName="Run MSBuild for Project" GenerateVSPropsFile="[True]" sap:VirtualizedContainerService.HintSize="220,100" LogFileDropLocation="[logFileDropLocation]" OutDir="[outputDirectory]" Platform="[platformConfiguration.Platform]" Project="[localProject]" RunCodeAnalysis="[RunCodeAnalysis]" TargetsNotLogged="[New String() {&quot;GetNativeManifest&quot;, &quot;GetCopyToOutputDirectoryItems&quot;, &quot;GetTargetPath&quot;}]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
</If.Else>
</If>
</Sequence>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception" sap:VirtualizedContainerService.HintSize="492,526">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">False</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="ex" />
</ActivityAction.Argument>
<Sequence DisplayName="Handle Exception" sap:VirtualizedContainerService.HintSize="486,495">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" DisplayName="Set CompilationStatus to Failed" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="CompilationStatus" />
<If Condition="[CreateWorkItem]" DisplayName="If CreateWorkItem" sap:VirtualizedContainerService.HintSize="464,247" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Create Work Item for non-Shelveset Builds" sap:VirtualizedContainerService.HintSize="281,146" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
<mtbwa:OpenWorkItem AssignedTo="[BuildDetail.RequestedFor]" Comment="[&quot;This work item was created by TFS Build on a build failure.&quot;]" CustomFields="[New Dictionary(Of String, String) From { {&quot;System.Reason&quot;, &quot;Build Failure&quot;}, {&quot;Microsoft.VSTS.TCM.ReproSteps&quot;, &quot;Start the build using TFS Build&quot;}, {&quot;Priority&quot;, &quot;1&quot;}, {&quot;Severity&quot;, &quot;1 - Critical&quot;} }]" DisplayName="Create Work Item" sap:VirtualizedContainerService.HintSize="200,22" Title="[String.Format(&quot;Build Failure in Build: {0}&quot;, BuildDetail.BuildNumber)]" Type="[&quot;Bug&quot;]" />
</mtbwa:InvokeForReason>
</If.Then>
</If>
<Rethrow DisplayName="Rethrow the exception so the build will stop" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" />
</Sequence>
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</ActivityAction>
</ForEach>
</If.Then>
</If>
<If Condition="[Not DisableTests]" DisplayName="If Not DisableTests" sap:VirtualizedContainerService.HintSize="1178,1930" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Run Tests" sap:VirtualizedContainerService.HintSize="1053,1829" mtbwt:BuildTrackingParticipant.Importance="Low">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<If Condition="[Not TestSpecs Is Nothing]" DisplayName="If Not TestSpecs Is Nothing" sap:VirtualizedContainerService.HintSize="1031,1705" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<ForEach x:TypeArguments="mtbwa:TestSpec" DisplayName="For Each TestSpec in TestSpecs" sap:VirtualizedContainerService.HintSize="906,1604" mtbwt:BuildTrackingParticipant.Importance="Low" Values="[TestSpecs]">
<ActivityAction x:TypeArguments="mtbwa:TestSpec">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="mtbwa:TestSpec" Name="spec" />
</ActivityAction.Argument>
<TryCatch DisplayName="Try Run Tests" sap:VirtualizedContainerService.HintSize="876,1501" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<If Condition="[TypeOf spec Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec]" DisplayName="If spec Is TestMetadataFileSpec" sap:VirtualizedContainerService.HintSize="858,759" mtbwt:BuildTrackingParticipant.Importance="None">
<If.Then>
<Sequence DisplayName="Run MSTest for Metadata File" sap:VirtualizedContainerService.HintSize="222,658">
<Sequence.Variables>
<Variable x:TypeArguments="mtbwa:TestMetadataFileSpec" Name="testMetadataFile" />
<Variable x:TypeArguments="x:String" Name="localTestMetadata" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Assign x:TypeArguments="mtbwa:TestMetadataFileSpec" DisplayName="Assign spec to testMetadataFile" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[testMetadataFile]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestMetadataFileSpec)]" />
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[testMetadataFile.MetadataFileName]" Result="[localTestMetadata]" Workspace="[Workspace]" />
<mtbwa:MSTest Category="[testMetadataFile.CategoryFilter]" CommandLineArguments="[testMetadataFile.MSTestCommandLineArgs]" DisplayName="Run MSTest for Metadata File" Flavor="[platformConfiguration.Configuration]" sap:VirtualizedContainerService.HintSize="200,22" MaxPriority="[testMetadataFile.MaximumPriority]" MinPriority="[testMetadataFile.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestLists="[testMetadataFile.TestLists]" TestMetadata="[localTestMetadata]" TestSettings="[String.Empty]" />
</Sequence>
</If.Then>
<If.Else>
<Sequence DisplayName="Run MSTest for Test Assemblies" sap:VirtualizedContainerService.HintSize="611,658" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="mtbwa:TestAssemblySpec" Name="testAssembly" />
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="testAssemblies" />
<Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testFlavor" />
<Variable x:TypeArguments="x:String" Default="[String.Empty]" Name="testPlatform" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Assign x:TypeArguments="mtbwa:TestAssemblySpec" DisplayName="Assign spec to testAssembly" sap:VirtualizedContainerService.HintSize="589,22" mtbwt:BuildTrackingParticipant.Importance="Low" To="[testAssembly]" Value="[DirectCast(spec, Microsoft.TeamFoundation.Build.Workflow.Activities.TestAssemblySpec)]" />
<mtbwa:FindMatchingFiles DisplayName="Find Test Assemblies" sap:VirtualizedContainerService.HintSize="589,22" mtbwt:BuildTrackingParticipant.Importance="Low" MatchPattern="[String.Format(&quot;{0}\{1}&quot;, outputDirectory, testAssembly.AssemblyFileSpec)]" Result="[testAssemblies]" />
<If Condition="[testAssemblies.Count() &gt; 0]" DisplayName="If Test Assemblies Found" sap:VirtualizedContainerService.HintSize="589,410" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<If Condition="[testAssembly.HasTestSettingsFile]" DisplayName="If testAssembly.HasTestSettingsFile" sap:VirtualizedContainerService.HintSize="464,309" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Find Test Settings File And Run MSTest" sap:VirtualizedContainerService.HintSize="231,208" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="x:String" Name="localTestSettings" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:ConvertWorkspaceItem DisplayName="Convert Server Path to Local Path" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" Input="[testAssembly.TestSettingsFileName]" Result="[localTestSettings]" Workspace="[Workspace]" />
<mtbwa:MSTest Category="[testAssembly.CategoryFilter]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" sap:VirtualizedContainerService.HintSize="200,22" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" TestSettings="[localTestSettings]" />
</Sequence>
</If.Then>
<If.Else>
<mtbwa:MSTest Category="[testAssembly.CategoryFilter]" CommandLineArguments="[testAssembly.MSTestCommandLineArgs]" DisplayName="Run MSTest for Test Assemblies" Flavor="[platformConfiguration.Configuration]" sap:VirtualizedContainerService.HintSize="208,208" MaxPriority="[testAssembly.MaximumPriority]" MinPriority="[testAssembly.MinimumPriority]" PathToResultsFilesRoot="[TestResultsDirectory]" Platform="[platformConfiguration.Platform]" SearchPathRoot="[outputDirectory]" TestContainers="[testAssemblies]" />
</If.Else>
</If>
</If.Then>
</If>
</Sequence>
</If.Else>
</If>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception" sap:VirtualizedContainerService.HintSize="862,480">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">False</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="testException" />
</ActivityAction.Argument>
<Sequence DisplayName="Handle MSTest Exception" sap:VirtualizedContainerService.HintSize="856,449">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<If Condition="[Not (TypeOf testException Is Microsoft.TeamFoundation.Build.Workflow.Activities.TestFailureException)]" DisplayName="If testException is NOT TestFailureException" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:WriteBuildError DisplayName="Write Test Failure Exception message" Message="[testException.Message]" />
</If.Then>
</If>
<mtbwa:SetBuildProperties DisplayName="Set TestStatus to Failed" sap:VirtualizedContainerService.HintSize="464,22" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed]" />
<If Condition="[spec.FailBuildOnFailure]" DisplayName="If spec.FailBuildOnFailure" sap:VirtualizedContainerService.HintSize="464,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Assign x:TypeArguments="x:Boolean" DisplayName="Set treatTestFailureAsBuildFailure to True" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" To="[treatTestFailureAsBuildFailure]" Value="[True]" />
</If.Then>
</If>
</Sequence>
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</ActivityAction>
</ForEach>
</If.Then>
</If>
</Sequence>
</If.Then>
</If>
</Sequence>
</ActivityAction>
</ForEach>
<If Condition="[BuildDetail.CompilationStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If CompilationStatus = Unknown" sap:VirtualizedContainerService.HintSize="1230,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" DisplayName="Set CompilationStatus to Succeeded" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="CompilationStatus" />
</If.Then>
</If>
<If Condition="[BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If TestStatus = Unknown" sap:VirtualizedContainerService.HintSize="1230,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:SetBuildProperties DisplayName="Set TestStatus to Succeeded" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" />
</If.Then>
</If>
<If Condition="[treatTestFailureAsBuildFailure And (BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Failed)]" DisplayName="If TreatTestFailureAsBuildFailure And (TestStatus = Failed)" sap:VirtualizedContainerService.HintSize="1230,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:SetBuildProperties DisplayName="Set Status to Failed" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" PropertiesToSet="Status" Status="[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]" />
</If.Then>
</If>
</Sequence>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception" sap:VirtualizedContainerService.HintSize="1256,106">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">False</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="compilationExceptionArgument" />
</ActivityAction.Argument>
<Assign x:TypeArguments="s:Exception" DisplayName="Save the Compilation Exception" sap:VirtualizedContainerService.HintSize="1250,75" mtbwt:BuildTrackingParticipant.Importance="None" To="[compilationException]" Value="[compilationExceptionArgument]" />
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
<If Condition="[AssociateChangesetsAndWorkItems]" DisplayName="If AssociateChangesetsAndWorkItems" sap:VirtualizedContainerService.HintSize="464,5218" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Associate Changesets and Work Items for non-Shelveset Builds" sap:VirtualizedContainerService.HintSize="281,146" Reason="Manual, IndividualCI, BatchedCI, Schedule, ScheduleForced, UserCreated">
<mtbwa:AssociateChangesetsAndWorkItems DisplayName="Associate Changesets and Work Items" Result="[associatedChangesets]" />
</mtbwa:InvokeForReason>
</If.Then>
</If>
</Parallel>
<If Condition="[Not compilationException Is Nothing]" DisplayName="If a Compilation Exception Occurred" sap:VirtualizedContainerService.HintSize="1888,201" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Throw DisplayName="Rethrow Compilation Exception" Exception="[compilationException]" sap:VirtualizedContainerService.HintSize="269,100" mtbwt:BuildTrackingParticipant.Importance="Low" />
</If.Then>
</If>
<Parallel DisplayName="Get Impacted Tests, Index Sources and Publish Symbols" sap:VirtualizedContainerService.HintSize="1888,1557">
<If Condition="[PerformTestImpactAnalysis]" DisplayName="If PerformTestImpactAnalysis" sap:VirtualizedContainerService.HintSize="464,1511" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<Sequence DisplayName="Get Impacted Tests" sap:VirtualizedContainerService.HintSize="281,208" mtbwt:BuildTrackingParticipant.Importance="Low">
<Sequence.Variables>
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="assemblies" />
</Sequence.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtbwa:FindMatchingFiles DisplayName="Find Build Outputs" sap:VirtualizedContainerService.HintSize="200,22" mtbwt:BuildTrackingParticipant.Importance="Low" MatchPattern="[String.Format(&quot;{0}\**\*.dll;{0}\**\*.exe&quot;, BinariesDirectory)]" Result="[assemblies]" />
<mttbb:GetImpactedTests Assemblies="[assemblies]" AssociatedChangesets="[associatedChangesets]" BinariesRoot="[BinariesDirectory]" Build="[BuildDetail]" CodeChanges="{x:Null}" DisplayName="Get Impacted Tests" ImpactedTests="{x:Null}" Workspace="[Workspace]" />
</Sequence>
</If.Then>
</If>
<If Condition="[SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.IndexSources Or SourceAndSymbolServerSettings.HasSymbolStorePath" sap:VirtualizedContainerService.HintSize="690,1511" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<mtbwa:InvokeForReason DisplayName="Index Sources and Publish Symbols for Triggered Builds" sap:VirtualizedContainerService.HintSize="565,1410" Reason="Triggered">
<mtbwa:InvokeForReason.Variables>
<Variable x:TypeArguments="scg:IEnumerable(x:String)" Name="symbolFiles" />
</mtbwa:InvokeForReason.Variables>
<mtbwa:FindMatchingFiles DisplayName="Find Symbol Files" sap:VirtualizedContainerService.HintSize="543,22" mtbwt:BuildTrackingParticipant.Importance="Low" MatchPattern="[String.Format(&quot;{0}\**\*.pdb&quot;, BinariesDirectory)]" Result="[symbolFiles]" />
<If Condition="[SourceAndSymbolServerSettings.IndexSources]" DisplayName="If SourceAndSymbolServerSettings.IndexSources" sap:VirtualizedContainerService.HintSize="543,569" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<TryCatch DisplayName="Try Index Sources" sap:VirtualizedContainerService.HintSize="418,468" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<mtbwa:IndexSources DisplayName="Index Sources" FileList="[symbolFiles]" sap:VirtualizedContainerService.HintSize="400,100" />
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception" sap:VirtualizedContainerService.HintSize="404,106">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">False</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
</ActivityAction.Argument>
<mtbwa:WriteBuildError sap:VirtualizedContainerService.HintSize="398,75" Message="[exception.Message]" />
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</If.Then>
</If>
<If Condition="[SourceAndSymbolServerSettings.HasSymbolStorePath]" DisplayName="If SourceAndSymbolServerSettings.HasSymbolStorePath" sap:VirtualizedContainerService.HintSize="543,615" mtbwt:BuildTrackingParticipant.Importance="Low">
<If.Then>
<TryCatch DisplayName="Try Publish Symbols" sap:VirtualizedContainerService.HintSize="418,514" mtbwt:BuildTrackingParticipant.Importance="Low">
<TryCatch.Try>
<mtbwa:SharedResourceScope DisplayName="Synchronize Access to Symbol Store" sap:VirtualizedContainerService.HintSize="400,146" mtbwt:BuildTrackingParticipant.Importance="Low" MaxExecutionTime="[TimeSpan.Zero]" MaxWaitTime="[New TimeSpan(1, 0, 0)]" ResourceName="[SourceAndSymbolServerSettings.SymbolStorePath]">
<mtbwa:PublishSymbols DisplayName="Publish Symbols" FileList="[symbolFiles]" sap:VirtualizedContainerService.HintSize="200,22" ProductName="[BuildDetail.BuildDefinition.Name]" StorePath="[SourceAndSymbolServerSettings.SymbolStorePath]" Version="[BuildDetail.BuildNumber]" />
</mtbwa:SharedResourceScope>
</TryCatch.Try>
<TryCatch.Catches>
<Catch x:TypeArguments="s:Exception" sap:VirtualizedContainerService.HintSize="404,106">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">False</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<ActivityAction x:TypeArguments="s:Exception">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="s:Exception" Name="exception" />
</ActivityAction.Argument>
<mtbwa:WriteBuildError sap:VirtualizedContainerService.HintSize="398,75" Message="[exception.Message]" />
</ActivityAction>
</Catch>
</TryCatch.Catches>
</TryCatch>
</If.Then>
</If>
</mtbwa:InvokeForReason>
</If.Then>
</If>
</Parallel>
</Sequence>
</TryCatch.Try>
</TryCatch>
</mtbwa:AgentScope>
<mtbwa:InvokeForReason DisplayName="Check In Gated Changes for CheckInShelveset Builds" sap:VirtualizedContainerService.HintSize="1950,146" Reason="CheckInShelveset">
<mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" sap:VirtualizedContainerService.HintSize="200,22" />
</mtbwa:InvokeForReason>
</Sequence>
</Activity>

View file

@ -0,0 +1,208 @@
<Activity mc:Ignorable="sads sap" x:Class="TfsBuild.Process" this:Process.LabWorkflowParameters="[New Microsoft.TeamFoundation.Lab.Workflow.Activities.LabWorkflowDetails()]" this:Process.Verbosity="[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]" this:Process.BuildNumberFormat="[&quot;$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)&quot;]" this:Process.SupportedReasons="Manual, BatchedCI, Schedule, ScheduleForced" this:Process.TimeoutForDeploymentScriptInMinutes="30" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mt="clr-namespace:Microsoft.TeamFoundation;assembly=Microsoft.TeamFoundation.Common" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbc1="clr-namespace:Microsoft.TeamFoundation.Build.Common;assembly=Microsoft.TeamFoundation.Build.Common" xmlns:mtbp="clr-namespace:Microsoft.TeamFoundation.Build.ProcessComponents;assembly=Microsoft.TeamFoundation.Build.ProcessComponents" xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbws="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Services;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtlc="clr-namespace:Microsoft.TeamFoundation.Lab.Client;assembly=Microsoft.TeamFoundation.Lab.Client" xmlns:mtltc="clr-namespace:Microsoft.TeamFoundation.Lab.TestIntegration.Client;assembly=Microsoft.TeamFoundation.Lab.TestIntegration.Client" xmlns:mtlwa="clr-namespace:Microsoft.TeamFoundation.Lab.Workflow.Activities;assembly=Microsoft.TeamFoundation.Lab.Workflow.Activities" xmlns:mtlwc="clr-namespace:Microsoft.TeamFoundation.Lab.WorkflowIntegration.Client;assembly=Microsoft.TeamFoundation.Lab.WorkflowIntegration.Client" xmlns:mttbb="clr-namespace:Microsoft.TeamFoundation.TestImpact.BuildIntegration.BuildActivities;assembly=Microsoft.TeamFoundation.TestImpact.BuildIntegration" xmlns:mttc="clr-namespace:Microsoft.TeamFoundation.TestManagement.Client;assembly=Microsoft.TeamFoundation.TestManagement.Client" xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Core" xmlns:s3="clr-namespace:System;assembly=System.ServiceModel" xmlns:s4="clr-namespace:System;assembly=System.ComponentModel.Composition" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sads="http://schemas.microsoft.com/netfx/2010/xaml/activities/debugger" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:this="clr-namespace:TfsBuild" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="BuildProcessVersion" Type="x:String" />
<x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
<x:Property Name="LabWorkflowParameters" Type="InArgument(mtlwa:LabWorkflowDetails)" />
<x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
<x:Property Name="BuildNumberFormat" Type="InArgument(x:String)" />
<x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
<x:Property Name="TimeoutForDeploymentScriptInMinutes" Type="InArgument(x:Int32)">
<x:Property.Attributes>
<RequiredArgumentAttribute />
</x:Property.Attributes>
</x:Property>
</x:Members>
<this:Process.BuildProcessVersion>11.0</this:Process.BuildProcessVersion>
<this:Process.Metadata>
<mtbw:ProcessParameterMetadataCollection>
<mtbw:ProcessParameterMetadata BrowsableWhen="Always" Category="Misc" DisplayName="Timeout For Each Deployment Script (in Minutes)" ParameterName="TimeoutForDeploymentScriptInMinutes" />
</mtbw:ProcessParameterMetadataCollection>
</this:Process.Metadata>
<sap:VirtualizedContainerService.HintSize>920,3702</sap:VirtualizedContainerService.HintSize>
<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
<Sequence DisplayName="Application Deployment Workflow" sad:XamlDebuggerXmlReader.FileName="D:\VSTLM\src\vset\LabManager\LabCustomActivities\Templates\LabDefaultTemplate.xaml" sap:VirtualizedContainerService.HintSize="880,3662" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
<Sequence.Variables>
<Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
<Variable x:TypeArguments="x:String" Name="LabEnvironmentUri" />
<Variable x:TypeArguments="x:String" Name="BuildLocation" />
<Variable x:TypeArguments="x:Int64" Name="SnapshotId" />
<Variable x:TypeArguments="x:Int32" Name="QueueBuildId" />
<Variable x:TypeArguments="mtbc:BuildStatus" Default="[Microsoft.TeamFoundation.Build.Client.BuildStatus.Succeeded]" Name="BuildStatus" />
<Variable x:TypeArguments="mtbc:IBuildDetail" Name="ChildBuildDetail" />
<Variable x:TypeArguments="mtbc:IBuildDetail" Name="SelectedBuildDetail" />
<Variable x:TypeArguments="x:String" Name="BuildNumber" />
<Variable x:TypeArguments="mtlc:LabEnvironment" Name="LabEnvironment" />
</Sequence.Variables>
<mtbwa:UpdateBuildNumber BuildNumberFormat="[BuildNumberFormat]" DisplayName="Update Build Number" sap:VirtualizedContainerService.HintSize="858,22" />
<mtbwa:GetBuildDetail DisplayName="Get Build Details" sap:VirtualizedContainerService.HintSize="858,22" Result="[BuildDetail]" />
<If Condition="[LabWorkflowParameters.BuildDetails.IsTeamSystemBuild = True AndAlso LabWorkflowParameters.BuildDetails.QueueNewBuild = True]" DisplayName="If Build is needed" sap:VirtualizedContainerService.HintSize="858,416">
<If.Then>
<Sequence DisplayName="Do Build" sap:VirtualizedContainerService.HintSize="301,308">
<sap:WorkflowViewStateService.ViewState>
<scg:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">True</x:Boolean>
</scg:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<mtlwa:RunWorkflow BuildController="{x:Null}" LabEnvironmentUri="{x:Null}" BuildDefinition="[LabWorkflowParameters.BuildDetails.BuildDefinitionName]" DisplayName="Start Build Workflow" sap:VirtualizedContainerService.HintSize="242,22" ProjectName="[BuildDetail.TeamProject]" Result="[QueueBuildId]" />
<mtlwa:WaitForWorkflow AllowPartiallySucceededBuild="True" BuildDetails="[ChildBuildDetail]" DisplayName="Wait For Build To Complete" sap:VirtualizedContainerService.HintSize="242,22" LabWorkflowType="[Microsoft.TeamFoundation.Lab.Workflow.Activities.WorkflowType.Build]" MaxConsecutiveFailuresToIgnoreDuringWaitForCompletion="[3]" MaxWaitTime="[TimeSpan.Zero]" QueueBuildId="[QueueBuildId]" RefreshInterval="[System.TimeSpan.FromMinutes(1)]" Result="[BuildStatus]" ThrowOnError="True" />
<Assign DisplayName="Set Build Location" sap:VirtualizedContainerService.HintSize="242,60">
<Assign.To>
<OutArgument x:TypeArguments="x:Uri">[LabWorkflowParameters.BuildDetails.BuildUri]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:Uri">[ChildBuildDetail.Uri]</InArgument>
</Assign.Value>
</Assign>
</Sequence>
</If.Then>
</If>
<mtlwa:WriteDeploymentInformation Url="{x:Null}" DeploymentInformationType="[Microsoft.TeamFoundation.Build.Common.DeploymentInformationTypes.Deploy]" DisplayName="Update Deployment Summary" sap:VirtualizedContainerService.HintSize="858,22" Message="[String.Format(&quot;Lab environment: {0}&quot;, LabWorkflowParameters.EnvironmentDetails.LabEnvironmentName)]" />
<mtlwa:GetBuildLocationAndBuildNumber BuildDetails="[LabWorkflowParameters.BuildDetails]" BuildNumber="[BuildNumber]" DisplayName="Get Build Location And Build Number" sap:VirtualizedContainerService.HintSize="858,22" Result="[BuildLocation]" SelectedBuild="[SelectedBuildDetail]" />
<If Condition="[LabWorkflowParameters.BuildDetails.IsTeamSystemBuild = True]" DisplayName="Compute build location needed" sap:VirtualizedContainerService.HintSize="858,208">
<If.Then>
<Assign DisplayName="Compute build path" sap:VirtualizedContainerService.HintSize="291,100">
<Assign.To>
<OutArgument x:TypeArguments="x:String">[BuildLocation]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:String">[If(LabWorkflowParameters.BuildDetails.Configuration Is Nothing, BuildLocation, If(LabWorkflowParameters.BuildDetails.Configuration.IsEmpty Or (SelectedBuildDetail.Information.GetNodesByType(Microsoft.TeamFoundation.Build.Common.InformationTypes.ConfigurationSummary, True)).Count = 1, BuildLocation, If(LabWorkflowParameters.BuildDetails.Configuration.IsPlatformEmptyOrAnyCpu, BuildLocation + "\" + LabWorkflowParameters.BuildDetails.Configuration.Configuration, BuildLocation + "\" + LabWorkflowParameters.BuildDetails.Configuration.Platform + "\" + LabWorkflowParameters.BuildDetails.Configuration.Configuration)))]</InArgument>
</Assign.Value>
</Assign>
</If.Then>
</If>
<If Condition="[LabWorkflowParameters.EnvironmentDetails.Disposition = Microsoft.TeamFoundation.Lab.Client.LabEnvironmentDisposition.Stored]" DisplayName="If user selected stored environment" sap:VirtualizedContainerService.HintSize="858,208">
<If.Then>
<Throw DisplayName="Indicate error" Exception="[New System.Exception(&quot;You have selected an environment that is stored in the library. Select an environment that is deployed on a team project host group.&quot;)]" sap:VirtualizedContainerService.HintSize="269,100" />
</If.Then>
</If>
<Assign DisplayName="Get Lab Environment Uri" sap:VirtualizedContainerService.HintSize="858,22" >
<Assign.To>
<OutArgument x:TypeArguments="x:String">[LabEnvironmentUri]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:String">[LabWorkflowParameters.EnvironmentDetails.LabEnvironmentUri.ToString()]</InArgument>
</Assign.Value>
</Assign>
<mtlwa:GetLabEnvironment DisplayName="Get Lab Environment" LabEnvironmentUri="[LabEnvironmentUri]" Result="[LabEnvironment]" />
<If Condition="[LabWorkflowParameters.EnvironmentDetails.RevertToSnapshot = True]" DisplayName=" If Restore Snapshot" sap:VirtualizedContainerService.HintSize="858,316">
<If.Then>
<Sequence DisplayName="Restore Snapshot" sap:VirtualizedContainerService.HintSize="231,208">
<mtlwa:GetLabEnvironmentSnapshotId DisplayName="Get Snapshot Details" sap:VirtualizedContainerService.HintSize="200,22" LabEnvironmentUri="[LabEnvironmentUri]" Result="[SnapshotId]" SnapshotName="[LabWorkflowParameters.EnvironmentDetails.SnapshotName]" />
<mtlwa:RestoreLabEnvironment DisplayName="Restore Lab Environment to Snapshot" sap:VirtualizedContainerService.HintSize="200,22" LabEnvironmentUri="[LabEnvironmentUri]" SnapshotId="[SnapshotId]" />
</Sequence>
</If.Then>
<If.Else>
<Sequence DisplayName="No Clean Snapshot" >
<If Condition="[Not String.Equals(Microsoft.TeamFoundation.Lab.Client.LabEnvironment.UnmanagedProvider, labEnvironment.LabProvider)]" DisplayName= "If Virtual Environment">
<If.Then>
<mtlwa:WriteDeploymentInformation Url="{x:Null}" DeploymentInformationType="[Microsoft.TeamFoundation.Build.Common.DeploymentInformationTypes.Deploy]" DisplayName="Clean snapshot not specified " sap:VirtualizedContainerService.HintSize="208,208" Message="Build definition did not specify a clean snapshot. It is a best practice to use clean snapshot when running the lab workflow." />
</If.Then>
</If>
</Sequence>
</If.Else>
</If>
<If Condition="[LabWorkflowParameters.DeploymentDetails.DeploymentNeeded = True or LabWorkflowParameters.TestParameters.RunTest = True]" DisplayName="If deployment or test needed" sap:VirtualizedContainerService.HintSize="858,1214">
<If.Then>
<mtlwa:WaitForEnvironmentReady DisplayName="Wait For Environment To Be Ready" sap:VirtualizedContainerService.HintSize="711,22" LabEnvironmentUri="[LabEnvironmentUri]" MaxWaitTime="[System.TimeSpan.FromMinutes(10)]" />
</If.Then>
</If>
<If Condition="[LabWorkflowParameters.DeploymentDetails.DeploymentNeeded = True]" DisplayName="If deployment needed" sap:VirtualizedContainerService.HintSize="858,1214">
<If.Then>
<Sequence DisplayName="Do deployment" sap:VirtualizedContainerService.HintSize="733,1106">
<mtlwa:ReserveEnvironmentForDeployment DisplayName="Reserve Environment For Deployment" sap:VirtualizedContainerService.HintSize="711,22" LabEnvironmentUri="[LabEnvironmentUri]" />
<TryCatch DisplayName="Deploy Build on Environment">
<TryCatch.Try>
<Sequence DisplayName="Deploying Build">
<ForEach x:TypeArguments="x:String" DisplayName="Run Deployment scripts" sap:VirtualizedContainerService.HintSize="711,254" Values="[LabWorkflowParameters.DeploymentDetails.Scripts]">
<ActivityAction x:TypeArguments="x:String">
<ActivityAction.Argument>
<DelegateInArgument x:TypeArguments="x:String" Name="deploymentConfigurationPair" />
</ActivityAction.Argument>
<mtlwa:RunDeploymentTask BuildLocation="[BuildLocation]" DeploymentScriptDetails="[deploymentConfigurationPair]" DisplayName="Run Deployment Task" sap:VirtualizedContainerService.HintSize="200,22" LabEnvironmentUri="[LabEnvironmentUri]" MaxWaitTime="[TimeSpan.FromMinutes(TimeoutForDeploymentScriptInMinutes)]" ThrowOnError="True" UseRoleForDeployment="[LabWorkflowParameters.DeploymentDetails.UseRoleForDeployment]" />
</ActivityAction>
</ForEach>
</Sequence>
</TryCatch.Try>
<TryCatch.Finally>
<mtlwa:ReleaseEnvironmentFromDeployment DisplayName="Release Environment From Deployment" sap:VirtualizedContainerService.HintSize="711,22" LabEnvironmentUri="[LabEnvironmentUri]" />
</TryCatch.Finally>
</TryCatch>
<mtlwa:WriteDeploymentInformation DeploymentInformationType="[Microsoft.TeamFoundation.Build.Common.DeploymentInformationTypes.Deploy]" DisplayName="Application Deployment Succeeded" sap:VirtualizedContainerService.HintSize="711,22" Message="[String.Format(&quot;The application was deployed successfully from the following build location:&quot;)]" Url="[BuildLocation]" />
<If Condition="[LabWorkflowParameters.DeploymentDetails.TakePostDeploymentSnapshot = True]" DisplayName="Post Deployment Snapshot" sap:VirtualizedContainerService.HintSize="711,626">
<If.Then>
<Sequence DisplayName="Take Post deployment Snapshot " sap:VirtualizedContainerService.HintSize="486,518">
<Sequence.Variables>
<Variable x:TypeArguments="x:Int64" Name="PostDeploymentSnapshotChainId" />
<Variable x:TypeArguments="x:String" Default="[String.Format(&quot;{0}_{1}&quot;, BuildDetail.BuildDefinition.Name, BuildDetail.BuildNumber)]" Name="PostDeploymentSnapshotName" />
</Sequence.Variables>
<If Condition="[String.IsNullOrEmpty(LabWorkflowParameters.DeploymentDetails.PostDeploymentSnapshotName) = False]" DisplayName="Check snapshot name" sap:VirtualizedContainerService.HintSize="464,208">
<If.Then>
<Assign sap:VirtualizedContainerService.HintSize="291,100">
<Assign.To>
<OutArgument x:TypeArguments="x:String">[PostDeploymentSnapshotName]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:String">[If(LabWorkflowParameters.BuildDetails.IsTeamSystemBuild = True,String.Format("{0}_{1}_{2}", LabWorkflowParameters.DeploymentDetails.PostDeploymentSnapshotName, BuildNumber,BuildDetail.BuildNumber),String.Format("{0}_{1}", LabWorkflowParameters.DeploymentDetails.PostDeploymentSnapshotName, BuildDetail.BuildNumber))]</InArgument>
</Assign.Value>
</Assign>
</If.Then>
</If>
<mtlwa:SnapshotLabEnvironment DisplayName="Taking Post Deployment snapshot" sap:VirtualizedContainerService.HintSize="464,22" LabEnvironmentUri="[LabEnvironmentUri]" SnapshotChainId="[PostDeploymentSnapshotChainId]" SnapshotName="[PostDeploymentSnapshotName]" />
<mtlwa:WriteDeploymentInformation Url="{x:Null}" DeploymentInformationType="[Microsoft.TeamFoundation.Build.Common.DeploymentInformationTypes.Deploy]" DisplayName="Taking Snapshot succeeded" sap:VirtualizedContainerService.HintSize="464,22" Message="[String.Format(&quot;The following snapshot was taken after the deployment was finished: {0}&quot;, PostDeploymentSnapshotName)]" />
<mtlwa:WriteDeploymentInformation DeploymentInformationType="[Microsoft.TeamFoundation.Build.Common.DeploymentInformationTypes.ConnectToSnapshot]" DisplayName="Added connection link to the Snapshot" sap:VirtualizedContainerService.HintSize="464,22" Message="[PostDeploymentSnapshotName]" Url="[PostDeploymentSnapshotChainId.ToString()]" />
</Sequence>
</If.Then>
<If.Else>
<Sequence DisplayName = "No Post Deployment Snapshot">
<If Condition="[Not String.Equals(Microsoft.TeamFoundation.Lab.Client.LabEnvironment.UnmanagedProvider, labEnvironment.LabProvider)]" DisplayName= "If Virtual Environment">
<If.Then>
<mtlwa:WriteDeploymentInformation Url="{x:Null}" DeploymentInformationType="[Microsoft.TeamFoundation.Build.Common.DeploymentInformationTypes.Deploy]" DisplayName="Post deployment snapshot not specified" sap:VirtualizedContainerService.HintSize="200,518" Message="Build definition did not specify a post deployment snapshot. It is a best practice to take post deployment snapshot when running the lab workflow." />
</If.Then>
</If>
</Sequence>
</If.Else>
</If>
</Sequence>
</If.Then>
</If>
<If Condition="[LabWorkflowParameters.TestParameters.RunTest = True]" DisplayName="Run Tests on Environment" sap:VirtualizedContainerService.HintSize="858,604">
<If.Then>
<Sequence DisplayName="Run Tests" sap:VirtualizedContainerService.HintSize="656,498">
<Sequence.Variables>
<Variable x:TypeArguments="mtltc:TestingCapabilityInformation" Name="TestCapabilityInfo" />
<Variable x:TypeArguments="x:String" Name="variable1" />
<Variable x:TypeArguments="mtlwa:TestRunStatistics" Default="[New Microsoft.TeamFoundation.Lab.Workflow.Activities.TestRunStatistics()]" Name="TestResults" />
</Sequence.Variables>
<mtlwa:ExecuteRemoteTestRun2 MaxWaitTime="{x:Null}" TestEnvironment="{x:Null}" BuildNumber="[BuildNumber]" BuildDefinitionName="[LabWorkflowParameters.BuildDetails.BuildDefinitionName]" DisplayName="Running Tests" sap:VirtualizedContainerService.HintSize="634,22" LabEnvironmentUri="[LabEnvironmentUri]" MaxConsecutiveFailuresToIgnoreDuringWaitForCompletion="[3]" RefreshInterval="[System.TimeSpan.FromMinutes(1)]" Result="[TestResults]" TestDirectory="[BuildLocation]" TestParameters="[LabWorkflowParameters.TestParameters]" Title="[String.Format(&quot;{0}&quot;, BuildDetail.BuildNumber)]" />
<If Condition="[TestResults.PassedTests &lt;&gt; TestResults.TotalTests Or TestResults.TestRunStatus &lt;&gt; TestManagement.Client.TestRunState.Completed]" DisplayName="If all tests have not passed" sap:VirtualizedContainerService.HintSize="634,312">
<If.Then>
<If Condition="[(LabWorkflowParameters.BuildDetails.IsTeamSystemBuild = True AndAlso LabWorkflowParameters.BuildDetails.QueueNewBuild = True) Or (LabWorkflowParameters.DeploymentDetails.DeploymentNeeded = True)]" DisplayName="Set build status" sap:VirtualizedContainerService.HintSize="509,206">
<If.Then>
<Assign DisplayName="Partially succeeded" sap:VirtualizedContainerService.HintSize="242,100">
<Assign.To>
<OutArgument x:TypeArguments="mtbc:BuildStatus">[BuildStatus]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="mtbc:BuildStatus">[Microsoft.TeamFoundation.Build.Client.BuildStatus.PartiallySucceeded]</InArgument>
</Assign.Value>
</Assign>
</If.Then>
<If.Else>
<Assign DisplayName="Failed" sap:VirtualizedContainerService.HintSize="242,100">
<Assign.To>
<OutArgument x:TypeArguments="mtbc:BuildStatus">[BuildStatus]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="mtbc:BuildStatus">[Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed]</InArgument>
</Assign.Value>
</Assign>
</If.Else>
</If>
</If.Then>
</If>
</Sequence>
</If.Then>
</If>
<mtbwa:SetBuildProperties DisplayName="Set build status" sap:VirtualizedContainerService.HintSize="858,22" PropertiesToSet="Status" Status="[BuildStatus]" />
</Sequence>
</Activity>

View file

@ -0,0 +1,76 @@
<Activity mc:Ignorable="sad" x:Class="TfsBuild.Process" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mtbc="clr-namespace:Microsoft.TeamFoundation.Build.Client;assembly=Microsoft.TeamFoundation.Build.Client" xmlns:mtbw="clr-namespace:Microsoft.TeamFoundation.Build.Workflow;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwa="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Activities;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtbwt="clr-namespace:Microsoft.TeamFoundation.Build.Workflow.Tracking;assembly=Microsoft.TeamFoundation.Build.Workflow" xmlns:mtvc="clr-namespace:Microsoft.TeamFoundation.VersionControl.Client;assembly=Microsoft.TeamFoundation.VersionControl.Client" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:sad="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:sad1="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:this="clr-namespace:TfsBuild;" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="ConfigurationFolderPath" Type="InArgument(x:String)" />
<x:Property Name="AgentSettings" Type="InArgument(mtbwa:AgentSettings)" />
<x:Property Name="MSBuildArguments" Type="InArgument(x:String)" />
<x:Property Name="MSBuildPlatform" Type="InArgument(mtbwa:ToolPlatform)" />
<x:Property Name="DoNotDownloadBuildType" Type="InArgument(x:Boolean)" />
<x:Property Name="LogFilePerProject" Type="InArgument(x:Boolean)" />
<x:Property Name="SourcesSubdirectory" Type="InArgument(x:String)" />
<x:Property Name="BinariesSubdirectory" Type="InArgument(x:String)" />
<x:Property Name="TestResultsSubdirectory" Type="InArgument(x:String)" />
<x:Property Name="RecursionType" Type="InArgument(mtvc:RecursionType)" />
<x:Property Name="Verbosity" Type="InArgument(mtbw:BuildVerbosity)" />
<x:Property Name="Metadata" Type="mtbw:ProcessParameterMetadataCollection" />
<x:Property Name="SupportedReasons" Type="mtbc:BuildReason" />
</x:Members>
<this:Process.ConfigurationFolderPath>
<InArgument x:TypeArguments="x:String" />
</this:Process.ConfigurationFolderPath>
<this:Process.AgentSettings>[New Microsoft.TeamFoundation.Build.Workflow.Activities.AgentSettings() With {.MaxWaitTime = New System.TimeSpan(4, 0, 0), .MaxExecutionTime = New System.TimeSpan(0, 0, 0), .TagComparison = Microsoft.TeamFoundation.Build.Workflow.Activities.TagComparison.MatchExactly }]</this:Process.AgentSettings>
<this:Process.MSBuildArguments>
<InArgument x:TypeArguments="x:String" />
</this:Process.MSBuildArguments>
<this:Process.MSBuildPlatform>[Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto]</this:Process.MSBuildPlatform>
<this:Process.DoNotDownloadBuildType>[False]</this:Process.DoNotDownloadBuildType>
<this:Process.LogFilePerProject>[False]</this:Process.LogFilePerProject>
<this:Process.SourcesSubdirectory>
<InArgument x:TypeArguments="x:String" />
</this:Process.SourcesSubdirectory>
<this:Process.BinariesSubdirectory>
<InArgument x:TypeArguments="x:String" />
</this:Process.BinariesSubdirectory>
<this:Process.TestResultsSubdirectory>
<InArgument x:TypeArguments="x:String" />
</this:Process.TestResultsSubdirectory>
<this:Process.RecursionType>[Microsoft.TeamFoundation.VersionControl.Client.RecursionType.OneLevel]</this:Process.RecursionType>
<this:Process.Verbosity>[Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal]</this:Process.Verbosity>
<this:Process.Metadata>
<mtbw:ProcessParameterMetadataCollection />
</this:Process.Metadata>
<this:Process.SupportedReasons>All</this:Process.SupportedReasons>
<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
<Sequence mtbwt:BuildTrackingParticipant.Importance="None">
<Sequence.Variables>
<Variable x:TypeArguments="mtbc:IBuildDetail" Name="BuildDetail" />
</Sequence.Variables>
<mtbwa:GetBuildDetail DisplayName="Get the Build" Result="[BuildDetail]" />
<mtbwa:InvokeForReason DisplayName="Update Build Number for Triggered Builds" Reason="Triggered">
<mtbwa:UpdateBuildNumber BuildNumberFormat="[&quot;$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)&quot;]" DisplayName="Update Build Number" />
</mtbwa:InvokeForReason>
<mtbwa:AgentScope DisplayName="Run On Agent" MaxExecutionTime="[AgentSettings.MaxExecutionTime]" MaxWaitTime="[AgentSettings.MaxWaitTime]" ReservationSpec="[AgentSettings.GetAgentReservationSpec()]">
<mtbwa:AgentScope.Variables>
<Variable x:TypeArguments="x:String" Name="buildDirectory" />
</mtbwa:AgentScope.Variables>
<mtbwa:GetBuildDirectory DisplayName="Get the Build Directory" Result="[buildDirectory]" />
<If Condition="[Not String.IsNullOrEmpty(ConfigurationFolderPath)]" DisplayName="If Not String.IsNullOrEmpty(ConfigurationFolderPath)">
<If.Then>
<mtbwa:TfsBuild BinariesSubdirectory="[BinariesSubdirectory]" BuildDirectory="[buildDirectory]" CommandLineArguments="[MSBuildArguments]" ConfigurationFolderPath="[ConfigurationFolderPath]" DisplayName="Run TfsBuild for Configuration Folder" DoNotDownloadBuildType="[DoNotDownloadBuildType]" LogFilePerProject="[LogFilePerProject]" RecursionType="[RecursionType]" SourcesSubdirectory="[SourcesSubdirectory]" TestResultsSubdirectory="[TestResultsSubdirectory]" ToolPlatform="[MSBuildPlatform]" Verbosity="[Verbosity]" />
</If.Then>
</If>
<If Condition="[BuildDetail.CompilationStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If CompilationStatus = Unknown">
<If.Then>
<mtbwa:SetBuildProperties CompilationStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" DisplayName="Set CompilationStatus to Succeeded" PropertiesToSet="CompilationStatus" />
</If.Then>
</If>
<If Condition="[BuildDetail.TestStatus = Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Unknown]" DisplayName="If TestStatus = Unknown">
<If.Then>
<mtbwa:SetBuildProperties DisplayName="Set TestStatus to Succeeded" PropertiesToSet="TestStatus" TestStatus="[Microsoft.TeamFoundation.Build.Client.BuildPhaseStatus.Succeeded]" />
</If.Then>
</If>
</mtbwa:AgentScope>
<mtbwa:InvokeForReason Reason="CheckInShelveset">
<mtbwa:CheckInGatedChanges DisplayName="Check In Gated Changes" />
</mtbwa:InvokeForReason>
</Sequence>
</Activity>

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{04B850F0-5A39-4157-A227-A574064110D2}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CommonTypes</RootNamespace>
<AssemblyName>CommonTypes</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="IService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Rectangle.cs" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CommonTypes
{
public interface IService
{
/// <summary>
/// An example with two integer arguments
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
int Sum(int a, int b);
/// <summary>
/// An example with a variable number of arguments
/// </summary>
/// <param name="values"></param>
/// <returns></returns>
int Sum(params int[] values);
/// <summary>
/// An example with a return value
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
string ToUpper(string str);
/// <summary>
/// An example with a ref argument
/// </summary>
/// <param name="str"></param>
void MakeStringUpperCase(ref string str);
/// <summary>
/// An example with an out argument
/// </summary>
/// <param name="str"></param>
/// <param name="lowerCaseString"></param>
void MakeStringLowerCase(string str, out string lowerCaseString);
/// <summary>
/// An example which alters a user defined type. In the current version you
/// have to pass the value by reference in order to alter the object.
/// </summary>
/// <param name="rectangle"></param>
void CalculateArea(ref Rectangle rectangle);
void Square(long a, out long b);
}
}

View file

@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("CommonTypes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CommonTypes")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("c564b05d-1138-4417-8410-58622ceb142e")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,41 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace CommonTypes
{
/// <summary>
/// A naive user defined type which we will use in the remoting example.
/// Remember that all types used must be serializable.
/// </summary>
[Serializable]
public class Rectangle
{
private int _width;
private int _height;
private int _area;
public Rectangle(int height, int width)
{
_height = height;
_width = width;
_area = -1; //let the service calculate this
}
public int Area
{
get { return _area; }
set { _area = value; }
}
public int Height
{
get { return _height; }
}
public int Width
{
get { return _width; }
}
}
}

View file

@ -0,0 +1,50 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemotingLiteExampleClient", "RemotingLiteExampleClient\RemotingLiteExampleClient.csproj", "{275568A0-7E5E-4151-8960-E54665FF5DF7}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemotingLiteExampleServer", "RemotingLiteExampleServer\RemotingLiteExampleServer.csproj", "{EFBE44D0-1F61-42CF-9489-EED99AA1887F}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CommonTypes", "CommonTypes\CommonTypes.csproj", "{04B850F0-5A39-4157-A227-A574064110D2}"
ProjectSection(WebsiteProperties) = preProject
Debug.AspNetCompiler.Debug = "True"
Release.AspNetCompiler.Debug = "False"
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemotingLite", "..\src\RemotingLite.csproj", "{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{275568A0-7E5E-4151-8960-E54665FF5DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{275568A0-7E5E-4151-8960-E54665FF5DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{275568A0-7E5E-4151-8960-E54665FF5DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{275568A0-7E5E-4151-8960-E54665FF5DF7}.Release|Any CPU.Build.0 = Release|Any CPU
{EFBE44D0-1F61-42CF-9489-EED99AA1887F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EFBE44D0-1F61-42CF-9489-EED99AA1887F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EFBE44D0-1F61-42CF-9489-EED99AA1887F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EFBE44D0-1F61-42CF-9489-EED99AA1887F}.Release|Any CPU.Build.0 = Release|Any CPU
{04B850F0-5A39-4157-A227-A574064110D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{04B850F0-5A39-4157-A227-A574064110D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{04B850F0-5A39-4157-A227-A574064110D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{04B850F0-5A39-4157-A227-A574064110D2}.Release|Any CPU.Build.0 = Release|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Text;
using CommonTypes;
using RemotingLite;
using System.Net;
namespace RemotingLiteExampleClient
{
/// <summary>
/// This class is an example of how to subclass ClientBase in order to provide more
/// control over the calls.
/// Notice that any class inheriting from ClientBase has a Proxy-property, which
/// is a proxy of the interface specified. This proxy is generated with RemotingLite.ProxyFactory
/// and provides the contact to the host.
///
/// Note the constructor!
/// </summary>
public class ClientProxyImpl : ClientBase<IService>, IService
{
/// <summary>
/// The class inheriting from ClientBase must define a constructor which takes
/// an end point to the host. You have to call the base constructor.
/// </summary>
/// <param name="endpoint"></param>
public ClientProxyImpl(IPEndPoint endpoint)
: base(endpoint)
{
}
#region IService Members
public int Sum(int a, int b)
{
return Proxy.Sum(a, b);
}
public int Sum(params int[] values)
{
return Proxy.Sum(values);
}
public string ToUpper(string str)
{
return Proxy.ToUpper(str);
}
public void MakeStringUpperCase(ref string str)
{
Proxy.MakeStringUpperCase(ref str);
}
public void MakeStringLowerCase(string str, out string lowerCaseString)
{
Proxy.MakeStringLowerCase(str, out lowerCaseString);
}
public void CalculateArea(ref Rectangle rectangle)
{
Proxy.CalculateArea(ref rectangle);
}
public void Square(long a, out long b)
{
Proxy.Square(a, out b);
}
#endregion
}
}

View file

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using CommonTypes;
namespace RemotingLiteExampleClient
{
/// <summary>
/// This class shows an example of how to use our own client proxy implementation
/// that inherits from ClientBase.
/// </summary>
public class ExampleUsingClientProxyImpl
{
public void Start(int port)
{
// This is an example that connects to the local host. See MSDN documentation.
// This will work if you run both client and host on the same machine.
#if true
IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
IPAddress address = null;
foreach (var a in addressList)
if (a.AddressFamily == AddressFamily.InterNetwork)
{
address = a;
break;
}
IPEndPoint endpoint = new IPEndPoint(address, port);
#else
IPEndPoint endpoint = new IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], 8000);
#endif
// When using our own implementation we can use the "using" construct since ClientBase (and
// thus our implementation) implements IDisposable.
using (ClientProxyImpl client = new ClientProxyImpl(endpoint))
{
//make a few calls to the host
Console.WriteLine(client.Sum(2, 3));
Console.WriteLine(client.Sum(2, 3, 4, 5, 6, 7, 8, 9));
Console.WriteLine(client.ToUpper("this string used to be lower case"));
string str = "this was a lower case string";
client.MakeStringUpperCase(ref str);
Console.WriteLine(str);
string lowerCaseString;
client.MakeStringLowerCase("THIS WAS AN UPPER CASE STRING", out lowerCaseString);
Console.WriteLine(lowerCaseString);
Rectangle rect = new Rectangle(30, 40);
Console.WriteLine(String.Format("Area before call : {0}", rect.Area));
client.CalculateArea(ref rect);
Console.WriteLine(String.Format("Area after call : {0}", rect.Area));
long b;
client.Square(123, out b);
Console.WriteLine(string.Format("123 squared is {0}", b));
}
}
}
}

View file

@ -0,0 +1,68 @@
using System;
using System.Collections.Generic;
using System.Text;
using CommonTypes;
using RemotingLite;
using System.Net.Sockets;
using System.Net;
namespace RemotingLiteExampleClient
{
/// <summary>
/// This is an example of how to use ProxyFactory directly.
/// </summary>
public class ExampleUsingProxyFactory
{
public void Start(int port)
{
// This is an example that connects to the local host. See MSDN documentation.
// This will work if you run both client and host on the same machine.
#if true
IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
IPAddress address = null;
foreach (var a in addressList)
if (a.AddressFamily == AddressFamily.InterNetwork)
{
address = a;
break;
}
IPEndPoint endpoint = new IPEndPoint(address, port);
#else
IPEndPoint endpoint = new IPEndPoint(Dns.GetHostEntry(Dns.GetHostName()).AddressList[0], 8000);
#endif
// When using the proxy factory we do not need to write any client side code for the
// proxy. This might be usefull if you:
// 1) Want more control of when the connection is closed. This is done when the object is
// disposed.
// 2) Are lazy :-)
//create the proxy
IService client = ProxyFactory.CreateProxy<IService>(endpoint);
//make a few calls to the host
Console.WriteLine(client.Sum(2, 3));
Console.WriteLine(client.Sum(2, 3, 4, 5, 6, 7, 8, 9));
Console.WriteLine(client.ToUpper("this string used to be lower case"));
string str = "this was a lower case string";
client.MakeStringUpperCase(ref str);
Console.WriteLine(str);
string lowerCaseString;
client.MakeStringLowerCase("THIS WAS AN UPPER CASE STRING", out lowerCaseString);
Console.WriteLine(lowerCaseString);
Rectangle rect = new Rectangle(30, 40);
Console.WriteLine(String.Format("Area before call : {0}", rect.Area));
client.CalculateArea(ref rect);
Console.WriteLine(String.Format("Area after call : {0}", rect.Area));
long b;
client.Square(123, out b);
Console.WriteLine(string.Format("123 squared is {0}", b));
// You can either dispose (and thus close the connection) the object yourself, or wait
// for the garbage collector to do it for you when going out of scope of this method.
// Here we dispose it explicitly,
((IDisposable)client).Dispose();
}
}
}

View file

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace RemotingLiteExampleClient
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Using our own implementation that inherits from ClientBase<>\n");
ExampleUsingClientProxyImpl example1 = new ExampleUsingClientProxyImpl();
example1.Start(8000);
Console.WriteLine("\nUsing ProxyFactory to create a proxy directly.\n");
ExampleUsingProxyFactory example2 = new ExampleUsingProxyFactory();
example2.Start(8000);
Console.ReadLine();
}
}
}

View file

@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("RemotingLiteExampleClient")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RemotingLiteExampleClient")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("400c12e2-5f51-4aec-b3f3-6a636d9d66c3")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{275568A0-7E5E-4151-8960-E54665FF5DF7}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RemotingLiteExampleClient</RootNamespace>
<AssemblyName>RemotingLiteExampleClient</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ClientProxyImpl.cs" />
<Compile Include="ExampleUsingClientProxyImpl.cs" />
<Compile Include="ExampleUsingProxyFactory.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\RemotingLite.csproj">
<Project>{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}</Project>
<Name>RemotingLite</Name>
</ProjectReference>
<ProjectReference Include="..\CommonTypes\CommonTypes.csproj">
<Project>{04B850F0-5A39-4157-A227-A574064110D2}</Project>
<Name>CommonTypes</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

View file

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Text;
using RemotingLite;
namespace RemotingLiteExampleServer
{
class Program
{
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(ServiceImpl), 8000))
{
host.UseThreadPool = true;
host.Open();
Console.WriteLine("Host is running. Press <ENTER> to terminate.");
Console.WriteLine(String.Format("Address is {0}", host.EndPoint.Address));
Console.WriteLine("Press <ENTER> to terminate.");
Console.ReadLine();
}
}
}
}

View file

@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("RemotingLiteExampleServer")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RemotingLiteExampleServer")]
[assembly: AssemblyCopyright("Copyright © 2008")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("fdee2604-d0ea-4f5d-a9c6-34ea06545b29")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View file

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{EFBE44D0-1F61-42CF-9489-EED99AA1887F}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RemotingLiteExampleServer</RootNamespace>
<AssemblyName>RemotingLiteExampleServer</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceImpl.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\RemotingLite.csproj">
<Project>{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}</Project>
<Name>RemotingLite</Name>
</ProjectReference>
<ProjectReference Include="..\CommonTypes\CommonTypes.csproj">
<Project>{04B850F0-5A39-4157-A227-A574064110D2}</Project>
<Name>CommonTypes</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
using System.Text;
using CommonTypes;
namespace RemotingLiteExampleServer
{
public class ServiceImpl : IService
{
#region IService Members
public int Sum(int a, int b)
{
return a + b;
}
public int Sum(params int[] values)
{
int sum = 0;
foreach (int value in values)
sum += value;
return sum;
}
public string ToUpper(string str)
{
return str.ToUpper();
}
public void MakeStringUpperCase(ref string str)
{
str = str.ToUpper();
}
public void MakeStringLowerCase(string str, out string lowerCaseString)
{
lowerCaseString = str.ToLower();
}
public void CalculateArea(ref Rectangle rectangle)
{
rectangle.Area = rectangle.Width * rectangle.Height;
}
public void Square(long a, out long b)
{
b = a * a;
}
#endregion
}
}

View file

@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

View file

@ -0,0 +1,26 @@
RemotingLite licence
Copyright (c) 2008, Frank Thomsen - http://sector0.dk
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of 'RemotingLite' nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Frank Thomsen ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Frank Thomsen BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,161 @@
/*************************************************************************************************
* RemotingLite
* ------
* A light framework for making remote method invocations using TCP/IP. It is based loosely on
* Windows Communication Foundation, and is meant to provide programmers with the same API
* regardless of whether they write software for the Microsoft .NET platform or the Mono .NET
* platform.
* Consult the documentation and example applications for information about how to use this API.
*
* Author : Frank Thomsen
* http : http://sector0.dk
* Concact : http://sector0.dk/?q=contact
* Information : http://sector0.dk/?q=node/27
* Licence : Free. If you use this, please let me know.
*
* Please feel free to contact me with ideas, bugs or improvements.
*************************************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.Serialization;
namespace RemotingLite
{
public class Channel : IDisposable
{
private TcpClient _client;
private NetworkStream _stream;
private BinaryReader _binReader;
private BinaryWriter _binWriter;
private BinaryFormatter _formatter;
private ParameterTransferHelper _parameterTransferHelper = new ParameterTransferHelper();
private List<MethodSyncInfo> _syncInfos;
/// <summary>
/// Creates a connection to the concrete object handling method calls on the server side
/// </summary>
/// <param name="endpoint"></param>
public Channel(IPEndPoint endpoint)
{
_client = new TcpClient(AddressFamily.InterNetwork);
_client.Connect(endpoint);
_client.NoDelay = true;
_stream = _client.GetStream();
_binReader = new BinaryReader(_stream);
_binWriter = new BinaryWriter(_stream);
_formatter = new BinaryFormatter();
SyncInterface();
}
/// <summary>
/// This method asks the server for a list of identifiers paired with method
/// names and -parameter types. This is used when invoking methods server side.
/// </summary>
private void SyncInterface()
{
//write the message type
_binWriter.Write((int)MessageType.SyncInterface);
//read sync data
var ms = new MemoryStream(_binReader.ReadBytes(_binReader.ReadInt32()));
_syncInfos = (List<MethodSyncInfo>)_formatter.Deserialize(ms);
}
/// <summary>
/// Closes the connection to the server
/// </summary>
public void Close()
{
Dispose();
}
/// <summary>
/// Invokes the method with the specified parameters.
/// </summary>
/// <param name="methodName">The name of the method</param>
/// <param name="parameters">Parameters for the method call</param>
/// <returns>An array of objects containing the return value (index 0) and the parameters used to call
/// the method, including any marked as "ref" or "out"</returns>
protected object[] InvokeMethod(params object[] parameters)
{
//write the message type
_binWriter.Write((int)MessageType.MethodInvocation);
//find the mathing server side method ident
var callingMethod = (new StackFrame(1)).GetMethod();
var methodName = callingMethod.Name;
var methodParams = callingMethod.GetParameters();
var ident = -1;
foreach (var si in _syncInfos)
{
//first of all the method names must match
if (si.MethodName == methodName)
{
//second of all the parameter types and -count must match
if (methodParams.Length == si.ParameterTypes.Length)
{
var matchingParameterTypes = true;
for (int i = 0; i < methodParams.Length; i++)
if (!methodParams[i].ParameterType.FullName.Equals(si.ParameterTypes[i].FullName))
{
matchingParameterTypes = false;
break;
}
if (matchingParameterTypes)
{
ident = si.MethodIdent;
break;
}
}
}
}
if (ident < 0)
throw new Exception(string.Format("Cannot match method '{0}' to its server side equivalent", callingMethod.Name));
//write the method ident to the server
_binWriter.Write(ident);
//send the parameters
_parameterTransferHelper.SendParameters(_binWriter, parameters);
_binWriter.Flush();
_stream.Flush();
// Read the result of the invocation.
MessageType messageType = (MessageType)_binReader.ReadInt32();
if (messageType == MessageType.UnknownMethod)
throw new Exception("Unknown method.");
object[] outParams = _parameterTransferHelper.ReceiveParameters(_binReader);
if (messageType == MessageType.ThrowException)
throw (Exception)outParams[0];
return outParams;
}
#region IDisposable Members
public void Dispose()
{
_binWriter.Write((int)MessageType.TerminateConnection);
_binWriter.Flush();
_binWriter.Close();
_binReader.Close();
_stream.Flush();
_stream.Close();
_client.Close();
}
#endregion
}
}

View file

@ -0,0 +1,46 @@
/*************************************************************************************************
* RemotingLite
* ------
* A light framework for making remote method invocations using TCP/IP. It is based loosely on
* Windows Communication Foundation, and is meant to provide programmers with the same API
* regardless of whether they write software for the Microsoft .NET platform or the Mono .NET
* platform.
* Consult the documentation and example applications for information about how to use this API.
*
* Author : Frank Thomsen
* http : http://sector0.dk
* Concact : http://sector0.dk/?q=contact
* Information : http://sector0.dk/?q=node/27
* Licence : Free. If you use this, please let me know.
*
* Please feel free to contact me with ideas, bugs or improvements.
*************************************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
namespace RemotingLite
{
public abstract class ClientBase<TInterface> : IDisposable where TInterface : class
{
private TInterface _proxy;
public TInterface Proxy { get { return _proxy; } }
public ClientBase(IPEndPoint endpoint)
{
_proxy = ProxyFactory.CreateProxy<TInterface>(endpoint);
}
#region IDisposable Members
public void Dispose()
{
(_proxy as Channel).Dispose();
}
#endregion
}
}

View file

@ -0,0 +1,26 @@
RemotingLite licence
Copyright (c) 2008, Frank Thomsen - http://sector0.dk
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of 'RemotingLite' nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Frank Thomsen ``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Frank Thomsen BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,34 @@
/*************************************************************************************************
* RemotingLite
* ------
* A light framework for making remote method invocations using TCP/IP. It is based loosely on
* Windows Communication Foundation, and is meant to provide programmers with the same API
* regardless of whether they write software for the Microsoft .NET platform or the Mono .NET
* platform.
* Consult the documentation and example applications for information about how to use this API.
*
* Author : Frank Thomsen
* http : http://sector0.dk
* Concact : http://sector0.dk/?q=contact
* Information : http://sector0.dk/?q=node/27
* Licence : Free. If you use this, please let me know.
*
* Please feel free to contact me with ideas, bugs or improvements.
*************************************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
namespace RemotingLite
{
internal enum MessageType
{
TerminateConnection = 0,
MethodInvocation = 1,
ReturnValues = 2,
UnknownMethod = 3,
ThrowException = 4,
SyncInterface = 5
};
}

View file

@ -0,0 +1,241 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
namespace RemotingLite
{
internal sealed class ParameterTypes
{
internal const byte Unknown = 0x00;
internal const byte Bool = 0x01;
internal const byte Byte = 0x02;
internal const byte SByte = 0x03;
internal const byte Char = 0x04;
internal const byte Decimal = 0x05;
internal const byte Double = 0x06;
internal const byte Float = 0x07;
internal const byte Int = 0x08;
internal const byte UInt = 0x09;
internal const byte Long = 0x0A;
internal const byte ULong = 0x0B;
internal const byte Short = 0x0C;
internal const byte UShort = 0x0D;
internal const byte String = 0x0E;
internal const byte ByteArray = 0x0F;
internal const byte CharArray = 0x10;
internal const byte Null = 0x11;
internal const byte Type = 0x12;
}
internal sealed class ParameterTransferHelper
{
private Dictionary<Type, byte> _parameterTypes;
internal ParameterTransferHelper()
{
_parameterTypes = new Dictionary<Type, byte>();
_parameterTypes.Add(typeof(bool), ParameterTypes.Bool);
_parameterTypes.Add(typeof(byte), ParameterTypes.Byte);
_parameterTypes.Add(typeof(sbyte), ParameterTypes.SByte);
_parameterTypes.Add(typeof(char), ParameterTypes.Char);
_parameterTypes.Add(typeof(decimal), ParameterTypes.Decimal);
_parameterTypes.Add(typeof(double), ParameterTypes.Double);
_parameterTypes.Add(typeof(float), ParameterTypes.Float);
_parameterTypes.Add(typeof(int), ParameterTypes.Int);
_parameterTypes.Add(typeof(uint), ParameterTypes.UInt);
_parameterTypes.Add(typeof(long), ParameterTypes.Long);
_parameterTypes.Add(typeof(ulong), ParameterTypes.ULong);
_parameterTypes.Add(typeof(short), ParameterTypes.Short);
_parameterTypes.Add(typeof(ushort), ParameterTypes.UShort);
_parameterTypes.Add(typeof(string), ParameterTypes.String);
_parameterTypes.Add(typeof(byte[]), ParameterTypes.ByteArray);
_parameterTypes.Add(typeof(char[]), ParameterTypes.CharArray);
_parameterTypes.Add(typeof(Type), ParameterTypes.Type);
}
internal void SendParameters(BinaryWriter writer, params object[] parameters)
{
MemoryStream ms;
BinaryFormatter formatter = new BinaryFormatter();
//write how many parameters are coming
writer.Write(parameters.Length);
//write data for each parameter
foreach (object parameter in parameters)
{
if (parameter != null)
{
Type type = parameter.GetType();
byte typeByte = GetParameterType(type);
//write the type byte
writer.Write(typeByte);
//write the parameter
switch (typeByte)
{
case ParameterTypes.Bool:
writer.Write((bool)parameter);
break;
case ParameterTypes.Byte:
writer.Write((byte)parameter);
break;
case ParameterTypes.ByteArray:
byte[] byteArray = (byte[])parameter;
writer.Write(byteArray.Length);
writer.Write(byteArray);
break;
case ParameterTypes.Char:
writer.Write((char)parameter);
break;
case ParameterTypes.CharArray:
char[] charArray = (char[])parameter;
writer.Write(charArray.Length);
writer.Write(charArray);
break;
case ParameterTypes.Decimal:
writer.Write((decimal)parameter);
break;
case ParameterTypes.Double:
writer.Write((double)parameter);
break;
case ParameterTypes.Float:
writer.Write((float)parameter);
break;
case ParameterTypes.Int:
writer.Write((int)parameter);
break;
case ParameterTypes.Long:
writer.Write((long)parameter);
break;
case ParameterTypes.SByte:
writer.Write((sbyte)parameter);
break;
case ParameterTypes.Short:
writer.Write((short)parameter);
break;
case ParameterTypes.String:
writer.Write((string)parameter);
break;
case ParameterTypes.UInt:
writer.Write((uint)parameter);
break;
case ParameterTypes.ULong:
writer.Write((ulong)parameter);
break;
case ParameterTypes.UShort:
writer.Write((ushort)parameter);
break;
case ParameterTypes.Type:
writer.Write(((Type)parameter).FullName);
break;
case ParameterTypes.Unknown:
ms = new MemoryStream();
formatter.Serialize(ms, parameter);
ms.Seek(0, SeekOrigin.Begin);
//write length of data
writer.Write((int)ms.Length);
//write data
writer.Write(ms.ToArray());
break;
default:
throw new Exception(string.Format("Unknown type byte '0x{0:X}'", typeByte));
}
}
else
writer.Write(ParameterTypes.Null);
}
}
internal object[] ReceiveParameters(BinaryReader reader)
{
int parameterCount = reader.ReadInt32();
object[] parameters = new object[parameterCount];
MemoryStream ms;
BinaryFormatter formatter = new BinaryFormatter();
for (int i = 0; i < parameterCount; i++)
{
//read type byte
byte typeByte = reader.ReadByte();
if (typeByte == ParameterTypes.Null)
parameters[i] = null;
else
{
int count;
switch (typeByte)
{
case ParameterTypes.Bool:
parameters[i] = reader.ReadBoolean();
break;
case ParameterTypes.Byte:
parameters[i] = reader.ReadByte();
break;
case ParameterTypes.ByteArray:
count = reader.ReadInt32();
parameters[i] = reader.ReadBytes(count);
break;
case ParameterTypes.Char:
parameters[i] = reader.ReadChar();
break;
case ParameterTypes.CharArray:
count = reader.ReadInt32();
parameters[i] = reader.ReadChars(count);
break;
case ParameterTypes.Decimal:
parameters[i] = reader.ReadDecimal();
break;
case ParameterTypes.Double:
parameters[i] = reader.ReadDouble();
break;
case ParameterTypes.Float:
parameters[i] = reader.ReadSingle();
break;
case ParameterTypes.Int:
parameters[i] = reader.ReadInt32();
break;
case ParameterTypes.Long:
parameters[i] = reader.ReadInt64();
break;
case ParameterTypes.SByte:
parameters[i] = reader.ReadSByte();
break;
case ParameterTypes.Short:
parameters[i] = reader.ReadInt16();
break;
case ParameterTypes.String:
parameters[i] = reader.ReadString();
break;
case ParameterTypes.UInt:
parameters[i] = reader.ReadUInt32();
break;
case ParameterTypes.ULong:
parameters[i] = reader.ReadUInt64();
break;
case ParameterTypes.UShort:
parameters[i] = reader.ReadUInt16();
break;
case ParameterTypes.Type:
var typeName = reader.ReadString();
parameters[i] = Type.GetType(typeName);
break;
case ParameterTypes.Unknown:
ms = new MemoryStream(reader.ReadBytes(reader.ReadInt32()));
//deserialize the parameter array
parameters[i] = formatter.Deserialize(ms);
break;
default:
throw new Exception(string.Format("Unknown type byte '0x{0:X}'", typeByte));
}
}
}
return parameters;
}
private byte GetParameterType(Type type)
{
if (_parameterTypes.ContainsKey(type))
return _parameterTypes[type];
else
return ParameterTypes.Unknown;
}
}
}

View file

@ -0,0 +1,35 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("RemotingLite")]
[assembly: AssemblyDescription("A light framework for remote method invocation")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("http://sector0.dk")]
[assembly: AssemblyProduct("RemotingLite")]
[assembly: AssemblyCopyright("Copyright © 2008 Frank Thomsen")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("0a4da926-e000-4481-955e-f8723aa69962")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.3.0.0")]
[assembly: AssemblyFileVersion("1.3.0.0")]

View file

@ -0,0 +1,212 @@
/*************************************************************************************************
* RemotingLite
* ------
* A light framework for making remote method invocations using TCP/IP. It is based loosely on
* Windows Communication Foundation, and is meant to provide programmers with the same API
* regardless of whether they write software for the Microsoft .NET platform or the Mono .NET
* platform.
* Consult the documentation and example applications for information about how to use this API.
*
* Author : Frank Thomsen
* http : http://sector0.dk
* Concact : http://sector0.dk/?q=contact
* Information : http://sector0.dk/?q=node/27
* Licence : Free. If you use this, please let me know.
*
* Please feel free to contact me with ideas, bugs or improvements.
*************************************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Reflection.Emit;
using System.Reflection;
using System.Threading;
namespace RemotingLite
{
public sealed class ProxyFactory
{
public static TInterface CreateProxy<TInterface>(IPEndPoint endpoint) where TInterface : class
{
AppDomain domain = Thread.GetDomain();
// create a new assembly for the proxy
AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(new AssemblyName("ProxyAssembly"), AssemblyBuilderAccess.Run);
// create a new module for the proxy
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("ProxyModule", true);
// Set the class to be public and sealed
TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed;
// Construct the type builder
TypeBuilder typeBuilder = moduleBuilder.DefineType(typeof(TInterface).Name + "Proxy", typeAttributes, typeof(Channel));
List<Type> allInterfaces = new List<Type>(typeof(TInterface).GetInterfaces());
allInterfaces.Add(typeof(TInterface));
//add the interface
typeBuilder.AddInterfaceImplementation(typeof(TInterface));
//construct the constructor
Type[] ctorArgTypes = new Type[] { typeof(IPEndPoint) };
CreateConstructor(typeBuilder, ctorArgTypes);
//construct the type maps
Dictionary<Type, OpCode> ldindOpCodeTypeMap = new Dictionary<Type, OpCode>();
ldindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Ldind_I1);
ldindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Ldind_U1);
ldindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Ldind_I1);
ldindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Ldind_I2);
ldindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Ldind_U2);
ldindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Ldind_I4);
ldindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Ldind_U4);
ldindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Ldind_I8);
ldindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Ldind_I8);
ldindOpCodeTypeMap.Add(typeof(Char), OpCodes.Ldind_U2);
ldindOpCodeTypeMap.Add(typeof(Double), OpCodes.Ldind_R8);
ldindOpCodeTypeMap.Add(typeof(Single), OpCodes.Ldind_R4);
Dictionary<Type, OpCode> stindOpCodeTypeMap = new Dictionary<Type, OpCode>();
stindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Stind_I1);
stindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Stind_I1);
stindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Stind_I1);
stindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Stind_I2);
stindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Stind_I2);
stindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Stind_I4);
stindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Stind_I4);
stindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Stind_I8);
stindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Stind_I8);
stindOpCodeTypeMap.Add(typeof(Char), OpCodes.Stind_I2);
stindOpCodeTypeMap.Add(typeof(Double), OpCodes.Stind_R8);
stindOpCodeTypeMap.Add(typeof(Single), OpCodes.Stind_R4);
//construct the method builders from the method infos defined in the interface
List<MethodInfo> methods = GetAllMethods(allInterfaces);
foreach (MethodInfo methodInfo in methods)
{
MethodBuilder methodBuilder = ConstructMethod(methodInfo, typeBuilder, ldindOpCodeTypeMap, stindOpCodeTypeMap);
typeBuilder.DefineMethodOverride(methodBuilder, methodInfo);
}
//create the type and construct an instance
Type t = typeBuilder.CreateType();
TInterface instance = (TInterface)t.GetConstructor(ctorArgTypes).Invoke(new object[] { endpoint });
return instance;
}
private static List<MethodInfo> GetAllMethods(List<Type> allInterfaces)
{
List<MethodInfo> methods = new List<MethodInfo>();
foreach (Type interfaceType in allInterfaces)
methods.AddRange(interfaceType.GetMethods());
return methods;
}
private static void CreateConstructor(TypeBuilder typeBuilder, Type[] ctorArgTypes)
{
ConstructorBuilder ctor = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, ctorArgTypes);
ConstructorInfo baseCtor = typeof(Channel).GetConstructor(ctorArgTypes);
ILGenerator ctorIL = ctor.GetILGenerator();
ctorIL.Emit(OpCodes.Ldarg_0); //load "this"
ctorIL.Emit(OpCodes.Ldarg_1); //load "endpoint"
ctorIL.Emit(OpCodes.Call, baseCtor); //call "base(...)"
ctorIL.Emit(OpCodes.Ret);
}
private static MethodBuilder ConstructMethod(MethodInfo methodInfo, TypeBuilder typeBuilder, Dictionary<Type, OpCode> ldindOpCodeTypeMap, Dictionary<Type, OpCode> stindOpCodeTypeMap)
{
ParameterInfo[] paramInfos = methodInfo.GetParameters();
int nofParams = paramInfos.Length;
Type[] parameterTypes = new Type[nofParams];
for (int i = 0; i < nofParams; i++)
parameterTypes[i] = paramInfos[i].ParameterType;
Type returnType = methodInfo.ReturnType;
MethodBuilder methodBuilder = typeBuilder.DefineMethod(methodInfo.Name, MethodAttributes.Public | MethodAttributes.Virtual, returnType, parameterTypes);
ILGenerator mIL = methodBuilder.GetILGenerator();
GenerateILCodeForMethod(mIL, parameterTypes, methodBuilder.ReturnType, ldindOpCodeTypeMap, stindOpCodeTypeMap);
return methodBuilder;
}
private static void GenerateILCodeForMethod(ILGenerator mIL, Type[] inputArgTypes, Type returnType, Dictionary<Type, OpCode> ldindOpCodeTypeMap, Dictionary<Type, OpCode> stindOpCodeTypeMap)
{
int nofArgs = inputArgTypes.Length;
//get the MethodInfo for InvokeMethod
MethodInfo invokeMethodMI = typeof(Channel).GetMethod("InvokeMethod", BindingFlags.Instance | BindingFlags.NonPublic);
//declare local variables
LocalBuilder resultLB = mIL.DeclareLocal(typeof(object[])); // object[] result
mIL.Emit(OpCodes.Ldarg_0); //load "this"
mIL.Emit(OpCodes.Ldc_I4, nofArgs); //push the number of arguments
mIL.Emit(OpCodes.Newarr, typeof(object)); //create an array of objects
//store every input argument in the args array
for (int i = 0; i < nofArgs; i++)
{
Type inputType = inputArgTypes[i].IsByRef ? inputArgTypes[i].GetElementType() : inputArgTypes[i];
mIL.Emit(OpCodes.Dup);
mIL.Emit(OpCodes.Ldc_I4, i); //push the index onto the stack
mIL.Emit(OpCodes.Ldarg, i + 1); //load the i'th argument. This might be an address
if (inputArgTypes[i].IsByRef)
{
if (inputType.IsValueType)
{
mIL.Emit(ldindOpCodeTypeMap[inputType]);
mIL.Emit(OpCodes.Box, inputType);
}
else
mIL.Emit(OpCodes.Ldind_Ref);
}
else
{
if (inputArgTypes[i].IsValueType)
mIL.Emit(OpCodes.Box, inputArgTypes[i]);
}
mIL.Emit(OpCodes.Stelem_Ref); //store the reference in the args array
}
mIL.Emit(OpCodes.Call, invokeMethodMI);
mIL.Emit(OpCodes.Stloc, resultLB.LocalIndex); //store the result
//store the results in the arguments
for (int i = 0; i < nofArgs; i++)
{
if (inputArgTypes[i].IsByRef)
{
Type inputType = inputArgTypes[i].GetElementType();
mIL.Emit(OpCodes.Ldarg, i + 1); //load the address of the argument
mIL.Emit(OpCodes.Ldloc, resultLB.LocalIndex); //load the result array
mIL.Emit(OpCodes.Ldc_I4, i + 1); //load the index into the result array
mIL.Emit(OpCodes.Ldelem_Ref); //load the value in the index of the array
if (inputType.IsValueType)
{
mIL.Emit(OpCodes.Unbox, inputArgTypes[i].GetElementType());
mIL.Emit(ldindOpCodeTypeMap[inputArgTypes[i].GetElementType()]);
mIL.Emit(stindOpCodeTypeMap[inputArgTypes[i].GetElementType()]);
}
else
{
mIL.Emit(OpCodes.Castclass, inputArgTypes[i].GetElementType());
mIL.Emit(OpCodes.Stind_Ref); //store the unboxed value at the argument address
}
}
}
if (returnType != typeof(void))
{
mIL.Emit(OpCodes.Ldloc, resultLB.LocalIndex); //load the result array
mIL.Emit(OpCodes.Ldc_I4, 0); //load the index of the return value. Alway 0
mIL.Emit(OpCodes.Ldelem_Ref); //load the value in the index of the array
if (returnType.IsValueType)
{
mIL.Emit(OpCodes.Unbox, returnType); //unbox it
mIL.Emit(ldindOpCodeTypeMap[returnType]);
}
else
mIL.Emit(OpCodes.Castclass, returnType);
}
mIL.Emit(OpCodes.Ret);
}
}
}

View file

@ -0,0 +1,45 @@
1.2.4 -> 1.2.5
o Fixed error with exceptions. When an exception is thrown server side it will now be rethrown at the client.
Thanks to Pierre Chalamet for the patch.
1.2.3 -> 1.2.4
===============
o Forced the TcpClient used in communication to use IP v. 4. This will enable the framework to run on Windows Vista, where
the default protocol seems to be IP v. 6, preventing the framework from working properly.
Thanks to Maneesak Pimsarn for providing the solution.
1.2.2 -> 1.2.3
===============
o Further optimized the serialization if the parameters of the method being invoked are one of the following simple
types: bool, byte, sbyte, char, decimal, double, float, int, uint, long, ulong, short, ushort, string, byte[], char[]
This gives a performance gain of up to 33% if the parameters are all one of the simple types.
1.2.1 -> 1.2.2
===============
o Fixed problem with out-parameters. The wrong opcodes where generated for the IL-code of the proxies, and the wrong type parameter was
checked for when assigning ref- and out-parameter values.
1.2 -> 1.2.1
===============
o Fixed the Mono incompatibility problem with the proxies generated by ProxyFactory.
1.1 -> 1.2
===============
o Significant performance improvements by a factor of 70-100 when communicating on network.
- Better and more efficient serialization and deserialization.
- A bit of transport protocol tuning.
- Only sending argument values back to the client when the argument is by reference.
o It is now possible to let the service host use thread pool threads instead of regular background threads.
Version 1.1.0
==============
o RemotingHost renamed to ServiceHost
o Added the property "EndPoint" to ServiceHost that specifies the end point the host is accepting incoming connections on.
o Renamed RemotingClientBase to ClientBase, and made it internal
o Added ProxyFactory which constructs proxies based on an interface. The instance coming out inherits from ClientBase.
This eliminates the need to write your own implementations of the proxies, and with all the type casting that was
necessary in version 1.0. This is automatically handled in the proxy.
o Added ClientBase. Subclass this when you want more control over what happens when invoking the host. This is also
necessary if you are implementing with the "using" keyword, since the instance needs to be castable to IDisposable.
o Added support for exceptions.

View file

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RemotingLite</RootNamespace>
<AssemblyName>RemotingLite</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileUpgradeFlags>
</FileUpgradeFlags>
<OldToolsVersion>2.0</OldToolsVersion>
<UpgradeBackupLocation />
<TargetFrameworkProfile />
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ClientBase.cs" />
<Compile Include="ParameterTransferHelper.cs" />
<Compile Include="ProxyFactory.cs" />
<Compile Include="MessageType.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Channel.cs" />
<Compile Include="ServiceHost.cs" />
</ItemGroup>
<ItemGroup>
<None Include="mono_build.bat" />
</ItemGroup>
<ItemGroup>
<None Include="Release Notes.txt" />
</ItemGroup>
<ItemGroup>
<None Include="Licence - RemotingLite.txt" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
<Visible>False</Visible>
<ProductName>Windows Installer 3.1</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View file

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemotingLite", "RemotingLite.csproj", "{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0AFFA4EB-EDEA-43CC-8045-C7D1FE557803}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,342 @@
/*************************************************************************************************
* RemotingLite
* ------
* A light framework for making remote method invocations using TCP/IP. It is based loosely on
* Windows Communication Foundation, and is meant to provide programmers with the same API
* regardless of whether they write software for the Microsoft .NET platform or the Mono .NET
* platform.
* Consult the documentation and example applications for information about how to use this API.
*
* Author : Frank Thomsen
* http : http://sector0.dk
* Concact : http://sector0.dk/?q=contact
* Information : http://sector0.dk/?q=node/27
* Licence : Free. If you use this, please let me know.
*
* Please feel free to contact me with ideas, bugs or improvements.
*************************************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Reflection;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Reflection.Emit;
using System.IO.Compression;
namespace RemotingLite
{
[Serializable]
internal class MethodSyncInfo
{
public int MethodIdent { get; set; }
public string MethodName { get; set; }
public Type[] ParameterTypes { get; set; }
}
public class ServiceHost : IDisposable
{
private bool _isOpen = false;
private TcpListener _listener;
private List<TcpClient> _clients;
private bool _continueListening;
private object _continueListeningLock = new object();
private object _singletonInstance;
private IPEndPoint _endPoint;
private bool _useThreadPool = false;
private Dictionary<int, MethodInfo> _interfaceMethods;
private Dictionary<int, bool[]> _methodParametersByRef;
private ParameterTransferHelper _parameterTransferHelper = new ParameterTransferHelper();
private bool Continue
{
get
{
lock (_continueListeningLock)
{
return _continueListening;
}
}
set
{
lock (_continueListeningLock)
{
_continueListening = value;
}
}
}
/// <summary>
/// Get or set whether the host should use regular or thread pool threads.
/// </summary>
public bool UseThreadPool
{
get { return _useThreadPool; }
set
{
if (_isOpen)
throw new Exception("The host is already open");
_useThreadPool = value;
}
}
/// <summary>
/// Constructs an instance of the host and starts listening for incoming connections.
/// All listener threads are regular background threads.
///
/// NOTE: the instance created from the specified type is not automatically thread safe!
/// </summary>
/// <param name="remotedType">The remoted type. This must have a default constructor</param>
/// <param name="port">The port number for incoming requests</param>
public ServiceHost(Type remotedType, int port)
: this(Activator.CreateInstance(remotedType), port)
{
}
/// <summary>
/// Constructs an instance of the host and starts listening for incoming connections.
/// All listener threads are regular background threads.
///
/// NOTE: the instance is not automatically thread safe!
/// </summary>
/// <param name="singletonInstance">The singleton instance of the service</param>
/// <param name="port">The port number for incoming requests</param>
public ServiceHost(object singletonInstance, int port)
{
IPAddress[] addressList = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
IPAddress address = null;
foreach (var a in addressList)
if (a.AddressFamily == AddressFamily.InterNetwork)
{
address = a;
break;
}
_endPoint = new IPEndPoint(address, port);
_listener = new TcpListener(_endPoint);
_clients = new List<TcpClient>();
_continueListening = true;
_singletonInstance = singletonInstance;
CreateMethodMap();
}
/// <summary>
/// Loads all methods from interfaces and assigns an identifier
/// to each. These are later synchronized with the client.
/// </summary>
private void CreateMethodMap()
{
var interfaces = _singletonInstance.GetType().GetInterfaces();
_interfaceMethods = new Dictionary<int, MethodInfo>();
_methodParametersByRef = new Dictionary<int, bool[]>();
var currentMethodIdent = 0;
foreach (var interfaceType in interfaces)
{
var methodInfos = interfaceType.GetMethods();
foreach (var mi in methodInfos)
{
_interfaceMethods.Add(currentMethodIdent, mi);
var parameterInfos = mi.GetParameters();
var isByRef = new bool[parameterInfos.Length];
for (int i = 0; i < isByRef.Length; i++)
isByRef[i] = parameterInfos[i].ParameterType.IsByRef;
_methodParametersByRef.Add(currentMethodIdent, isByRef);
currentMethodIdent++;
}
}
}
/// <summary>
/// Gets the end point this host is listening on
/// </summary>
public IPEndPoint EndPoint
{
get { return _endPoint; }
}
/// <summary>
/// Opens the host and starts a listener thread. This listener thread spawns a new thread (or uses a
/// thread pool thread) for each incoming connection.
/// </summary>
public void Open()
{
//start listening in the background
if (_useThreadPool)
ThreadPool.QueueUserWorkItem(ListenerThreadProc);
else
{
Thread t = new Thread(ListenerThreadProc);
t.IsBackground = true;
t.Start();
}
_isOpen = true;
}
/// <summary>
/// Closes the host and calls Dispose().
/// </summary>
public void Close()
{
Dispose();
}
/// <summary>
/// Listens for incoming requests.
///
/// This method runs in a separate thread
/// </summary>
/// <param name="state"></param>
private void ListenerThreadProc(object state)
{
_listener.Start();
while (Continue)
{
try
{
TcpClient client = _listener.AcceptTcpClient();
_clients.Add(client);
if (_useThreadPool)
ThreadPool.QueueUserWorkItem(ClientThreadProc, client);
else
{
Thread t = new Thread(ClientThreadProc);
t.IsBackground = true;
t.Start(client);
}
}
catch (SocketException) //this is normal since the thread is a background thread
{
Continue = false;
}
}
}
/// <summary>
/// This method handles all requests from a single client.
///
/// There is one thread running this method for each connected client.
/// </summary>
/// <param name="state"></param>
private void ClientThreadProc(object state)
{
TcpClient client = (TcpClient)state;
client.NoDelay = true;
Stream stream = client.GetStream();
BinaryReader binReader = new BinaryReader(stream);
BinaryWriter binWriter = new BinaryWriter(stream);
bool doContinue = true;
do
{
try
{
MemoryStream ms;
BinaryFormatter formatter = new BinaryFormatter();
//read message type
MessageType messageType = (MessageType)binReader.ReadInt32();
switch (messageType)
{
case MessageType.SyncInterface:
//Create a list of sync infos from the dictionary
var syncInfos = new List<MethodSyncInfo>();
foreach(var kvp in _interfaceMethods)
{
var parameters = kvp.Value.GetParameters();
var parameterTypes = new Type[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
parameterTypes[i] = parameters[i].ParameterType;
syncInfos.Add(new MethodSyncInfo { MethodIdent = kvp.Key, MethodName = kvp.Value.Name, ParameterTypes = parameterTypes });
}
//send the sync data back to the client
ms = new MemoryStream();
formatter.Serialize(ms, syncInfos);
ms.Seek(0, SeekOrigin.Begin);
binWriter.Write((int)ms.Length);
binWriter.Write(ms.ToArray());
binWriter.Flush();
stream.Flush();
break;
case MessageType.MethodInvocation:
//read the method identifier
int methodHashCode = binReader.ReadInt32();
if (_interfaceMethods.ContainsKey(methodHashCode))
{
var method = _interfaceMethods[methodHashCode];
var isByRef = _methodParametersByRef[methodHashCode];
//read parameter data
var parameters = _parameterTransferHelper.ReceiveParameters(binReader);
//invoke the method
object[] returnParameters;
var returnMessageType = MessageType.ReturnValues;
try
{
object returnValue = method.Invoke(_singletonInstance, parameters);
//the result to the client is the return value (null if void) and the input parameters
returnParameters = new object[1 + parameters.Length];
returnParameters[0] = returnValue;
for (int i = 0; i < parameters.Length; i++)
returnParameters[i + 1] = isByRef[i] ? parameters[i] : null;
}
catch (Exception ex)
{
//an exception was caught. Rethrow it client side
returnParameters = new object[] { ex };
returnMessageType = MessageType.ThrowException;
}
//send the result back to the client
// (1) write the message type
binWriter.Write((int)returnMessageType);
// (2) write the return parameters
_parameterTransferHelper.SendParameters(binWriter, returnParameters);
}
else
binWriter.Write((int)MessageType.UnknownMethod);
//flush
binWriter.Flush();
stream.Flush();
break;
case MessageType.TerminateConnection:
doContinue = false;
break;
default:
break;
}
}
catch (Exception) //do not resume operation on this thread if any errors are unhandled.
{
doContinue = false;
}
}
while (doContinue);
client.Close();
binReader.Close();
stream.Close();
lock (_clients)
{
_clients.Remove(client);
}
}
#region IDisposable Members
public void Dispose()
{
_isOpen = false;
Continue = false;
_listener.Stop();
foreach (TcpClient client in _clients)
client.Close();
}
#endregion
}
}

View file

@ -0,0 +1 @@
call gmcs Properties\AssemblyInfo.cs *.cs -optimize+ -target:library -out:RemotingLite.dll

View file

@ -2642,3 +2642,6 @@ Translated:Search Library
English:My Library
Translated:My Library
English:Add to Library
Translated:Add to Library