From 2d3d26a68d09ea7cdea201f44df5bda53da655ec Mon Sep 17 00:00:00 2001 From: larsbrubaker Date: Thu, 9 Oct 2014 11:29:33 -0700 Subject: [PATCH] Working to get the collision stuff working with mesh groups Put in the RomotingLite project to start on TigerSong --- PartPreviewWindow/View3DTransfromPart.cs | 107 +++- .../DefaultTemplate.11.1.xaml | 543 ++++++++++++++++ .../DefaultTemplate.xaml | 602 ++++++++++++++++++ .../LabDefaultTemplate.11.xaml | 208 ++++++ .../UpgradeTemplate.xaml | 76 +++ .../Example/CommonTypes/CommonTypes.csproj | 87 +++ .../Example/CommonTypes/IService.cs | 53 ++ .../CommonTypes/Properties/AssemblyInfo.cs | 35 + .../Example/CommonTypes/Rectangle.cs | 41 ++ .../Example/RemotingLiteExample.sln | 50 ++ .../ClientProxyImpl.cs | 70 ++ .../ExampleUsingClientProxyImpl.cs | 60 ++ .../ExampleUsingProxyFactory.cs | 68 ++ .../RemotingLiteExampleClient/Program.cs | 22 + .../Properties/AssemblyInfo.cs | 33 + .../RemotingLiteExampleClient.csproj | 102 +++ .../RemotingLiteExampleClient/app.config | 3 + .../RemotingLiteExampleServer/Program.cs | 24 + .../Properties/AssemblyInfo.cs | 33 + .../RemotingLiteExampleServer.csproj | 100 +++ .../RemotingLiteExampleServer/ServiceImpl.cs | 52 ++ .../RemotingLiteExampleServer/app.config | 3 + .../Example/deps/Licence - RemotingLite.txt | 26 + .../Example/deps/RemotingLite.dll | Bin 0 -> 28672 bytes .../RemotingLite/src/Channel.cs | 161 +++++ .../RemotingLite/src/ClientBase.cs | 46 ++ .../src/Licence - RemotingLite.txt | 26 + .../RemotingLite/src/MessageType.cs | 34 + .../src/ParameterTransferHelper.cs | 241 +++++++ .../src/Properties/AssemblyInfo.cs | 35 + .../RemotingLite/src/ProxyFactory.cs | 212 ++++++ .../RemotingLite/src/Release Notes.txt | 45 ++ .../RemotingLite/src/RemotingLite.csproj | 102 +++ .../RemotingLite/src/RemotingLite.sln | 20 + .../RemotingLite/src/ServiceHost.cs | 342 ++++++++++ .../RemotingLite/src/mono_build.bat | 1 + StaticData/Translations/Master.txt | 3 + 37 files changed, 3647 insertions(+), 19 deletions(-) create mode 100644 PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.11.1.xaml create mode 100644 PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.xaml create mode 100644 PrinterCommunication/RemotingLite/BuildProcessTemplates/LabDefaultTemplate.11.xaml create mode 100644 PrinterCommunication/RemotingLite/BuildProcessTemplates/UpgradeTemplate.xaml create mode 100644 PrinterCommunication/RemotingLite/Example/CommonTypes/CommonTypes.csproj create mode 100644 PrinterCommunication/RemotingLite/Example/CommonTypes/IService.cs create mode 100644 PrinterCommunication/RemotingLite/Example/CommonTypes/Properties/AssemblyInfo.cs create mode 100644 PrinterCommunication/RemotingLite/Example/CommonTypes/Rectangle.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExample.sln create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ClientProxyImpl.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingClientProxyImpl.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingProxyFactory.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Program.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Properties/AssemblyInfo.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/RemotingLiteExampleClient.csproj create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/app.config create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Program.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Properties/AssemblyInfo.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/RemotingLiteExampleServer.csproj create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/ServiceImpl.cs create mode 100644 PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/app.config create mode 100644 PrinterCommunication/RemotingLite/Example/deps/Licence - RemotingLite.txt create mode 100644 PrinterCommunication/RemotingLite/Example/deps/RemotingLite.dll create mode 100644 PrinterCommunication/RemotingLite/src/Channel.cs create mode 100644 PrinterCommunication/RemotingLite/src/ClientBase.cs create mode 100644 PrinterCommunication/RemotingLite/src/Licence - RemotingLite.txt create mode 100644 PrinterCommunication/RemotingLite/src/MessageType.cs create mode 100644 PrinterCommunication/RemotingLite/src/ParameterTransferHelper.cs create mode 100644 PrinterCommunication/RemotingLite/src/Properties/AssemblyInfo.cs create mode 100644 PrinterCommunication/RemotingLite/src/ProxyFactory.cs create mode 100644 PrinterCommunication/RemotingLite/src/Release Notes.txt create mode 100644 PrinterCommunication/RemotingLite/src/RemotingLite.csproj create mode 100644 PrinterCommunication/RemotingLite/src/RemotingLite.sln create mode 100644 PrinterCommunication/RemotingLite/src/ServiceHost.cs create mode 100644 PrinterCommunication/RemotingLite/src/mono_build.bat diff --git a/PartPreviewWindow/View3DTransfromPart.cs b/PartPreviewWindow/View3DTransfromPart.cs index d1e6a8bf5..d0f754639 100644 --- a/PartPreviewWindow/View3DTransfromPart.cs +++ b/PartPreviewWindow/View3DTransfromPart.cs @@ -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 { diff --git a/PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.11.1.xaml b/PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.11.1.xaml new file mode 100644 index 000000000..bf54edfd9 --- /dev/null +++ b/PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.11.1.xaml @@ -0,0 +1,543 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + [New Microsoft.TeamFoundation.Build.Workflow.Activities.BuildSettings()] + [False] + [New Microsoft.TeamFoundation.Build.Workflow.Activities.TestSpecList(New Microsoft.TeamFoundation.Build.Workflow.Activities.AgileTestPlatformSpec("**\*test*.dll"))] + ["$(BuildDefinitionName)_$(Date:yyyyMMdd)$(Rev:.r)"] + [False] + [True] + [True] + [Microsoft.TeamFoundation.Build.Workflow.Activities.CleanWorkspaceOption.All] + + + + [Microsoft.TeamFoundation.Build.Workflow.Activities.CodeAnalysisOption.AsConfigured] + [True] + [Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto] + [True] + [New Microsoft.TeamFoundation.Build.Workflow.Activities.SourceAndSymbolServerSettings(True, Nothing)] + [True] + + + + [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 }] + [Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal] + + + + + + + All + 11.0 + Assembly references and imported namespaces serialized as XML namespaces + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.xaml b/PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.xaml new file mode 100644 index 000000000..12cc6241d --- /dev/null +++ b/PrinterCommunication/RemotingLite/BuildProcessTemplates/DefaultTemplate.xaml @@ -0,0 +1,602 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Assembly references and imported namespaces serialized as XML namespaces + + + True + + + + + + + + + True + + + + + + + True + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + True + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + True + + + + + + + + + + + + + + + True + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + True + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + False + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/BuildProcessTemplates/LabDefaultTemplate.11.xaml b/PrinterCommunication/RemotingLite/BuildProcessTemplates/LabDefaultTemplate.11.xaml new file mode 100644 index 000000000..9e1fb0b51 --- /dev/null +++ b/PrinterCommunication/RemotingLite/BuildProcessTemplates/LabDefaultTemplate.11.xaml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + 11.0 + + + + + + 920,3702 + Assembly references and imported namespaces serialized as XML namespaces + + + + + + + + + + + + + + + + + + + + + True + + + + + + + [LabWorkflowParameters.BuildDetails.BuildUri] + + + [ChildBuildDetail.Uri] + + + + + + + + + + + + [BuildLocation] + + + [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)))] + + + + + + + + + + + + [LabEnvironmentUri] + + + [LabWorkflowParameters.EnvironmentDetails.LabEnvironmentUri.ToString()] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [PostDeploymentSnapshotName] + + + [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))] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + [BuildStatus] + + + [Microsoft.TeamFoundation.Build.Client.BuildStatus.PartiallySucceeded] + + + + + + + [BuildStatus] + + + [Microsoft.TeamFoundation.Build.Client.BuildStatus.Failed] + + + + + + + + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/BuildProcessTemplates/UpgradeTemplate.xaml b/PrinterCommunication/RemotingLite/BuildProcessTemplates/UpgradeTemplate.xaml new file mode 100644 index 000000000..166acb22c --- /dev/null +++ b/PrinterCommunication/RemotingLite/BuildProcessTemplates/UpgradeTemplate.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + [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 }] + + + + [Microsoft.TeamFoundation.Build.Workflow.Activities.ToolPlatform.Auto] + [False] + [False] + + + + + + + + + + [Microsoft.TeamFoundation.VersionControl.Client.RecursionType.OneLevel] + [Microsoft.TeamFoundation.Build.Workflow.BuildVerbosity.Normal] + + + + All + Assembly references and imported namespaces serialized as XML namespaces + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/Example/CommonTypes/CommonTypes.csproj b/PrinterCommunication/RemotingLite/Example/CommonTypes/CommonTypes.csproj new file mode 100644 index 000000000..f8dd5f7f6 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/CommonTypes/CommonTypes.csproj @@ -0,0 +1,87 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {04B850F0-5A39-4157-A227-A574064110D2} + Library + Properties + CommonTypes + CommonTypes + v4.0 + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/Example/CommonTypes/IService.cs b/PrinterCommunication/RemotingLite/Example/CommonTypes/IService.cs new file mode 100644 index 000000000..e3692b86b --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/CommonTypes/IService.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CommonTypes +{ + public interface IService + { + /// + /// An example with two integer arguments + /// + /// + /// + /// + int Sum(int a, int b); + + /// + /// An example with a variable number of arguments + /// + /// + /// + int Sum(params int[] values); + + /// + /// An example with a return value + /// + /// + /// + string ToUpper(string str); + + /// + /// An example with a ref argument + /// + /// + void MakeStringUpperCase(ref string str); + + /// + /// An example with an out argument + /// + /// + /// + void MakeStringLowerCase(string str, out string lowerCaseString); + + /// + /// 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. + /// + /// + void CalculateArea(ref Rectangle rectangle); + + void Square(long a, out long b); + } +} diff --git a/PrinterCommunication/RemotingLite/Example/CommonTypes/Properties/AssemblyInfo.cs b/PrinterCommunication/RemotingLite/Example/CommonTypes/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..8b3888622 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/CommonTypes/Properties/AssemblyInfo.cs @@ -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")] diff --git a/PrinterCommunication/RemotingLite/Example/CommonTypes/Rectangle.cs b/PrinterCommunication/RemotingLite/Example/CommonTypes/Rectangle.cs new file mode 100644 index 000000000..0caa35746 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/CommonTypes/Rectangle.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace CommonTypes +{ + /// + /// A naive user defined type which we will use in the remoting example. + /// Remember that all types used must be serializable. + /// + [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; } + } + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExample.sln b/PrinterCommunication/RemotingLite/Example/RemotingLiteExample.sln new file mode 100644 index 000000000..b57d64b3d --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExample.sln @@ -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 diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ClientProxyImpl.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ClientProxyImpl.cs new file mode 100644 index 000000000..02270bd8d --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ClientProxyImpl.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Text; +using CommonTypes; +using RemotingLite; +using System.Net; + +namespace RemotingLiteExampleClient +{ + /// + /// 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! + /// + public class ClientProxyImpl : ClientBase, IService + { + /// + /// The class inheriting from ClientBase must define a constructor which takes + /// an end point to the host. You have to call the base constructor. + /// + /// + 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 + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingClientProxyImpl.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingClientProxyImpl.cs new file mode 100644 index 000000000..c70ba7c8f --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingClientProxyImpl.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Net; +using System.Net.Sockets; +using CommonTypes; + +namespace RemotingLiteExampleClient +{ + /// + /// This class shows an example of how to use our own client proxy implementation + /// that inherits from ClientBase. + /// + 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)); + } + } + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingProxyFactory.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingProxyFactory.cs new file mode 100644 index 000000000..d51423086 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/ExampleUsingProxyFactory.cs @@ -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 +{ + /// + /// This is an example of how to use ProxyFactory directly. + /// + 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(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(); + } + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Program.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Program.cs new file mode 100644 index 000000000..90ca9a10a --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Program.cs @@ -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(); + } + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Properties/AssemblyInfo.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..f8adbc513 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/Properties/AssemblyInfo.cs @@ -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")] diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/RemotingLiteExampleClient.csproj b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/RemotingLiteExampleClient.csproj new file mode 100644 index 000000000..e057f8f98 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/RemotingLiteExampleClient.csproj @@ -0,0 +1,102 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {275568A0-7E5E-4151-8960-E54665FF5DF7} + Exe + Properties + RemotingLiteExampleClient + RemotingLiteExampleClient + v4.0 + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + {0AFFA4EB-EDEA-43CC-8045-C7D1FE557803} + RemotingLite + + + {04B850F0-5A39-4157-A227-A574064110D2} + CommonTypes + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/app.config b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/app.config new file mode 100644 index 000000000..e36560333 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleClient/app.config @@ -0,0 +1,3 @@ + + + diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Program.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Program.cs new file mode 100644 index 000000000..b8446da28 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Program.cs @@ -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 to terminate."); + Console.WriteLine(String.Format("Address is {0}", host.EndPoint.Address)); + Console.WriteLine("Press to terminate."); + Console.ReadLine(); + } + } + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Properties/AssemblyInfo.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..8abe256dd --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/Properties/AssemblyInfo.cs @@ -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")] diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/RemotingLiteExampleServer.csproj b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/RemotingLiteExampleServer.csproj new file mode 100644 index 000000000..bd8fdc723 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/RemotingLiteExampleServer.csproj @@ -0,0 +1,100 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {EFBE44D0-1F61-42CF-9489-EED99AA1887F} + Exe + Properties + RemotingLiteExampleServer + RemotingLiteExampleServer + v4.0 + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + {0AFFA4EB-EDEA-43CC-8045-C7D1FE557803} + RemotingLite + + + {04B850F0-5A39-4157-A227-A574064110D2} + CommonTypes + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/ServiceImpl.cs b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/ServiceImpl.cs new file mode 100644 index 000000000..92ec4fff6 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/ServiceImpl.cs @@ -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 + } +} diff --git a/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/app.config b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/app.config new file mode 100644 index 000000000..e36560333 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/RemotingLiteExampleServer/app.config @@ -0,0 +1,3 @@ + + + diff --git a/PrinterCommunication/RemotingLite/Example/deps/Licence - RemotingLite.txt b/PrinterCommunication/RemotingLite/Example/deps/Licence - RemotingLite.txt new file mode 100644 index 000000000..cf5a42c24 --- /dev/null +++ b/PrinterCommunication/RemotingLite/Example/deps/Licence - RemotingLite.txt @@ -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. \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/Example/deps/RemotingLite.dll b/PrinterCommunication/RemotingLite/Example/deps/RemotingLite.dll new file mode 100644 index 0000000000000000000000000000000000000000..672ca5950b8158255f9c19cc17856b804345fc07 GIT binary patch literal 28672 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 z _syncInfos; + + /// + /// Creates a connection to the concrete object handling method calls on the server side + /// + /// + 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(); + } + + /// + /// 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. + /// + 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)_formatter.Deserialize(ms); + } + + /// + /// Closes the connection to the server + /// + public void Close() + { + Dispose(); + } + + /// + /// Invokes the method with the specified parameters. + /// + /// The name of the method + /// Parameters for the method call + /// 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" + 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 + } +} diff --git a/PrinterCommunication/RemotingLite/src/ClientBase.cs b/PrinterCommunication/RemotingLite/src/ClientBase.cs new file mode 100644 index 000000000..963beb573 --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/ClientBase.cs @@ -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 : IDisposable where TInterface : class + { + private TInterface _proxy; + + public TInterface Proxy { get { return _proxy; } } + + public ClientBase(IPEndPoint endpoint) + { + _proxy = ProxyFactory.CreateProxy(endpoint); + } + + #region IDisposable Members + + public void Dispose() + { + (_proxy as Channel).Dispose(); + } + + #endregion + } +} diff --git a/PrinterCommunication/RemotingLite/src/Licence - RemotingLite.txt b/PrinterCommunication/RemotingLite/src/Licence - RemotingLite.txt new file mode 100644 index 000000000..cf5a42c24 --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/Licence - RemotingLite.txt @@ -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. \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/src/MessageType.cs b/PrinterCommunication/RemotingLite/src/MessageType.cs new file mode 100644 index 000000000..144a16f10 --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/MessageType.cs @@ -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 + }; +} diff --git a/PrinterCommunication/RemotingLite/src/ParameterTransferHelper.cs b/PrinterCommunication/RemotingLite/src/ParameterTransferHelper.cs new file mode 100644 index 000000000..b3fdab43e --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/ParameterTransferHelper.cs @@ -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 _parameterTypes; + + internal ParameterTransferHelper() + { + _parameterTypes = new Dictionary(); + _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; + } + } +} diff --git a/PrinterCommunication/RemotingLite/src/Properties/AssemblyInfo.cs b/PrinterCommunication/RemotingLite/src/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..65909c68f --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/Properties/AssemblyInfo.cs @@ -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")] diff --git a/PrinterCommunication/RemotingLite/src/ProxyFactory.cs b/PrinterCommunication/RemotingLite/src/ProxyFactory.cs new file mode 100644 index 000000000..5cbe0bb73 --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/ProxyFactory.cs @@ -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(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 allInterfaces = new List(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 ldindOpCodeTypeMap = new Dictionary(); + 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 stindOpCodeTypeMap = new Dictionary(); + 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 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 GetAllMethods(List allInterfaces) + { + List methods = new List(); + 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 ldindOpCodeTypeMap, Dictionary 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 ldindOpCodeTypeMap, Dictionary 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); + } + } +} diff --git a/PrinterCommunication/RemotingLite/src/Release Notes.txt b/PrinterCommunication/RemotingLite/src/Release Notes.txt new file mode 100644 index 000000000..1512d2a72 --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/Release Notes.txt @@ -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. \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/src/RemotingLite.csproj b/PrinterCommunication/RemotingLite/src/RemotingLite.csproj new file mode 100644 index 000000000..7299aa4c4 --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/RemotingLite.csproj @@ -0,0 +1,102 @@ + + + + Debug + AnyCPU + 8.0.50727 + 2.0 + {0AFFA4EB-EDEA-43CC-8045-C7D1FE557803} + Library + Properties + RemotingLite + RemotingLite + v4.0 + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + AllRules.ruleset + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + AllRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + true + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/PrinterCommunication/RemotingLite/src/RemotingLite.sln b/PrinterCommunication/RemotingLite/src/RemotingLite.sln new file mode 100644 index 000000000..7c9ea85ec --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/RemotingLite.sln @@ -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 diff --git a/PrinterCommunication/RemotingLite/src/ServiceHost.cs b/PrinterCommunication/RemotingLite/src/ServiceHost.cs new file mode 100644 index 000000000..abf15c0ac --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/ServiceHost.cs @@ -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 _clients; + private bool _continueListening; + private object _continueListeningLock = new object(); + private object _singletonInstance; + private IPEndPoint _endPoint; + private bool _useThreadPool = false; + private Dictionary _interfaceMethods; + private Dictionary _methodParametersByRef; + private ParameterTransferHelper _parameterTransferHelper = new ParameterTransferHelper(); + + private bool Continue + { + get + { + lock (_continueListeningLock) + { + return _continueListening; + } + } + set + { + lock (_continueListeningLock) + { + _continueListening = value; + } + } + } + + /// + /// Get or set whether the host should use regular or thread pool threads. + /// + public bool UseThreadPool + { + get { return _useThreadPool; } + set + { + if (_isOpen) + throw new Exception("The host is already open"); + _useThreadPool = value; + } + } + + /// + /// 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! + /// + /// The remoted type. This must have a default constructor + /// The port number for incoming requests + public ServiceHost(Type remotedType, int port) + : this(Activator.CreateInstance(remotedType), port) + { + } + + /// + /// 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! + /// + /// The singleton instance of the service + /// The port number for incoming requests + 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(); + _continueListening = true; + _singletonInstance = singletonInstance; + CreateMethodMap(); + } + + /// + /// Loads all methods from interfaces and assigns an identifier + /// to each. These are later synchronized with the client. + /// + private void CreateMethodMap() + { + var interfaces = _singletonInstance.GetType().GetInterfaces(); + _interfaceMethods = new Dictionary(); + _methodParametersByRef = new Dictionary(); + 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++; + } + } + } + + /// + /// Gets the end point this host is listening on + /// + public IPEndPoint EndPoint + { + get { return _endPoint; } + } + + /// + /// 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. + /// + 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; + } + + /// + /// Closes the host and calls Dispose(). + /// + public void Close() + { + Dispose(); + } + + /// + /// Listens for incoming requests. + /// + /// This method runs in a separate thread + /// + /// + 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; + } + } + } + + /// + /// This method handles all requests from a single client. + /// + /// There is one thread running this method for each connected client. + /// + /// + 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(); + 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 + } +} diff --git a/PrinterCommunication/RemotingLite/src/mono_build.bat b/PrinterCommunication/RemotingLite/src/mono_build.bat new file mode 100644 index 000000000..889f7120f --- /dev/null +++ b/PrinterCommunication/RemotingLite/src/mono_build.bat @@ -0,0 +1 @@ +call gmcs Properties\AssemblyInfo.cs *.cs -optimize+ -target:library -out:RemotingLite.dll diff --git a/StaticData/Translations/Master.txt b/StaticData/Translations/Master.txt index 9ffae789e..1da91b6b6 100644 --- a/StaticData/Translations/Master.txt +++ b/StaticData/Translations/Master.txt @@ -2642,3 +2642,6 @@ Translated:Search Library English:My Library Translated:My Library +English:Add to Library +Translated:Add to Library +