Merge pull request #142 from mycroes/net-standard-1-3

Support for NetStandard 1.3
This commit is contained in:
Michael Croes
2018-07-02 23:00:19 +02:00
committed by GitHub
23 changed files with 87 additions and 865 deletions

View File

@@ -18,12 +18,13 @@ S7.Net Plus has a [User Manual](https://github.com/killnine/s7netplus/blob/maste
+ Compatible S7 PLC (S7-200, S7-300, S7-400, S7-1200, S7-1500)
## Target framework
+ .NET Framework 3.5 or higher
+ Universal Windows Application (.Net Core) - see S7.UniversalWindowsApp.sln
## Supported frameworks
+ .NET Framework 4.5.2 and higher
+ .NET Standard 1.3 (.NET Core 1.0, UWP 10.0, Xamarin, ...)
+ .NET Standard 2.0 (.NET Core 2.0, .NET Framework 4.6.1)
## Compile
You need at least Visual Studio 2015 (you can download the Community Edition for free).
You need at least Visual Studio 2017 (you can download the Community Edition for free).
## Nuget

View File

@@ -1,29 +0,0 @@
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("S7.Net.Core")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("S7.Net.Core")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 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 Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
http://go.microsoft.com/fwlink/?LinkID=391919
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="S7.Net.Core">
<!-- add directives for your library here -->
</Library>
</Directives>

View File

@@ -1,176 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CBFF80E8-3D3D-4656-A27C-A65EA5774536}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>S7.Net.Core</RootNamespace>
<AssemblyName>S7.Net.Core</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10586.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>ARM</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>ARM</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<PlatformTarget>ARM</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<PlatformTarget>ARM</PlatformTarget>
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="..\S7.Net\Conversion.cs">
<Link>Conversion.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Enums.cs">
<Link>Enums.cs</Link>
</Compile>
<Compile Include="..\S7.Net\PLC.cs">
<Link>PLC.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Boolean.cs">
<Link>Types\Boolean.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Byte.cs">
<Link>Types\Byte.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\ByteArray.cs">
<Link>Types\ByteArray.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Class.cs">
<Link>Types\Class.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Counter.cs">
<Link>Types\Counter.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\DataItem.cs">
<Link>Types\DataItem.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\DInt.cs">
<Link>Types\DInt.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Double.cs">
<Link>Types\Double.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\DWord.cs">
<Link>Types\DWord.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Int.cs">
<Link>Types\Int.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\String.cs">
<Link>Types\String.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Struct.cs">
<Link>Types\Struct.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Timer.cs">
<Link>Types\Timer.cs</Link>
</Compile>
<Compile Include="..\S7.Net\Types\Word.cs">
<Link>Types\Word.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SocketClient.cs" />
<EmbeddedResource Include="Properties\S7.Net.Core.rd.xml" />
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.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

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<RestoreSuccess Condition=" '$(RestoreSuccess)' == '' ">True</RestoreSuccess>
<RestoreTool Condition=" '$(RestoreTool)' == '' ">NuGet</RestoreTool>
<ProjectAssetsFile Condition=" '$(ProjectAssetsFile)' == '' ">C:\Users\shade\Documents\GitHub\s7netplus\S7.Net.Core\project.lock.json</ProjectAssetsFile>
<NuGetPackageRoot Condition=" '$(NuGetPackageRoot)' == '' ">$(UserProfile)\.nuget\packages\</NuGetPackageRoot>
<NuGetPackageFolders Condition=" '$(NuGetPackageFolders)' == '' ">C:\Users\shade\.nuget\packages\</NuGetPackageFolders>
<NuGetProjectStyle Condition=" '$(NuGetProjectStyle)' == '' ">ProjectJson</NuGetProjectStyle>
<NuGetToolVersion Condition=" '$(NuGetToolVersion)' == '' ">4.3.1</NuGetToolVersion>
</PropertyGroup>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.0\build\Microsoft.Net.Native.Compiler.props" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.0\build\Microsoft.Net.Native.Compiler.props')" />
</ImportGroup>
</Project>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8" standalone="no"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
<Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x86\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x86.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-x64\1.7.0\build\Microsoft.Net.Native.SharedLibrary-x64.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.sharedlibrary-arm\1.7.0\build\Microsoft.Net.Native.SharedLibrary-arm.targets')" />
<Import Project="$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.0\build\Microsoft.Net.Native.Compiler.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.net.native.compiler\1.7.0\build\Microsoft.Net.Native.Compiler.targets')" />
</ImportGroup>
</Project>

