生成单文件
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
using HandyControl.Collections;
|
||||
using System;
|
||||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using 电子展板.Utility.Extension;
|
||||
|
||||
namespace 电子展板
|
||||
{
|
||||
@@ -13,7 +16,8 @@ namespace 电子展板
|
||||
{
|
||||
public App()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
30
电子展板/Assets/InitConfig.json
Normal file
30
电子展板/Assets/InitConfig.json
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +1,5 @@
|
||||
using Nancy.Hosting.Self;
|
||||
//using Nancy;
|
||||
//using Nancy.Hosting.Self;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
@@ -13,7 +14,7 @@ namespace 电子展板.Base
|
||||
{
|
||||
public class GlobalVariable
|
||||
{
|
||||
public static NancyHost WebServer;
|
||||
//public static NancyHost WebServer;
|
||||
|
||||
private static MyConfig _config;
|
||||
/// <summary>
|
||||
@@ -24,7 +25,38 @@ namespace 电子展板.Base
|
||||
get
|
||||
{
|
||||
if (_config == null)
|
||||
_config = File.ReadAllText(MyEnvironment.Root("/Configs/Config.json")).ToObject<MyConfig>();
|
||||
{
|
||||
try
|
||||
{
|
||||
_config = File.ReadAllText(MyEnvironment.Root("/Config.json"), Encoding.UTF8).ToObject<MyConfig>();
|
||||
//删除缓存没用到的图片
|
||||
List<string> list = new List<string>
|
||||
{
|
||||
_config.CPCMember1Path,
|
||||
_config.CPCMember2Path,
|
||||
_config.CPCMember3Path,
|
||||
_config.CPCMember4Path
|
||||
};
|
||||
list = list.Where(it => !it.IsNullOrEmpty()).Select(it => it.Replace("/upload/", "")).ToList();
|
||||
if (_config.FileUploadList == null)
|
||||
_config.FileUploadList = new List<UploadFiles>();
|
||||
_config.FileUploadList = _config.FileUploadList.Where(it => list.Contains(it.Name)).ToList();
|
||||
File.WriteAllText(MyEnvironment.Root("/Config.json"), _config.ToJson(), Encoding.UTF8);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
string packUri = $"pack://application:,,,/Assets/InitConfig.json";
|
||||
string json = "";
|
||||
using (Stream stream = System.Windows.Application.GetResourceStream(new Uri(packUri, UriKind.RelativeOrAbsolute)).Stream)
|
||||
{
|
||||
using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
|
||||
{
|
||||
json = new StreamReader(stream, Encoding.UTF8).ReadToEnd();
|
||||
}
|
||||
}
|
||||
_config = json.ToObject<MyConfig>();
|
||||
}
|
||||
}
|
||||
return _config;
|
||||
}
|
||||
set
|
||||
@@ -35,7 +67,7 @@ namespace 电子展板.Base
|
||||
|
||||
public static void SaveConfig()
|
||||
{
|
||||
File.WriteAllText(MyEnvironment.Root("/Configs/Config.json"), Config.ToJson());
|
||||
File.WriteAllText(MyEnvironment.Root("/Config.json"), Config.ToJson(), Encoding.UTF8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<PropertyChanged />
|
||||
<!--<Costura />-->
|
||||
<PropertyChanged />
|
||||
<Costura />
|
||||
</Weavers>
|
||||
@@ -53,6 +53,157 @@
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX86Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinX64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="UnmanagedWinArm64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeReferences" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls if runtime assemblies are also embedded.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UseRuntimeReferencePaths" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Controls whether the runtime assemblies are embedded with their full path or only with their assembly name.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCompression" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableCleanup" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="DisableEventSubscription" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The attach method no longer subscribes to the `AppDomain.AssemblyResolve` (.NET 4.x) and `AssemblyLoadContext.Resolving` (.NET 6.0+) events.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="ExcludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="IncludeRuntimeAssemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of runtime assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX86Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinX86Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X86 (32 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>Obsolete, use UnmanagedWinX64Assemblies instead</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinX64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged X64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="UnmanagedWinArm64Assemblies" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>A list of unmanaged Arm64 (64 bit) assembly names to include, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
<xs:attribute name="PreloadOrder" type="xs:string">
|
||||
<xs:annotation>
|
||||
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
|
||||
</xs:annotation>
|
||||
</xs:attribute>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||
<xs:annotation>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Nancy.Swagger.Annotations.Attributes;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Documents;
|
||||
using 电子展板.Base;
|
||||
|
||||
namespace 电子展板.Models
|
||||
@@ -118,51 +120,8 @@ namespace 电子展板.Models
|
||||
[Comment("党员字体大小")]
|
||||
[ModelProperty(Description = "党员字体大小", Required = true, Minimum = 15, Maximum = 60)]
|
||||
public int CPCMemberSize { get; set; }
|
||||
/// <summary>
|
||||
/// 转换成JSON字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
//public string ToJson()
|
||||
//{
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// sb.AppendLine("{");
|
||||
// //得到所有的Property
|
||||
// var properties = GetType().GetProperties();
|
||||
// for (int i = 0; i < properties.Length; i++)
|
||||
// {
|
||||
// var property = properties[i];
|
||||
// string endChar = ",";
|
||||
// if (i == properties.Length - 1)
|
||||
// {
|
||||
// endChar = "";
|
||||
// }
|
||||
// var comment = property.GetCustomAttributes(typeof(CommentAttribute), false).FirstOrDefault() as CommentAttribute;
|
||||
// string commentText = "";
|
||||
// if (comment != null)
|
||||
// {
|
||||
// commentText = $" /* {comment.Comment} */";
|
||||
// }
|
||||
// string propertyName = property.Name;
|
||||
// var value = property.GetValue(this, null);
|
||||
// if (value != null)
|
||||
// {
|
||||
// var valueType = value.GetType();
|
||||
// if (valueType == typeof(string))
|
||||
// {
|
||||
// string value1 = (string)value;
|
||||
// value1 = value1.Replace("\"", "\\\"");
|
||||
// value1 = value1.Replace("\r\n", "\\r\\n");
|
||||
// sb.AppendLine($" \"{propertyName}\":\"{value1}\"{endChar}{commentText}");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// sb.AppendLine($" \"{propertyName}\":{value}{endChar}{commentText}");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// sb.AppendLine("}");
|
||||
// return sb.ToString();
|
||||
//}
|
||||
|
||||
public List<UploadFiles> FileUploadList { get; set; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
14
电子展板/Models/UploadFiles.cs
Normal file
14
电子展板/Models/UploadFiles.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace 电子展板.Models
|
||||
{
|
||||
public class UploadFiles
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public byte[] Bin { get; set; }
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
928
电子展板/Utility/ByteArrayStream.cs
Normal file
928
电子展板/Utility/ByteArrayStream.cs
Normal file
@@ -0,0 +1,928 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace 电子展板.Utility
|
||||
{
|
||||
public class ByteArrayStream : Stream
|
||||
{
|
||||
private byte[] _buffer;
|
||||
private int _position;
|
||||
private int _length;
|
||||
private int _capacity;
|
||||
private Encoding _defaultEncoding = Encoding.UTF8;
|
||||
|
||||
// 默认编码方式(用于字符串读写)
|
||||
public Encoding DefaultEncoding
|
||||
{
|
||||
get => _defaultEncoding;
|
||||
set => _defaultEncoding = value ?? throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
// 构造函数:创建指定初始容量的流
|
||||
public ByteArrayStream(int initialCapacity = 4096)
|
||||
{
|
||||
if (initialCapacity < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(initialCapacity));
|
||||
|
||||
_capacity = initialCapacity;
|
||||
_buffer = new byte[initialCapacity];
|
||||
_position = 0;
|
||||
_length = 0;
|
||||
}
|
||||
|
||||
// 构造函数:从现有字节数组创建流
|
||||
public ByteArrayStream(byte[] buffer)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException(nameof(buffer));
|
||||
|
||||
_buffer = buffer;
|
||||
_capacity = buffer.Length;
|
||||
_length = buffer.Length;
|
||||
_position = 0;
|
||||
}
|
||||
|
||||
// 指示当前流是否支持读取
|
||||
public override bool CanRead => true;
|
||||
|
||||
// 指示当前流是否支持查找
|
||||
public override bool CanSeek => true;
|
||||
|
||||
// 指示当前流是否支持写入
|
||||
public override bool CanWrite => true;
|
||||
|
||||
// 获取流的长度
|
||||
public override long Length => _length;
|
||||
|
||||
// 获取或设置当前流中的位置
|
||||
public override long Position
|
||||
{
|
||||
get => _position;
|
||||
set
|
||||
{
|
||||
if (value < 0 || value > _length)
|
||||
throw new ArgumentOutOfRangeException(nameof(value));
|
||||
_position = (int)value;
|
||||
}
|
||||
}
|
||||
|
||||
// 确保有足够的容量
|
||||
private void EnsureCapacity(int required)
|
||||
{
|
||||
if (required <= _capacity) return;
|
||||
|
||||
// 每次扩容为当前容量的2倍或所需容量(取较大值)
|
||||
int newCapacity = Math.Max(_capacity * 2, required);
|
||||
byte[] newBuffer = new byte[newCapacity];
|
||||
Array.Copy(_buffer, newBuffer, _length);
|
||||
_buffer = newBuffer;
|
||||
_capacity = newCapacity;
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
// 内存流无需实际刷新
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException(nameof(buffer));
|
||||
if (offset < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(offset));
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(count));
|
||||
if (offset + count > buffer.Length)
|
||||
throw new ArgumentException("偏移量和计数的总和超过缓冲区长度");
|
||||
|
||||
int bytesToRead = Math.Min(count, _length - _position);
|
||||
if (bytesToRead > 0)
|
||||
{
|
||||
Array.Copy(_buffer, _position, buffer, offset, bytesToRead);
|
||||
_position += bytesToRead;
|
||||
}
|
||||
return bytesToRead;
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
long newPosition;
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
newPosition = offset;
|
||||
break;
|
||||
case SeekOrigin.Current:
|
||||
newPosition = _position + offset;
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
newPosition = _length + offset;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(origin));
|
||||
}
|
||||
|
||||
if (newPosition < 0 || newPosition > _length)
|
||||
throw new IOException("seek 位置无效");
|
||||
|
||||
_position = (int)newPosition;
|
||||
return _position;
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
if (value < 0 || value > int.MaxValue)
|
||||
throw new ArgumentOutOfRangeException(nameof(value));
|
||||
|
||||
int newLength = (int)value;
|
||||
EnsureCapacity(newLength);
|
||||
_length = newLength;
|
||||
|
||||
if (_position > newLength)
|
||||
_position = newLength;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
if (buffer == null)
|
||||
throw new ArgumentNullException(nameof(buffer));
|
||||
if (offset < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(offset));
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(count));
|
||||
if (offset + count > buffer.Length)
|
||||
throw new ArgumentException("偏移量和计数的总和超过缓冲区长度");
|
||||
|
||||
if (count == 0) return;
|
||||
|
||||
int newPosition = _position + count;
|
||||
if (newPosition > _length)
|
||||
{
|
||||
EnsureCapacity(newPosition);
|
||||
_length = newPosition;
|
||||
}
|
||||
|
||||
Array.Copy(buffer, offset, _buffer, _position, count);
|
||||
_position = newPosition;
|
||||
}
|
||||
|
||||
#region 基础数据类型读写方法 - 完整实现
|
||||
|
||||
/// <summary>
|
||||
/// 读取一个字节
|
||||
/// </summary>
|
||||
public new byte ReadByte()
|
||||
{
|
||||
if (_position >= _length)
|
||||
throw new EndOfStreamException("已到达流的末尾");
|
||||
|
||||
return _buffer[_position++];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入一个字节
|
||||
/// </summary>
|
||||
public new void WriteByte(byte value)
|
||||
{
|
||||
EnsureCapacity(_position + 1);
|
||||
|
||||
if (_position == _length)
|
||||
_length++;
|
||||
|
||||
_buffer[_position++] = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取16位有符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public short ReadInt16()
|
||||
{
|
||||
return ReadInt16(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取16位有符号整数
|
||||
/// </summary>
|
||||
public short ReadInt16(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(2);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToInt16(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入16位有符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteInt16(short value)
|
||||
{
|
||||
WriteInt16(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入16位有符号整数
|
||||
/// </summary>
|
||||
public void WriteInt16(short value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取16位无符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public ushort ReadUInt16()
|
||||
{
|
||||
return ReadUInt16(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取16位无符号整数
|
||||
/// </summary>
|
||||
public ushort ReadUInt16(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(2);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToUInt16(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入16位无符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteUInt16(ushort value)
|
||||
{
|
||||
WriteUInt16(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入16位无符号整数
|
||||
/// </summary>
|
||||
public void WriteUInt16(ushort value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取32位有符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public int ReadInt32()
|
||||
{
|
||||
return ReadInt32(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取32位有符号整数
|
||||
/// </summary>
|
||||
public int ReadInt32(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(4);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToInt32(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入32位有符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteInt32(int value)
|
||||
{
|
||||
WriteInt32(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入32位有符号整数
|
||||
/// </summary>
|
||||
public void WriteInt32(int value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取32位无符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
return ReadUInt32(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取32位无符号整数
|
||||
/// </summary>
|
||||
public uint ReadUInt32(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(4);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToUInt32(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入32位无符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteUInt32(uint value)
|
||||
{
|
||||
WriteUInt32(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入32位无符号整数
|
||||
/// </summary>
|
||||
public void WriteUInt32(uint value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取64位有符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public long ReadInt64()
|
||||
{
|
||||
return ReadInt64(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取64位有符号整数
|
||||
/// </summary>
|
||||
public long ReadInt64(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(8);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入64位有符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteInt64(long value)
|
||||
{
|
||||
WriteInt64(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入64位有符号整数
|
||||
/// </summary>
|
||||
public void WriteInt64(long value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取64位无符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public ulong ReadUInt64()
|
||||
{
|
||||
return ReadUInt64(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取64位无符号整数
|
||||
/// </summary>
|
||||
public ulong ReadUInt64(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(8);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToUInt64(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入64位无符号整数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteUInt64(ulong value)
|
||||
{
|
||||
WriteUInt64(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入64位无符号整数
|
||||
/// </summary>
|
||||
public void WriteUInt64(ulong value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取单精度浮点数(小端字节序)
|
||||
/// </summary>
|
||||
public float ReadFloat()
|
||||
{
|
||||
return ReadFloat(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取单精度浮点数
|
||||
/// </summary>
|
||||
public float ReadFloat(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(4);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToSingle(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入单精度浮点数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteFloat(float value)
|
||||
{
|
||||
WriteFloat(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入单精度浮点数
|
||||
/// </summary>
|
||||
public void WriteFloat(float value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取双精度浮点数(小端字节序)
|
||||
/// </summary>
|
||||
public double ReadDouble()
|
||||
{
|
||||
return ReadDouble(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取双精度浮点数
|
||||
/// </summary>
|
||||
public double ReadDouble(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(8);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToDouble(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入双精度浮点数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteDouble(double value)
|
||||
{
|
||||
WriteDouble(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入双精度浮点数
|
||||
/// </summary>
|
||||
public void WriteDouble(double value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取布尔值(1字节,0表示false,非0表示true)
|
||||
/// </summary>
|
||||
public bool ReadBoolean()
|
||||
{
|
||||
return ReadByte() != 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入布尔值(1字节,0表示false,1表示true)
|
||||
/// </summary>
|
||||
public void WriteBoolean(bool value)
|
||||
{
|
||||
WriteByte(value ? (byte)1 : (byte)0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取字符(小端字节序)
|
||||
/// </summary>
|
||||
public char ReadChar()
|
||||
{
|
||||
return ReadChar(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取字符
|
||||
/// </summary>
|
||||
public char ReadChar(Endianness endianness)
|
||||
{
|
||||
byte[] bytes = ReadBytes(2);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
return BitConverter.ToChar(bytes, 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入字符(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteChar(char value)
|
||||
{
|
||||
WriteChar(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入字符
|
||||
/// </summary>
|
||||
public void WriteChar(char value, Endianness endianness)
|
||||
{
|
||||
byte[] bytes = BitConverter.GetBytes(value);
|
||||
if (NeedReverse(endianness))
|
||||
Array.Reverse(bytes);
|
||||
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取十进制数(小端字节序)
|
||||
/// </summary>
|
||||
public decimal ReadDecimal()
|
||||
{
|
||||
return ReadDecimal(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取十进制数
|
||||
/// </summary>
|
||||
public decimal ReadDecimal(Endianness endianness)
|
||||
{
|
||||
int[] bits = new int[4];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
bits[i] = ReadInt32(endianness);
|
||||
}
|
||||
return new decimal(bits);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入十进制数(小端字节序)
|
||||
/// </summary>
|
||||
public void WriteDecimal(decimal value)
|
||||
{
|
||||
WriteDecimal(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入十进制数
|
||||
/// </summary>
|
||||
public void WriteDecimal(decimal value, Endianness endianness)
|
||||
{
|
||||
int[] bits = decimal.GetBits(value);
|
||||
foreach (int bit in bits)
|
||||
{
|
||||
WriteInt32(bit, endianness);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取指定长度的字节数组
|
||||
/// </summary>
|
||||
public byte[] ReadBytes(int count)
|
||||
{
|
||||
if (count < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(count));
|
||||
if (_position + count > _length)
|
||||
throw new EndOfStreamException("没有足够的字节可供读取");
|
||||
|
||||
byte[] result = new byte[count];
|
||||
Array.Copy(_buffer, _position, result, 0, count);
|
||||
_position += count;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 字符串读写方法
|
||||
|
||||
/// <summary>
|
||||
/// 读取以null结尾的字符串(C风格字符串)
|
||||
/// </summary>
|
||||
public string ReadNullTerminatedString()
|
||||
{
|
||||
return ReadNullTerminatedString(DefaultEncoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取以null结尾的字符串(C风格字符串)
|
||||
/// </summary>
|
||||
public string ReadNullTerminatedString(Encoding encoding)
|
||||
{
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException(nameof(encoding));
|
||||
|
||||
int startPos = _position;
|
||||
|
||||
// 查找null终止符
|
||||
while (_position < _length && _buffer[_position] != 0)
|
||||
{
|
||||
_position++;
|
||||
}
|
||||
|
||||
int byteCount = _position - startPos;
|
||||
string result = encoding.GetString(_buffer, startPos, byteCount);
|
||||
|
||||
// 跳过null终止符
|
||||
if (_position < _length)
|
||||
{
|
||||
_position++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入以null结尾的字符串(C风格字符串)
|
||||
/// </summary>
|
||||
public void WriteNullTerminatedString(string value)
|
||||
{
|
||||
WriteNullTerminatedString(value, DefaultEncoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入以null结尾的字符串(C风格字符串)
|
||||
/// </summary>
|
||||
public void WriteNullTerminatedString(string value, Encoding encoding)
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException(nameof(encoding));
|
||||
|
||||
byte[] bytes = encoding.GetBytes(value);
|
||||
Write(bytes, 0, bytes.Length);
|
||||
WriteByte(0); // 写入null终止符
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取前缀长度的字符串(先读取长度,再读取内容)
|
||||
/// 使用Int32作为长度前缀
|
||||
/// </summary>
|
||||
public string ReadLengthPrefixedString()
|
||||
{
|
||||
return ReadLengthPrefixedString(DefaultEncoding, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取前缀长度的字符串(先读取长度,再读取内容)
|
||||
/// 使用Int32作为长度前缀
|
||||
/// </summary>
|
||||
public string ReadLengthPrefixedString(Encoding encoding, Endianness endianness)
|
||||
{
|
||||
return ReadLengthPrefixedString<int>(encoding, endianness);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取前缀长度的字符串(先读取长度,再读取内容)
|
||||
/// 支持指定长度类型(Int16, Int32, Int64等)
|
||||
/// </summary>
|
||||
public string ReadLengthPrefixedString<TLength>(Encoding encoding, Endianness endianness)
|
||||
where TLength : struct, IConvertible
|
||||
{
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException(nameof(encoding));
|
||||
|
||||
// 读取长度前缀
|
||||
TLength lengthValue = Read<TLength>(endianness);
|
||||
int length = Convert.ToInt32(lengthValue);
|
||||
|
||||
if (length < 0)
|
||||
throw new IOException("字符串长度不能为负数");
|
||||
|
||||
byte[] bytes = ReadBytes(length);
|
||||
return encoding.GetString(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入前缀长度的字符串(先写入长度,再写入内容)
|
||||
/// 使用Int32作为长度前缀
|
||||
/// </summary>
|
||||
public void WriteLengthPrefixedString(string value)
|
||||
{
|
||||
WriteLengthPrefixedString(value, DefaultEncoding, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入前缀长度的字符串(先写入长度,再写入内容)
|
||||
/// 使用Int32作为长度前缀
|
||||
/// </summary>
|
||||
public void WriteLengthPrefixedString(string value, Encoding encoding, Endianness endianness)
|
||||
{
|
||||
WriteLengthPrefixedString<int>(value, encoding, endianness);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入前缀长度的字符串(先写入长度,再写入内容)
|
||||
/// 支持指定长度类型(Int16, Int32, Int64等)
|
||||
/// </summary>
|
||||
public void WriteLengthPrefixedString<TLength>(string value, Encoding encoding, Endianness endianness)
|
||||
where TLength : struct, IConvertible
|
||||
{
|
||||
if (value == null)
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException(nameof(encoding));
|
||||
|
||||
byte[] bytes = encoding.GetBytes(value);
|
||||
|
||||
// 检查长度是否在指定类型范围内
|
||||
TLength lengthValue = (TLength)Convert.ChangeType(bytes.Length, typeof(TLength));
|
||||
|
||||
// 写入长度前缀和字符串内容
|
||||
Write<TLength>(lengthValue, endianness);
|
||||
Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取固定长度的字符串
|
||||
/// </summary>
|
||||
public string ReadFixedLengthString(int byteCount)
|
||||
{
|
||||
return ReadFixedLengthString(byteCount, DefaultEncoding);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取固定长度的字符串
|
||||
/// </summary>
|
||||
public string ReadFixedLengthString(int byteCount, Encoding encoding)
|
||||
{
|
||||
if (byteCount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(byteCount));
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException(nameof(encoding));
|
||||
|
||||
byte[] bytes = ReadBytes(byteCount);
|
||||
return encoding.GetString(bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入固定长度的字符串,不足则填充,超出则截断
|
||||
/// </summary>
|
||||
public void WriteFixedLengthString(string value, int byteCount)
|
||||
{
|
||||
WriteFixedLengthString(value, byteCount, DefaultEncoding, (byte)0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写入固定长度的字符串,不足则填充,超出则截断
|
||||
/// </summary>
|
||||
public void WriteFixedLengthString(string value, int byteCount, Encoding encoding, byte paddingByte)
|
||||
{
|
||||
if (byteCount < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(byteCount));
|
||||
if (encoding == null)
|
||||
throw new ArgumentNullException(nameof(encoding));
|
||||
if (value == null)
|
||||
value = string.Empty;
|
||||
|
||||
// 获取字符串的字节表示
|
||||
byte[] originalBytes = encoding.GetBytes(value);
|
||||
|
||||
// 创建目标字节数组
|
||||
byte[] targetBytes = new byte[byteCount];
|
||||
|
||||
if (paddingByte != 0)
|
||||
{
|
||||
// // 填充默认值
|
||||
for (int i = 0; i < byteCount; i++)
|
||||
targetBytes[i] = paddingByte;
|
||||
}
|
||||
// 复制字节,超出部分截断
|
||||
int copyLength = Math.Min(originalBytes.Length, byteCount);
|
||||
Array.Copy(originalBytes, targetBytes, copyLength);
|
||||
|
||||
Write(targetBytes, 0, targetBytes.Length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 泛型读写方法
|
||||
|
||||
/// <summary>
|
||||
/// 泛型读取方法(小端字节序)
|
||||
/// </summary>
|
||||
public T Read<T>() where T : struct
|
||||
{
|
||||
return Read<T>(Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型读取方法
|
||||
/// </summary>
|
||||
public T Read<T>(Endianness endianness) where T : struct
|
||||
{
|
||||
Type type = typeof(T);
|
||||
|
||||
if (type == typeof(byte)) return (T)(object)ReadByte();
|
||||
if (type == typeof(short)) return (T)(object)ReadInt16(endianness);
|
||||
if (type == typeof(ushort)) return (T)(object)ReadUInt16(endianness);
|
||||
if (type == typeof(int)) return (T)(object)ReadInt32(endianness);
|
||||
if (type == typeof(uint)) return (T)(object)ReadUInt32(endianness);
|
||||
if (type == typeof(long)) return (T)(object)ReadInt64(endianness);
|
||||
if (type == typeof(ulong)) return (T)(object)ReadUInt64(endianness);
|
||||
if (type == typeof(float)) return (T)(object)ReadFloat(endianness);
|
||||
if (type == typeof(double)) return (T)(object)ReadDouble(endianness);
|
||||
if (type == typeof(bool)) return (T)(object)ReadBoolean();
|
||||
if (type == typeof(char)) return (T)(object)ReadChar(endianness);
|
||||
if (type == typeof(decimal)) return (T)(object)ReadDecimal(endianness);
|
||||
|
||||
throw new NotSupportedException($"不支持的类型: {type.Name}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型写入方法(小端字节序)
|
||||
/// </summary>
|
||||
public void Write<T>(T value) where T : struct
|
||||
{
|
||||
Write(value, Endianness.LittleEndian);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 泛型写入方法
|
||||
/// </summary>
|
||||
public void Write<T>(T value, Endianness endianness) where T : struct
|
||||
{
|
||||
Type type = typeof(T);
|
||||
|
||||
if (type == typeof(byte)) { WriteByte((byte)(object)value); return; }
|
||||
if (type == typeof(short)) { WriteInt16((short)(object)value, endianness); return; }
|
||||
if (type == typeof(ushort)) { WriteUInt16((ushort)(object)value, endianness); return; }
|
||||
if (type == typeof(int)) { WriteInt32((int)(object)value, endianness); return; }
|
||||
if (type == typeof(uint)) { WriteUInt32((uint)(object)value, endianness); return; }
|
||||
if (type == typeof(long)) { WriteInt64((long)(object)value, endianness); return; }
|
||||
if (type == typeof(ulong)) { WriteUInt64((ulong)(object)value, endianness); return; }
|
||||
if (type == typeof(float)) { WriteFloat((float)(object)value, endianness); return; }
|
||||
if (type == typeof(double)) { WriteDouble((double)(object)value, endianness); return; }
|
||||
if (type == typeof(bool)) { WriteBoolean((bool)(object)value); return; }
|
||||
if (type == typeof(char)) { WriteChar((char)(object)value, endianness); return; }
|
||||
if (type == typeof(decimal)) { WriteDecimal((decimal)(object)value, endianness); return; }
|
||||
|
||||
throw new NotSupportedException($"不支持的类型: {type.Name}");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 将流内容转换为字节数组
|
||||
/// </summary>
|
||||
public byte[] ToByteArray()
|
||||
{
|
||||
byte[] result = new byte[_length];
|
||||
Array.Copy(_buffer, result, _length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 辅助方法:判断是否需要反转字节顺序
|
||||
/// </summary>
|
||||
private bool NeedReverse(Endianness endianness)
|
||||
{
|
||||
return (endianness == Endianness.BigEndian && BitConverter.IsLittleEndian) ||
|
||||
(endianness == Endianness.LittleEndian && !BitConverter.IsLittleEndian);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 字节序枚举
|
||||
/// </summary>
|
||||
public enum Endianness
|
||||
{
|
||||
LittleEndian, // 小端字节序
|
||||
BigEndian // 大端字节序
|
||||
}
|
||||
}
|
||||
@@ -1,94 +1,94 @@
|
||||
using NLog;
|
||||
using NLog.Config;
|
||||
//using NLog;
|
||||
//using NLog.Config;
|
||||
using System;
|
||||
using 电子展板.Utility.Extension;
|
||||
|
||||
namespace 电子展板.Utility.Logs
|
||||
{
|
||||
public class LogHelper
|
||||
{
|
||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
//public class LogHelper
|
||||
//{
|
||||
// private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static LogHelper _obj;
|
||||
// private static LogHelper _obj;
|
||||
|
||||
private LogHelper()
|
||||
{
|
||||
LogManager.Configuration = new XmlLoggingConfiguration(MyEnvironment.Root("/Configs/NLog.config"));
|
||||
}
|
||||
public static LogHelper Instance => _obj ?? (new LogHelper());
|
||||
// private LogHelper()
|
||||
// {
|
||||
// LogManager.Configuration = new XmlLoggingConfiguration(MyEnvironment.Root("/Configs/NLog.config"));
|
||||
// }
|
||||
// public static LogHelper Instance => _obj ?? (new LogHelper());
|
||||
|
||||
|
||||
|
||||
#region Debug,调试
|
||||
public void Debug(string msg)
|
||||
{
|
||||
_logger.Debug(msg);
|
||||
}
|
||||
// #region Debug,调试
|
||||
// public void Debug(string msg)
|
||||
// {
|
||||
// _logger.Debug(msg);
|
||||
// }
|
||||
|
||||
public void Debug(string msg, Exception err)
|
||||
{
|
||||
_logger.Debug(err, msg);
|
||||
}
|
||||
#endregion
|
||||
// public void Debug(string msg, Exception err)
|
||||
// {
|
||||
// _logger.Debug(err, msg);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region Info,信息
|
||||
public void Info(string msg)
|
||||
{
|
||||
_logger.Info(msg);
|
||||
}
|
||||
// #region Info,信息
|
||||
// public void Info(string msg)
|
||||
// {
|
||||
// _logger.Info(msg);
|
||||
// }
|
||||
|
||||
public void Info(string msg, Exception err)
|
||||
{
|
||||
_logger.Info(err, msg);
|
||||
}
|
||||
#endregion
|
||||
// public void Info(string msg, Exception err)
|
||||
// {
|
||||
// _logger.Info(err, msg);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region Warn,警告
|
||||
public void Warn(string msg)
|
||||
{
|
||||
_logger.Warn(msg);
|
||||
}
|
||||
// #region Warn,警告
|
||||
// public void Warn(string msg)
|
||||
// {
|
||||
// _logger.Warn(msg);
|
||||
// }
|
||||
|
||||
public void Warn(string msg, Exception err)
|
||||
{
|
||||
_logger.Warn(err, msg);
|
||||
}
|
||||
#endregion
|
||||
// public void Warn(string msg, Exception err)
|
||||
// {
|
||||
// _logger.Warn(err, msg);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region Trace,追踪
|
||||
public void Trace(string msg)
|
||||
{
|
||||
_logger.Trace(msg);
|
||||
}
|
||||
// #region Trace,追踪
|
||||
// public void Trace(string msg)
|
||||
// {
|
||||
// _logger.Trace(msg);
|
||||
// }
|
||||
|
||||
public void Trace(string msg, Exception err)
|
||||
{
|
||||
_logger.Trace(err, msg);
|
||||
}
|
||||
#endregion
|
||||
// public void Trace(string msg, Exception err)
|
||||
// {
|
||||
// _logger.Trace(err, msg);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region Error,错误
|
||||
public void Error(string msg)
|
||||
{
|
||||
_logger.Error(msg);
|
||||
}
|
||||
// #region Error,错误
|
||||
// public void Error(string msg)
|
||||
// {
|
||||
// _logger.Error(msg);
|
||||
// }
|
||||
|
||||
public void Error(string msg, Exception err)
|
||||
{
|
||||
_logger.Error(err, msg);
|
||||
}
|
||||
#endregion
|
||||
// public void Error(string msg, Exception err)
|
||||
// {
|
||||
// _logger.Error(err, msg);
|
||||
// }
|
||||
// #endregion
|
||||
|
||||
#region Fatal,致命错误
|
||||
public void Fatal(string msg)
|
||||
{
|
||||
_logger.Fatal(msg);
|
||||
}
|
||||
// #region Fatal,致命错误
|
||||
// public void Fatal(string msg)
|
||||
// {
|
||||
// _logger.Fatal(msg);
|
||||
// }
|
||||
|
||||
public void Fatal(string msg, Exception err)
|
||||
{
|
||||
_logger.Fatal(err, msg);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
// public void Fatal(string msg, Exception err)
|
||||
// {
|
||||
// _logger.Fatal(err, msg);
|
||||
// }
|
||||
// #endregion
|
||||
//}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace 电子展板.Utility.Web
|
||||
{
|
||||
public class WithExtensionMultipartFormDataStreamProvider : MultipartFormDataStreamProvider
|
||||
{
|
||||
public string guid { get; set; }
|
||||
public string OriginalName { get; set; }
|
||||
public string Ext { get; set; }
|
||||
|
||||
public WithExtensionMultipartFormDataStreamProvider(string rootPath, string guidStr) : base(rootPath)
|
||||
{
|
||||
guid = guidStr;
|
||||
}
|
||||
|
||||
public override string GetLocalFileName(System.Net.Http.Headers.HttpContentHeaders headers)
|
||||
{
|
||||
OriginalName = !string.IsNullOrWhiteSpace(headers.ContentDisposition.FileName) ? GetValidFileName(headers.ContentDisposition.FileName) : "";
|
||||
Ext = !string.IsNullOrWhiteSpace(OriginalName) ? Path.GetExtension(GetValidFileName(OriginalName)) : "";
|
||||
return guid + Ext;
|
||||
}
|
||||
|
||||
private string GetValidFileName(string filePath)
|
||||
{
|
||||
char[] invalids = System.IO.Path.GetInvalidFileNameChars();
|
||||
return string.Join("_", filePath.Split(invalids, StringSplitOptions.RemoveEmptyEntries)).TrimEnd('.');
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,20 @@
|
||||
using Nancy;
|
||||
using Nancy.Hosting.Self;
|
||||
using Nancy.Json;
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Forms;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using 电子展板.Base;
|
||||
using 电子展板.Models;
|
||||
using 电子展板.Utility;
|
||||
using 电子展板.Utility.Core;
|
||||
using 电子展板.Utility.Extension;
|
||||
|
||||
namespace 电子展板.ViewModels
|
||||
@@ -28,7 +29,7 @@ namespace 电子展板.ViewModels
|
||||
public DelegateCommand<Window> LoadedCommand { get; set; }
|
||||
public DelegateCommand<CancelEventArgs> WindowClosingCommand { get; set; }
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
{
|
||||
LoadedCommand = new DelegateCommand<Window>(Loaded);
|
||||
WindowClosingCommand = new DelegateCommand<CancelEventArgs>(WindowClosing);
|
||||
EventBus.Instance.Subscribe(this, "save", ReloadImage);
|
||||
@@ -43,15 +44,18 @@ namespace 电子展板.ViewModels
|
||||
this.window.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
|
||||
this.window.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
|
||||
this.window.Height = (int)(Screen.AllScreens[screenIndex].Bounds.Height / GetDpiScaleX());
|
||||
GlobalVariable.WebServer = new NancyHost(new Uri("http://localhost:80"));
|
||||
GlobalVariable.WebServer.Start();
|
||||
|
||||
WebServer.Start();
|
||||
//GlobalVariable.WebServer = new NancyHost(new Uri("http://localhost:80"));
|
||||
//GlobalVariable.WebServer.Start();
|
||||
}
|
||||
|
||||
private void WindowClosing(CancelEventArgs args)
|
||||
{
|
||||
GlobalVariable.WebServer?.Stop();
|
||||
GlobalVariable.WebServer?.Dispose();
|
||||
GlobalVariable.WebServer = null;
|
||||
WebServer.Stop();
|
||||
//GlobalVariable.WebServer?.Stop();
|
||||
//GlobalVariable.WebServer?.Dispose();
|
||||
//GlobalVariable.WebServer = null;
|
||||
Environment.Exit(0);
|
||||
}
|
||||
public double GetDpiScaleX()
|
||||
@@ -70,62 +74,32 @@ namespace 电子展板.ViewModels
|
||||
|
||||
private void InitImage()
|
||||
{
|
||||
try
|
||||
{
|
||||
BitmapImage image1 = new BitmapImage();
|
||||
image1.BeginInit();
|
||||
image1.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image1.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember1Path)));
|
||||
image1.EndInit();
|
||||
image1.Freeze();
|
||||
Image1 = image1;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Image1 = null;
|
||||
}
|
||||
try
|
||||
{
|
||||
BitmapImage image2 = new BitmapImage();
|
||||
image2.BeginInit();
|
||||
image2.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image2.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember2Path)));
|
||||
image2.EndInit();
|
||||
image2.Freeze();
|
||||
Image2 = image2;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Image2 = null;
|
||||
Image1 = GetImage(Config.CPCMember1Path);
|
||||
Image2 = GetImage(Config.CPCMember2Path);
|
||||
Image3 = GetImage(Config.CPCMember3Path);
|
||||
Image4 = GetImage(Config.CPCMember4Path);
|
||||
}
|
||||
|
||||
}
|
||||
private ImageSource GetImage(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
BitmapImage image3 = new BitmapImage();
|
||||
image3.BeginInit();
|
||||
image3.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image3.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember3Path)));
|
||||
image3.EndInit();
|
||||
image3.Freeze();
|
||||
Image3 = image3;
|
||||
if (path.IsNullOrEmpty())
|
||||
return null;
|
||||
UploadFiles uploadFiles = GlobalVariable.Config.FileUploadList.FirstOrDefault(x => path.EndsWith(x.Name));
|
||||
if (uploadFiles == null)
|
||||
return null;
|
||||
BitmapImage image = new BitmapImage();
|
||||
image.BeginInit();
|
||||
image.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image.StreamSource = new ByteArrayStream(uploadFiles.Bin);
|
||||
image.EndInit();
|
||||
image.Freeze();
|
||||
return image;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Image3 = null;
|
||||
}
|
||||
try
|
||||
{
|
||||
BitmapImage image4 = new BitmapImage();
|
||||
image4.BeginInit();
|
||||
image4.CacheOption = BitmapCacheOption.OnLoad;
|
||||
image4.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember4Path)));
|
||||
image4.EndInit();
|
||||
image4.Freeze();
|
||||
Image4 = image4;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Image4 = null;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ using Swagger.ObjectModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using 电子展板.Base;
|
||||
@@ -100,7 +101,11 @@ namespace 电子展板.WebModule
|
||||
private object GetUploadFiles(string id)
|
||||
{
|
||||
string contentType = MimeTypes.GetMimeType(id);
|
||||
return Response.AsFile(MyEnvironment.Root("/Upload/" + id), contentType);
|
||||
//return Response.AsFile(MyEnvironment.Root("/Upload/" + id), contentType);
|
||||
UploadFiles uploadFiles = GlobalVariable.Config.FileUploadList.FirstOrDefault(x => x.Name == id);
|
||||
if (uploadFiles == null)
|
||||
return null;
|
||||
return Response.FromStream(new MemoryStream(uploadFiles.Bin), contentType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,14 +125,21 @@ namespace 电子展板.WebModule
|
||||
{
|
||||
Directory.CreateDirectory(uploadPath);
|
||||
}
|
||||
|
||||
string ext = Path.GetExtension(file.Name);
|
||||
string fileName = UUID.StrSnowId + ext;
|
||||
var filePath = uploadPath + fileName;
|
||||
using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
|
||||
{
|
||||
file.Value.CopyTo(fileStream);
|
||||
}
|
||||
|
||||
//var filePath = uploadPath + fileName;
|
||||
//using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
|
||||
//{
|
||||
// file.Value.CopyTo(fileStream);
|
||||
//}
|
||||
|
||||
|
||||
ByteArrayStream stream = new ByteArrayStream();
|
||||
file.Value.CopyTo(stream);
|
||||
byte[] data = stream.ToByteArray();
|
||||
GlobalVariable.Config.FileUploadList.Add(new UploadFiles { Name = fileName, Bin = data });
|
||||
GlobalVariable.SaveConfig();
|
||||
RetValue<string> result = new RetValue<string> { state = 1, message = "上传成功", data = $"/upload/{fileName}" };
|
||||
return Response.AsJson(result);
|
||||
}
|
||||
@@ -140,11 +152,14 @@ namespace 电子展板.WebModule
|
||||
[Route(Tags = new[] { "保存配置" })]
|
||||
private object SaveConfig([RouteParam(ParamIn = ParameterIn.Body, Name = "parms", Description = "保存参数", Required = true)] MyConfig config)
|
||||
{
|
||||
LogHelper.Instance.Info($"用户保存了配置:{JsonHelper.ToJson(config)}");
|
||||
//保存
|
||||
PropertyInfo[] propertyInfos = typeof(MyConfig).GetProperties();
|
||||
foreach (PropertyInfo propertyInfo in propertyInfos)
|
||||
{
|
||||
if (propertyInfo.Name == "FileUploadList")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
object value = propertyInfo.GetValue(config);
|
||||
propertyInfo.SetValue(GlobalVariable.Config, value);
|
||||
}
|
||||
|
||||
182
电子展板/WebModule/IndexController.cs
Normal file
182
电子展板/WebModule/IndexController.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using System.Web.Http;
|
||||
using 电子展板.Base;
|
||||
using 电子展板.Models;
|
||||
using 电子展板.Utility;
|
||||
using 电子展板.Utility.Core;
|
||||
using 电子展板.Utility.Other;
|
||||
using 电子展板.Utility.Web;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace 电子展板.WebModule
|
||||
{
|
||||
public class IndexController : ApiController
|
||||
{
|
||||
/// 主界面
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet, Route(""), Route("index.html")]
|
||||
public ActionResult Index()
|
||||
{
|
||||
return Resouce("/Views/Index.html", "text/html");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得配置信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet, Route("getConfig")]
|
||||
public ActionResult GetConfig()
|
||||
{
|
||||
return Json(GlobalVariable.Config);
|
||||
}
|
||||
/// <summary>
|
||||
/// 上传图片。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("uploadImage")]
|
||||
public ActionResult UploadImage()
|
||||
{
|
||||
if (!Request.Content.IsMimeMultipartContent())
|
||||
{
|
||||
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
|
||||
}
|
||||
string tempPath = Path.GetTempPath();
|
||||
var provider = new WithExtensionMultipartFormDataStreamProvider(tempPath, UUID.StrSnowId);
|
||||
var fileData = Request.Content.ReadAsMultipartAsync(provider).Result;
|
||||
if (fileData.FileData.Count == 0)
|
||||
{
|
||||
return Error();
|
||||
}
|
||||
var file = fileData.FileData[0];
|
||||
byte[] data = null;
|
||||
using (ByteArrayStream byteArrayStream = new ByteArrayStream())
|
||||
{
|
||||
using (var stream = System.IO.File.OpenRead(file.LocalFileName))
|
||||
{
|
||||
stream.CopyTo(byteArrayStream);
|
||||
}
|
||||
System.IO.File.Delete(file.LocalFileName);
|
||||
data = byteArrayStream.ToByteArray();
|
||||
}
|
||||
string filename = Path.GetFileName(file.LocalFileName);
|
||||
GlobalVariable.Config.FileUploadList.Add(new UploadFiles { Name = filename, Bin = data });
|
||||
GlobalVariable.SaveConfig();
|
||||
|
||||
string virtualPath = "/upload/" + filename;
|
||||
return Success("上传成功", virtualPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图形显示
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet, Route("upload/{id}")]
|
||||
public ActionResult GetUploadFile([FromUri] string id)
|
||||
{
|
||||
string contentType = System.Web.MimeMapping.GetMimeMapping(id);
|
||||
UploadFiles uploadFiles = GlobalVariable.Config.FileUploadList.FirstOrDefault(x => x.Name == id);
|
||||
if (uploadFiles == null)
|
||||
return null;
|
||||
return File(uploadFiles.Bin, id, contentType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存配置文件
|
||||
/// </summary>
|
||||
/// <param name="config"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost, Route("save")]
|
||||
public ActionResult Save([FromBody] MyConfig config)
|
||||
{
|
||||
//保存
|
||||
PropertyInfo[] propertyInfos = typeof(MyConfig).GetProperties();
|
||||
foreach (PropertyInfo propertyInfo in propertyInfos)
|
||||
{
|
||||
if (propertyInfo.Name == "FileUploadList")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
object value = propertyInfo.GetValue(config);
|
||||
propertyInfo.SetValue(GlobalVariable.Config, value);
|
||||
}
|
||||
GlobalVariable.SaveConfig();
|
||||
//保存并修改界面
|
||||
EventBus.Instance.Publish("save", "");
|
||||
return Success();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private ActionResult File(byte[] bytes, string name, string contentType)
|
||||
{
|
||||
ActionResult response = new ActionResult(HttpStatusCode.OK);
|
||||
response.Content = new StreamContent(new MemoryStream(bytes));
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentLength = bytes.Length;
|
||||
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
||||
{
|
||||
FileName = HttpUtility.UrlEncode(name)
|
||||
};
|
||||
response.Headers.Add("Access-Control-Expose-Headers", "FileName");
|
||||
response.Headers.Add("FileName", HttpUtility.UrlEncode(name));
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
private ActionResult Json(object obj)
|
||||
{
|
||||
return new ActionResult { Content = new StringContent(obj.ToJson(), Encoding.UTF8, "application/json") };
|
||||
}
|
||||
|
||||
public ActionResult Resouce(string viewName, string contentType)
|
||||
{
|
||||
string packUri = $"pack://application:,,,/Assets{viewName}";
|
||||
byte[] bytes = null;
|
||||
using (Stream stream = System.Windows.Application.GetResourceStream(new Uri(packUri, UriKind.RelativeOrAbsolute)).Stream)
|
||||
{
|
||||
bytes = new byte[stream.Length];
|
||||
stream.Read(bytes, 0, bytes.Length);
|
||||
}
|
||||
ActionResult response = new ActionResult(HttpStatusCode.OK);
|
||||
response.Content = new ByteArrayContent(bytes);
|
||||
response.Content.Headers.ContentType = new MediaTypeHeaderValue(contentType);
|
||||
response.Content.Headers.ContentLength = bytes.Length;
|
||||
return response;
|
||||
}
|
||||
|
||||
protected ActionResult Success(string message = "恭喜您,操作成功。", object data = null)
|
||||
{
|
||||
return Json(new { state = 1, message, data });
|
||||
}
|
||||
|
||||
protected ActionResult Error(string message = "对不起,操作失败。", object data = null)
|
||||
{
|
||||
return Json(new { state = 2, message, data });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ActionResult : System.Net.Http.HttpResponseMessage
|
||||
{
|
||||
public ActionResult() : base(HttpStatusCode.OK)
|
||||
{
|
||||
|
||||
}
|
||||
public ActionResult(HttpStatusCode statusCode) : base(statusCode)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
120
电子展板/WebServer.cs
Normal file
120
电子展板/WebServer.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using Microsoft.Owin;
|
||||
using Microsoft.Owin.Hosting;
|
||||
using Nancy.Hosting.Self;
|
||||
using Owin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Formatting;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Http;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
namespace 电子展板
|
||||
{
|
||||
public class WebServer
|
||||
{
|
||||
private static bool UseNancy = false;
|
||||
private static NancyHost _host;
|
||||
private static IDisposable host;
|
||||
public static void Start()
|
||||
{
|
||||
if (UseNancy)
|
||||
{
|
||||
_host = new NancyHost(new Uri("http://localhost:80"));
|
||||
_host.Start();
|
||||
}
|
||||
else
|
||||
{
|
||||
StartOptions startOptions = new StartOptions();
|
||||
startOptions.Urls.Add($"http://*:80/");
|
||||
host = WebApp.Start<Startup>(startOptions);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
if (_host != null)
|
||||
{
|
||||
_host.Stop();
|
||||
_host.Dispose();
|
||||
_host = null;
|
||||
}
|
||||
if (host != null)
|
||||
{
|
||||
host.Dispose();
|
||||
host = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Web启动类
|
||||
/// </summary>
|
||||
public class Startup
|
||||
{
|
||||
private HttpConfiguration _config;
|
||||
/// <summary>
|
||||
/// 配置
|
||||
/// </summary>
|
||||
/// <param name="app"></param>
|
||||
/// <param name="env"></param>
|
||||
public void Configuration(IAppBuilder app)
|
||||
{
|
||||
_config = new HttpConfiguration();
|
||||
_config.MapHttpAttributeRoutes();
|
||||
_config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
|
||||
_config.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("datatype", "json", "application/json"));
|
||||
//全局拦截
|
||||
app.Use<ResouceStaticRoute>("/static", "/Assets");
|
||||
app.UseWebApi(_config);
|
||||
}
|
||||
}
|
||||
|
||||
public class ResouceStaticRoute : OwinMiddleware
|
||||
{
|
||||
private string route;
|
||||
private string resources;
|
||||
public ResouceStaticRoute(OwinMiddleware next, string route, string resources) : base(next)
|
||||
{
|
||||
this.route = route;
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
public override async Task Invoke(IOwinContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
string method = context.Request.Method;//GET POST
|
||||
string path = context.Request.Path.ToString();
|
||||
if (method.ToUpper() == "GET" && path.StartsWith(route))
|
||||
{
|
||||
string resourePath = path.Replace(route, "");
|
||||
string packUri = $"pack://application:,,,{resources}{resourePath}";
|
||||
byte[] bytes = null;
|
||||
using (Stream stream = System.Windows.Application.GetResourceStream(new Uri(packUri, UriKind.RelativeOrAbsolute)).Stream)
|
||||
{
|
||||
bytes = new byte[stream.Length];
|
||||
stream.Read(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
context.Response.ContentType = System.Web.MimeMapping.GetMimeMapping(path);
|
||||
context.Response.Write(bytes, 0, bytes.Length);
|
||||
await Task.FromResult(0);
|
||||
}
|
||||
await Next.Invoke(context);
|
||||
}
|
||||
catch (InvalidCastException ex)
|
||||
{
|
||||
await Next.Invoke(context);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Next.Invoke(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,30 +11,43 @@
|
||||
<ItemGroup>
|
||||
<Content Include="favicon.ico" />
|
||||
<Resource Include="Assets\**" />
|
||||
<Content Include="..\Configs\*" Link="Configs\%(Filename)%(Extension)">
|
||||
<!--<Content Include="..\Configs\*" Link="%(Filename)%(Extension)">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>-->
|
||||
<Content Include="..\Configs\Config.json" Link="%(Filename)%(Extension)">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Costura.Fody" Version="6.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<!-- JSON框架 -->
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<!-- 日志框架 -->
|
||||
<PackageReference Include="NLog" Version="6.0.2" />
|
||||
<!--<PackageReference Include="NLog" Version="6.0.2" />-->
|
||||
<!-- WEB 自宿主 -->
|
||||
<PackageReference Include="ZJW.NancySwagger" Version="2.0.1" />
|
||||
<PackageReference Include="Nancy.Hosting.Self" Version="2.0.0" />
|
||||
<!-- 界面UI-->
|
||||
<PackageReference Include="HandyControl" Version="3.5.1" />
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Upload\0.jpg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
|
||||
|
||||
<!-- WEB 自宿主 -->
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Owin" version="5.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.3.0" />
|
||||
<PackageReference Include="Microsoft.Owin" Version="4.2.3" />
|
||||
<PackageReference Include="Microsoft.Owin.Host.SystemWeb" Version="4.2.3" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNet.Identity.Owin" Version="2.2.4" />
|
||||
<PackageReference Include="Swashbuckle.Core" version="5.6.0" />
|
||||
<PackageReference Include="Beginor.Owin.StaticFile" Version="0.3.1" />
|
||||
<PackageReference Include="Microsoft.AspNet.Mvc" Version="5.3.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user