View File

@@ -1,481 +0,0 @@
using System;
using System.Net.Sockets;
using System.Threading;
using System.Net;
namespace S7.Net
{
/// <summary>
/// This class encapsulate System.Net.Sockets.Socket class of .Net core, so we can use the same methods of the standard Socket class inside the S7.Net sources.
/// </summary>
internal class Socket
{
public bool Connected
{
get
{
if (_socket == null)
return false;
return _socket.Connected;
}
}
public SocketError LastSocketError { get; private set; }
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType)
{
_socket = new System.Net.Sockets.Socket(addressFamily, socketType, protocolType);
}
public void Connect(IPEndPoint server)
{
if (Connected)
return;
LastSocketError = SocketError.NotConnected;
var socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = server;
var completedEvent = new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
{
LastSocketError = e.SocketError;
_clientDone.Set();
});
socketEventArg.Completed += completedEvent;
_clientDone.Reset();
LastSocketError = SocketError.TimedOut;
_socket.ConnectAsync(socketEventArg);
_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
socketEventArg.Completed -= completedEvent;
}
public int Send(byte[] buffer, int size, SocketFlags socketFlag)
{
var response = 0;
if (_socket != null)
{
var socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.UserToken = null;
var completedEvent = new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
{
LastSocketError = e.SocketError;
if (e.SocketError == SocketError.Success)
response = e.BytesTransferred;
_clientDone.Set();
});
socketEventArg.Completed += completedEvent;
socketEventArg.SetBuffer(buffer, 0, size);
_clientDone.Reset();
LastSocketError = SocketError.TimedOut;
_socket.SendAsync(socketEventArg);
_clientDone.WaitOne(_sendTimeout);
socketEventArg.Completed -= completedEvent;
}
else
{
LastSocketError = SocketError.NotInitialized;
}
return response;
}
public int Receive(byte[] buffer, int size, SocketFlags socketFlag)
{
var response = 0;
if (_socket != null)
{
var socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint;
socketEventArg.SetBuffer(buffer, 0, size);
var completedEvent = new EventHandler<SocketAsyncEventArgs>(delegate (object s, SocketAsyncEventArgs e)
{
LastSocketError = e.SocketError;
if (e.SocketError == SocketError.Success)
response = e.BytesTransferred;
_clientDone.Set();
});
socketEventArg.Completed += completedEvent;
_clientDone.Reset();
LastSocketError = SocketError.TimedOut;
_socket.ReceiveAsync(socketEventArg);
_clientDone.WaitOne(_receiveTimeout);
socketEventArg.Completed -= completedEvent;
}
else
{
LastSocketError = SocketError.NotInitialized;
}
return response;
}
public void Shutdown(SocketShutdown how)
{
_socket.Shutdown(how);
}
public void Close()
{
if (_socket != null)
{
_socket.Dispose();
_socket = null;
}
}
//
// Summary:
// Sets the specified System.Net.Sockets.Socket option to the specified integer
// value.
//
// Parameters:
// optionLevel:
// One of the System.Net.Sockets.SocketOptionLevel values.
//
// optionName:
// One of the System.Net.Sockets.SocketOptionName values.
//
// optionValue:
// A value of the option.
//
// Exceptions:
// T:System.Net.Sockets.SocketException:
// An error occurred when attempting to access the socket. See the Remarks section
// for more information.
//
// T:System.ObjectDisposedException:
// The System.Net.Sockets.Socket has been closed.
public void SetSocketOption(SocketOptionLevel optionLevel, SocketOptionName optionName, int optionValue)
{
switch (optionName)
{
case SocketOptionName.ReceiveTimeout:
_receiveTimeout = optionValue;
break;
case SocketOptionName.SendTimeout:
_sendTimeout = optionValue;
break;
default:
throw new NotImplementedException("SetSocketOption option not implemented");
}
}
private System.Net.Sockets.Socket _socket = null;
private int _receiveTimeout = TIMEOUT_MILLISECONDS;
private int _sendTimeout = TIMEOUT_MILLISECONDS;
private readonly static ManualResetEvent _clientDone =
new ManualResetEvent(false);
private const int TIMEOUT_MILLISECONDS = 1000;
}
//
// Summary:
// Specifies socket send and receive behaviors.
[Flags]
public enum SocketFlags
{
//
// Summary:
// Use no flags for this call.
None = 0,
////
//// Summary:
//// Process out-of-band data.
//OutOfBand = 1,
////
//// Summary:
//// Peek at the incoming message.
//Peek = 2,
////
//// Summary:
//// Send without using routing tables.
//DontRoute = 4,
////
//// Summary:
//// Provides a standard value for the number of WSABUF structures that are used to
//// send and receive data.
//MaxIOVectorLength = 16,
////
//// Summary:
//// The message was too large to fit into the specified buffer and was truncated.
//Truncated = 256,
////
//// Summary:
//// Indicates that the control data did not fit into an internal 64-KB buffer and
//// was truncated.
//ControlDataTruncated = 512,
////
//// Summary:
//// Indicates a broadcast packet.
//Broadcast = 1024,
////
//// Summary:
//// Indicates a multicast packet.
//Multicast = 2048,
////
//// Summary:
//// Partial send or receive for message.
//Partial = 32768
}
//
// Summary:
// Defines socket option levels for the System.Net.Sockets.Socket.SetSocketOption(System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName,System.Int32)
// and System.Net.Sockets.Socket.GetSocketOption(System.Net.Sockets.SocketOptionLevel,System.Net.Sockets.SocketOptionName)
// methods.
public enum SocketOptionLevel
{
//
// Summary:
// System.Net.Sockets.Socket options apply only to IP sockets.
IP = 0,
//
// Summary:
// System.Net.Sockets.Socket options apply only to TCP sockets.
Tcp = 6,
//
// Summary:
// System.Net.Sockets.Socket options apply only to UDP sockets.
Udp = 17,
//
// Summary:
// System.Net.Sockets.Socket options apply only to IPv6 sockets.
IPv6 = 41,
//
// Summary:
// System.Net.Sockets.Socket options apply to all sockets.
Socket = 65535
}
//
// Summary:
// Defines configuration option names.
public enum SocketOptionName
{
//
// Summary:
// Close the socket gracefully without lingering.
DontLinger = -129,
//
// Summary:
// Enables a socket to be bound for exclusive access.
ExclusiveAddressUse = -5,
//
// Summary:
// Record debugging information.
Debug = 1,
//
// Summary:
// Specifies the IP options to be inserted into outgoing datagrams.
IPOptions = 1,
//
// Summary:
// Disables the Nagle algorithm for send coalescing.
NoDelay = 1,
//
// Summary:
// Send UDP datagrams with checksum set to zero.
NoChecksum = 1,
//
// Summary:
// The socket is listening.
AcceptConnection = 2,
//
// Summary:
// Indicates that the application provides the IP header for outgoing datagrams.
HeaderIncluded = 2,
//
// Summary:
// Use urgent data as defined in RFC-1222. This option can be set only once; after
// it is set, it cannot be turned off.
BsdUrgent = 2,
//
// Summary:
// Use expedited data as defined in RFC-1222. This option can be set only once;
// after it is set, it cannot be turned off.
Expedited = 2,
//
// Summary:
// Change the IP header type of the service field.
TypeOfService = 3,
//
// Summary:
// Allows the socket to be bound to an address that is already in use.
ReuseAddress = 4,
//
// Summary:
// Set the IP header Time-to-Live field.
IpTimeToLive = 4,
//
// Summary:
// Use keep-alives.
KeepAlive = 8,
//
// Summary:
// Set the interface for outgoing multicast packets.
MulticastInterface = 9,
//
// Summary:
// An IP multicast Time to Live.
MulticastTimeToLive = 10,
//
// Summary:
// An IP multicast loopback.
MulticastLoopback = 11,
//
// Summary:
// Add an IP group membership.
AddMembership = 12,
//
// Summary:
// Drop an IP group membership.
DropMembership = 13,
//
// Summary:
// Do not fragment IP datagrams.
DontFragment = 14,
//
// Summary:
// Join a source group.
AddSourceMembership = 15,
//
// Summary:
// Do not route; send the packet directly to the interface addresses.
DontRoute = 16,
//
// Summary:
// Drop a source group.
DropSourceMembership = 16,
//
// Summary:
// Block data from a source.
BlockSource = 17,
//
// Summary:
// Unblock a previously blocked source.
UnblockSource = 18,
//
// Summary:
// Return information about received packets.
PacketInformation = 19,
//
// Summary:
// Set or get the UDP checksum coverage.
ChecksumCoverage = 20,
//
// Summary:
// Specifies the maximum number of router hops for an Internet Protocol version
// 6 (IPv6) packet. This is similar to Time to Live (TTL) for Internet Protocol
// version 4.
HopLimit = 21,
//
// Summary:
// Permit sending broadcast messages on the socket.
Broadcast = 32,
//
// Summary:
// Bypass hardware when possible.
UseLoopback = 64,
//
// Summary:
// Linger on close if unsent data is present.
Linger = 128,
//
// Summary:
// Receives out-of-band data in the normal data stream.
OutOfBandInline = 256,
//
// Summary:
// Specifies the total per-socket buffer space reserved for sends. This is unrelated
// to the maximum message size or the size of a TCP window.
SendBuffer = 4097,
//
// Summary:
// Specifies the total per-socket buffer space reserved for receives. This is unrelated
// to the maximum message size or the size of a TCP window.
ReceiveBuffer = 4098,
//
// Summary:
// Specifies the low water mark for Overload:System.Net.Sockets.Socket.Send operations.
SendLowWater = 4099,
//
// Summary:
// Specifies the low water mark for Overload:System.Net.Sockets.Socket.Receive operations.
ReceiveLowWater = 4100,
//
// Summary:
// Send a time-out. This option applies only to synchronous methods; it has no effect
// on asynchronous methods such as the System.Net.Sockets.Socket.BeginSend(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.AsyncCallback,System.Object)
// method.
SendTimeout = 4101,
//
// Summary:
// Receive a time-out. This option applies only to synchronous methods; it has no
// effect on asynchronous methods such as the System.Net.Sockets.Socket.BeginSend(System.Byte[],System.Int32,System.Int32,System.Net.Sockets.SocketFlags,System.AsyncCallback,System.Object)
// method.
ReceiveTimeout = 4102,
//
// Summary:
// Get the error status and clear.
Error = 4103,
//
// Summary:
// Get the socket type.
Type = 4104,
//
// Summary:
// Updates an accepted socket's properties by using those of an existing socket.
// This is equivalent to using the Winsock2 SO_UPDATE_ACCEPT_CONTEXT socket option
// and is supported only on connection-oriented sockets.
UpdateAcceptContext = 28683,
//
// Summary:
// Updates a connected socket's properties by using those of an existing socket.
// This is equivalent to using the Winsock2 SO_UPDATE_CONNECT_CONTEXT socket option
// and is supported only on connection-oriented sockets.
UpdateConnectContext = 28688,
//
// Summary:
// Not supported; will throw a System.Net.Sockets.SocketException if used.
MaxConnections = int.MaxValue
}
}

View File

@@ -1,16 +0,0 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.4.0"
},
"frameworks": {
"uap10.0.10240": {}
},
"runtimes": {
"win10-arm": {},
"win10-arm-aot": {},
"win10-x86": {},
"win10-x86-aot": {},
"win10-x64": {},
"win10-x64-aot": {}
}
}

View File

@@ -1,6 +1,5 @@
using System;
using System.IO;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Linq;
@@ -98,15 +97,20 @@ namespace S7.Net
var segment = TPDU.Read(stream);
if (segment == null) return null;
var output = new MemoryStream(segment.Data.Length);
var buffer = new byte[segment.Data.Length];
var output = new MemoryStream(buffer);
output.Write(segment.Data, 0, segment.Data.Length);
while (!segment.LastDataUnit)
{
segment = TPDU.Read(stream);
output.Write(segment.Data, (int)output.Position, segment.Data.Length);
Array.Resize(ref buffer, buffer.Length + segment.Data.Length);
var lastPosition = output.Position;
output = new MemoryStream(buffer);
output.Write(segment.Data, (int) lastPosition, segment.Data.Length);
}
return output.GetBuffer().Take((int)output.Position).ToArray();
return buffer.Take((int)output.Position).ToArray();
}
/// <summary>
@@ -120,15 +124,19 @@ namespace S7.Net
var segment = await TPDU.ReadAsync(stream);
if (segment == null) return null;
var output = new MemoryStream(segment.Data.Length);
var buffer = new byte[segment.Data.Length];
var output = new MemoryStream(buffer);
output.Write(segment.Data, 0, segment.Data.Length);
while (!segment.LastDataUnit)
{
segment = await TPDU.ReadAsync(stream);
output.Write(segment.Data, (int)output.Position, segment.Data.Length);
Array.Resize(ref buffer, buffer.Length + segment.Data.Length);
var lastPosition = output.Position;
output = new MemoryStream(buffer);
output.Write(segment.Data, (int) lastPosition, segment.Data.Length);
}
return output.GetBuffer().Take((int)output.Position).ToArray();
return buffer.Take((int)output.Position).ToArray();
}
}
}

View File

@@ -0,0 +1,19 @@
using System.Net.Sockets;
namespace S7.Net
{
public static class TcpClientMixins
{
#if NETSTANDARD1_3
public static void Close(this TcpClient tcpClient)
{
tcpClient.Dispose();
}
public static void Connect(this TcpClient tcpClient, string host, int port)
{
tcpClient.ConnectAsync(host, port).GetAwaiter().GetResult();
}
#endif
}
}

View File

@@ -1,11 +1,5 @@
using S7.Net.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace S7.Net
@@ -103,7 +97,7 @@ namespace S7.Net
public Plc(CpuType cpu, string ip, Int16 rack, Int16 slot)
{
if (!Enum.IsDefined(typeof(CpuType), cpu))
throw new InvalidEnumArgumentException(nameof(cpu), (int) cpu, typeof(CpuType));
throw new ArgumentException($"The value of argument '{nameof(cpu)}' ({cpu}) is invalid for Enum type '{typeof(CpuType).Name}'.", nameof(cpu));
if (string.IsNullOrEmpty(ip))
throw new ArgumentException("IP address must valid.", nameof(ip));

View File

@@ -1,9 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
#if NET_FULL
using System.Runtime.Serialization;
#endif
namespace S7.Net
{
@@ -21,9 +20,11 @@ namespace S7.Net
{
}
#if NET_FULL
protected WrongNumberOfBytesException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#endif
}
internal class InvalidAddressException : Exception
@@ -40,9 +41,11 @@ namespace S7.Net
{
}
#if NET_FULL
protected InvalidAddressException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#endif
}
internal class InvalidVariableTypeException : Exception
@@ -59,9 +62,11 @@ namespace S7.Net
{
}
#if NET_FULL
protected InvalidVariableTypeException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#endif
}
internal class TPKTInvalidException : Exception
@@ -78,8 +83,10 @@ namespace S7.Net
{
}
#if NET_FULL
protected TPKTInvalidException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
#endif
}
}

View File

@@ -1,11 +1,7 @@
using S7.Net.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace S7.Net
{

View File

@@ -1,8 +1,6 @@
using S7.Net.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;

View File

@@ -1,11 +1,8 @@
using S7.Net.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Threading.Tasks;
using S7.Net.Protocol;
//Implement synchronous methods here

View File

@@ -1,11 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net452;netstandard2.0;netstandard1.3</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Properties\S7.Net.snk</AssemblyOriginatorKeyFile>
<InternalsVisibleTo>S7.Net.UnitTest</InternalsVisibleTo>
</PropertyGroup>
<PropertyGroup Condition="'$(TargetFramework)' == 'net452' Or '$(TargetFramework)' == 'netstandard2.0' ">
<DefineConstants>NET_FULL</DefineConstants>
</PropertyGroup>
</Project>

View File

@@ -1,5 +1,4 @@
using System;
using System.Net.Sockets;
using System.IO;
using System.Threading.Tasks;

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections;
namespace S7.Net.Types
{

View File

@@ -1,6 +1,4 @@
using System;
namespace S7.Net.Types
namespace S7.Net.Types
{
/// <summary>
/// Contains the methods to read, set and reset bits inside bytes

View File

@@ -13,8 +13,8 @@ namespace S7.Net.Types
private static IEnumerable<PropertyInfo> GetAccessableProperties(Type classType)
{
return classType
#if NETFX_CORE
.GetProperties().Where(p => p.GetSetMethod() != null);
#if NETSTANDARD1_3
.GetTypeInfo().DeclaredProperties.Where(p => p.SetMethod != null);
#else
.GetProperties(
BindingFlags.SetProperty |

View File

@@ -1,6 +1,4 @@
using System;
using System.Linq;
using System.Globalization;
using System.Reflection;
namespace S7.Net.Types
@@ -19,8 +17,14 @@ namespace S7.Net.Types
{
double numBytes = 0.0;
System.Reflection.FieldInfo[] infos = structType.GetFields();
foreach (System.Reflection.FieldInfo info in infos)
var infos = structType
#if NETSTANDARD1_3
.GetTypeInfo().DeclaredFields;
#else
.GetFields();
#endif
foreach (var info in infos)
{
switch (info.FieldType.Name)
{
@@ -80,8 +84,15 @@ namespace S7.Net.Types
double numBytes = 0.0;
object structValue = Activator.CreateInstance(structType);
System.Reflection.FieldInfo[] infos = structValue.GetType().GetFields();
foreach (System.Reflection.FieldInfo info in infos)
var infos = structValue.GetType()
#if NETSTANDARD1_3
.GetTypeInfo().DeclaredFields;
#else
.GetFields();
#endif
foreach (var info in infos)
{
switch (info.FieldType.Name)
{
@@ -182,8 +193,14 @@ namespace S7.Net.Types
int bitPos = 0;
double numBytes = 0.0;
System.Reflection.FieldInfo[] infos = type.GetFields();
foreach (System.Reflection.FieldInfo info in infos)
var infos = type
#if NETSTANDARD1_3
.GetTypeInfo().DeclaredFields;
#else
.GetFields();
#endif
foreach (var info in infos)
{
bytes2 = null;
switch (info.FieldType.Name)

View File

@@ -1,45 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7A8252C3-E6AE-435A-809D-4413C06E0711}"
ProjectSection(SolutionItems) = preProject
README.md = README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S7.Net.Core", "S7.Net.Core\S7.Net.Core.csproj", "{CBFF80E8-3D3D-4656-A27C-A65EA5774536}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|ARM.ActiveCfg = Debug|ARM
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|ARM.Build.0 = Debug|ARM
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x64.ActiveCfg = Debug|x64
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x64.Build.0 = Debug|x64
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x86.ActiveCfg = Debug|x86
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Debug|x86.Build.0 = Debug|x86
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|Any CPU.Build.0 = Release|Any CPU
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|ARM.ActiveCfg = Release|ARM
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|ARM.Build.0 = Release|ARM
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x64.ActiveCfg = Release|x64
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x64.Build.0 = Release|x64
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x86.ActiveCfg = Release|x86
{CBFF80E8-3D3D-4656-A27C-A65EA5774536}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

2
S7.sln
View File

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2026
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "S7.Net", "S7.Net\S7.Net.csproj", "{BFD484F9-3F04-42A2-BF2A-60A189A25DCF}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "S7.Net", "S7.Net\S7.Net.csproj", "{BFD484F9-3F04-42A2-BF2A-60A189A25DCF}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7A8252C3-E6AE-435A-809D-4413C06E0711}"
ProjectSection(SolutionItems) = preProject