生成单文件
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -1,8 +1,11 @@
|
|||||||
using HandyControl.Collections;
|
using HandyControl.Collections;
|
||||||
|
using System;
|
||||||
using System.Configuration;
|
using System.Configuration;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using 电子展板.Utility.Extension;
|
||||||
|
|
||||||
namespace 电子展板
|
namespace 电子展板
|
||||||
{
|
{
|
||||||
@@ -13,7 +16,8 @@ namespace 电子展板
|
|||||||
{
|
{
|
||||||
public App()
|
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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -13,7 +14,7 @@ namespace 电子展板.Base
|
|||||||
{
|
{
|
||||||
public class GlobalVariable
|
public class GlobalVariable
|
||||||
{
|
{
|
||||||
public static NancyHost WebServer;
|
//public static NancyHost WebServer;
|
||||||
|
|
||||||
private static MyConfig _config;
|
private static MyConfig _config;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -24,7 +25,38 @@ namespace 电子展板.Base
|
|||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_config == null)
|
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;
|
return _config;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
@@ -35,7 +67,7 @@ namespace 电子展板.Base
|
|||||||
|
|
||||||
public static void SaveConfig()
|
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">
|
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||||
<PropertyChanged />
|
<PropertyChanged />
|
||||||
<!--<Costura />-->
|
<Costura />
|
||||||
</Weavers>
|
</Weavers>
|
||||||
@@ -53,6 +53,157 @@
|
|||||||
</xs:attribute>
|
</xs:attribute>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
</xs:element>
|
</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:all>
|
||||||
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
<xs:attribute name="VerifyAssembly" type="xs:boolean">
|
||||||
<xs:annotation>
|
<xs:annotation>
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using Nancy.Swagger.Annotations.Attributes;
|
using Nancy.Swagger.Annotations.Attributes;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Windows.Documents;
|
||||||
using 电子展板.Base;
|
using 电子展板.Base;
|
||||||
|
|
||||||
namespace 电子展板.Models
|
namespace 电子展板.Models
|
||||||
@@ -118,51 +120,8 @@ namespace 电子展板.Models
|
|||||||
[Comment("党员字体大小")]
|
[Comment("党员字体大小")]
|
||||||
[ModelProperty(Description = "党员字体大小", Required = true, Minimum = 15, Maximum = 60)]
|
[ModelProperty(Description = "党员字体大小", Required = true, Minimum = 15, Maximum = 60)]
|
||||||
public int CPCMemberSize { get; set; }
|
public int CPCMemberSize { get; set; }
|
||||||
/// <summary>
|
|
||||||
/// 转换成JSON字符串
|
public List<UploadFiles> FileUploadList { get; set; }
|
||||||
/// </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();
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
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;
|
||||||
using NLog.Config;
|
//using NLog.Config;
|
||||||
using System;
|
using System;
|
||||||
using 电子展板.Utility.Extension;
|
using 电子展板.Utility.Extension;
|
||||||
|
|
||||||
namespace 电子展板.Utility.Logs
|
namespace 电子展板.Utility.Logs
|
||||||
{
|
{
|
||||||
public class LogHelper
|
//public class LogHelper
|
||||||
{
|
//{
|
||||||
private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
// private readonly Logger _logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private static LogHelper _obj;
|
// private static LogHelper _obj;
|
||||||
|
|
||||||
private LogHelper()
|
// private LogHelper()
|
||||||
{
|
// {
|
||||||
LogManager.Configuration = new XmlLoggingConfiguration(MyEnvironment.Root("/Configs/NLog.config"));
|
// LogManager.Configuration = new XmlLoggingConfiguration(MyEnvironment.Root("/Configs/NLog.config"));
|
||||||
}
|
// }
|
||||||
public static LogHelper Instance => _obj ?? (new LogHelper());
|
// public static LogHelper Instance => _obj ?? (new LogHelper());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#region Debug,调试
|
// #region Debug,调试
|
||||||
public void Debug(string msg)
|
// public void Debug(string msg)
|
||||||
{
|
// {
|
||||||
_logger.Debug(msg);
|
// _logger.Debug(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Debug(string msg, Exception err)
|
// public void Debug(string msg, Exception err)
|
||||||
{
|
// {
|
||||||
_logger.Debug(err, msg);
|
// _logger.Debug(err, msg);
|
||||||
}
|
// }
|
||||||
#endregion
|
// #endregion
|
||||||
|
|
||||||
#region Info,信息
|
// #region Info,信息
|
||||||
public void Info(string msg)
|
// public void Info(string msg)
|
||||||
{
|
// {
|
||||||
_logger.Info(msg);
|
// _logger.Info(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Info(string msg, Exception err)
|
// public void Info(string msg, Exception err)
|
||||||
{
|
// {
|
||||||
_logger.Info(err, msg);
|
// _logger.Info(err, msg);
|
||||||
}
|
// }
|
||||||
#endregion
|
// #endregion
|
||||||
|
|
||||||
#region Warn,警告
|
// #region Warn,警告
|
||||||
public void Warn(string msg)
|
// public void Warn(string msg)
|
||||||
{
|
// {
|
||||||
_logger.Warn(msg);
|
// _logger.Warn(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Warn(string msg, Exception err)
|
// public void Warn(string msg, Exception err)
|
||||||
{
|
// {
|
||||||
_logger.Warn(err, msg);
|
// _logger.Warn(err, msg);
|
||||||
}
|
// }
|
||||||
#endregion
|
// #endregion
|
||||||
|
|
||||||
#region Trace,追踪
|
// #region Trace,追踪
|
||||||
public void Trace(string msg)
|
// public void Trace(string msg)
|
||||||
{
|
// {
|
||||||
_logger.Trace(msg);
|
// _logger.Trace(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Trace(string msg, Exception err)
|
// public void Trace(string msg, Exception err)
|
||||||
{
|
// {
|
||||||
_logger.Trace(err, msg);
|
// _logger.Trace(err, msg);
|
||||||
}
|
// }
|
||||||
#endregion
|
// #endregion
|
||||||
|
|
||||||
#region Error,错误
|
// #region Error,错误
|
||||||
public void Error(string msg)
|
// public void Error(string msg)
|
||||||
{
|
// {
|
||||||
_logger.Error(msg);
|
// _logger.Error(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Error(string msg, Exception err)
|
// public void Error(string msg, Exception err)
|
||||||
{
|
// {
|
||||||
_logger.Error(err, msg);
|
// _logger.Error(err, msg);
|
||||||
}
|
// }
|
||||||
#endregion
|
// #endregion
|
||||||
|
|
||||||
#region Fatal,致命错误
|
// #region Fatal,致命错误
|
||||||
public void Fatal(string msg)
|
// public void Fatal(string msg)
|
||||||
{
|
// {
|
||||||
_logger.Fatal(msg);
|
// _logger.Fatal(msg);
|
||||||
}
|
// }
|
||||||
|
|
||||||
public void Fatal(string msg, Exception err)
|
// public void Fatal(string msg, Exception err)
|
||||||
{
|
// {
|
||||||
_logger.Fatal(err, msg);
|
// _logger.Fatal(err, msg);
|
||||||
}
|
// }
|
||||||
#endregion
|
// #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 System;
|
||||||
using Nancy.Hosting.Self;
|
|
||||||
using Nancy.Json;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Shapes;
|
||||||
using 电子展板.Base;
|
using 电子展板.Base;
|
||||||
|
using 电子展板.Models;
|
||||||
using 电子展板.Utility;
|
using 电子展板.Utility;
|
||||||
|
using 电子展板.Utility.Core;
|
||||||
using 电子展板.Utility.Extension;
|
using 电子展板.Utility.Extension;
|
||||||
|
|
||||||
namespace 电子展板.ViewModels
|
namespace 电子展板.ViewModels
|
||||||
@@ -28,7 +29,7 @@ namespace 电子展板.ViewModels
|
|||||||
public DelegateCommand<Window> LoadedCommand { get; set; }
|
public DelegateCommand<Window> LoadedCommand { get; set; }
|
||||||
public DelegateCommand<CancelEventArgs> WindowClosingCommand { get; set; }
|
public DelegateCommand<CancelEventArgs> WindowClosingCommand { get; set; }
|
||||||
public MainWindowViewModel()
|
public MainWindowViewModel()
|
||||||
{
|
{
|
||||||
LoadedCommand = new DelegateCommand<Window>(Loaded);
|
LoadedCommand = new DelegateCommand<Window>(Loaded);
|
||||||
WindowClosingCommand = new DelegateCommand<CancelEventArgs>(WindowClosing);
|
WindowClosingCommand = new DelegateCommand<CancelEventArgs>(WindowClosing);
|
||||||
EventBus.Instance.Subscribe(this, "save", ReloadImage);
|
EventBus.Instance.Subscribe(this, "save", ReloadImage);
|
||||||
@@ -43,15 +44,18 @@ namespace 电子展板.ViewModels
|
|||||||
this.window.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
|
this.window.Top = (int)(Screen.AllScreens[screenIndex].Bounds.Top / GetDpiScaleX());
|
||||||
this.window.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
|
this.window.Width = (int)(Screen.AllScreens[screenIndex].Bounds.Width / GetDpiScaleX());
|
||||||
this.window.Height = (int)(Screen.AllScreens[screenIndex].Bounds.Height / 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)
|
private void WindowClosing(CancelEventArgs args)
|
||||||
{
|
{
|
||||||
GlobalVariable.WebServer?.Stop();
|
WebServer.Stop();
|
||||||
GlobalVariable.WebServer?.Dispose();
|
//GlobalVariable.WebServer?.Stop();
|
||||||
GlobalVariable.WebServer = null;
|
//GlobalVariable.WebServer?.Dispose();
|
||||||
|
//GlobalVariable.WebServer = null;
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
public double GetDpiScaleX()
|
public double GetDpiScaleX()
|
||||||
@@ -70,62 +74,32 @@ namespace 电子展板.ViewModels
|
|||||||
|
|
||||||
private void InitImage()
|
private void InitImage()
|
||||||
{
|
{
|
||||||
try
|
Image1 = GetImage(Config.CPCMember1Path);
|
||||||
{
|
Image2 = GetImage(Config.CPCMember2Path);
|
||||||
BitmapImage image1 = new BitmapImage();
|
Image3 = GetImage(Config.CPCMember3Path);
|
||||||
image1.BeginInit();
|
Image4 = GetImage(Config.CPCMember4Path);
|
||||||
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;
|
|
||||||
|
|
||||||
}
|
private ImageSource GetImage(string path)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
BitmapImage image3 = new BitmapImage();
|
if (path.IsNullOrEmpty())
|
||||||
image3.BeginInit();
|
return null;
|
||||||
image3.CacheOption = BitmapCacheOption.OnLoad;
|
UploadFiles uploadFiles = GlobalVariable.Config.FileUploadList.FirstOrDefault(x => path.EndsWith(x.Name));
|
||||||
image3.StreamSource = new MemoryStream(File.ReadAllBytes(MyEnvironment.Root(Config.CPCMember3Path)));
|
if (uploadFiles == null)
|
||||||
image3.EndInit();
|
return null;
|
||||||
image3.Freeze();
|
BitmapImage image = new BitmapImage();
|
||||||
Image3 = image3;
|
image.BeginInit();
|
||||||
|
image.CacheOption = BitmapCacheOption.OnLoad;
|
||||||
|
image.StreamSource = new ByteArrayStream(uploadFiles.Bin);
|
||||||
|
image.EndInit();
|
||||||
|
image.Freeze();
|
||||||
|
return image;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Image3 = null;
|
return 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Swagger.ObjectModel;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using 电子展板.Base;
|
using 电子展板.Base;
|
||||||
@@ -100,7 +101,11 @@ namespace 电子展板.WebModule
|
|||||||
private object GetUploadFiles(string id)
|
private object GetUploadFiles(string id)
|
||||||
{
|
{
|
||||||
string contentType = MimeTypes.GetMimeType(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>
|
/// <summary>
|
||||||
@@ -120,14 +125,21 @@ namespace 电子展板.WebModule
|
|||||||
{
|
{
|
||||||
Directory.CreateDirectory(uploadPath);
|
Directory.CreateDirectory(uploadPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
string ext = Path.GetExtension(file.Name);
|
string ext = Path.GetExtension(file.Name);
|
||||||
string fileName = UUID.StrSnowId + ext;
|
string fileName = UUID.StrSnowId + ext;
|
||||||
var filePath = uploadPath + fileName;
|
|
||||||
using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
|
//var filePath = uploadPath + fileName;
|
||||||
{
|
//using (FileStream fileStream = new FileStream(filePath, FileMode.Create))
|
||||||
file.Value.CopyTo(fileStream);
|
//{
|
||||||
}
|
// 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}" };
|
RetValue<string> result = new RetValue<string> { state = 1, message = "上传成功", data = $"/upload/{fileName}" };
|
||||||
return Response.AsJson(result);
|
return Response.AsJson(result);
|
||||||
}
|
}
|
||||||
@@ -140,11 +152,14 @@ namespace 电子展板.WebModule
|
|||||||
[Route(Tags = new[] { "保存配置" })]
|
[Route(Tags = new[] { "保存配置" })]
|
||||||
private object SaveConfig([RouteParam(ParamIn = ParameterIn.Body, Name = "parms", Description = "保存参数", Required = true)] MyConfig config)
|
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();
|
PropertyInfo[] propertyInfos = typeof(MyConfig).GetProperties();
|
||||||
foreach (PropertyInfo propertyInfo in propertyInfos)
|
foreach (PropertyInfo propertyInfo in propertyInfos)
|
||||||
{
|
{
|
||||||
|
if (propertyInfo.Name == "FileUploadList")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
object value = propertyInfo.GetValue(config);
|
object value = propertyInfo.GetValue(config);
|
||||||
propertyInfo.SetValue(GlobalVariable.Config, value);
|
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>
|
<ItemGroup>
|
||||||
<Content Include="favicon.ico" />
|
<Content Include="favicon.ico" />
|
||||||
<Resource Include="Assets\**" />
|
<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>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Costura.Fody" Version="6.0.0">
|
||||||
|
<PrivateAssets>all</PrivateAssets>
|
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
</PackageReference>
|
||||||
<!-- JSON框架 -->
|
<!-- JSON框架 -->
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||||
<!-- 日志框架 -->
|
<!-- 日志框架 -->
|
||||||
<PackageReference Include="NLog" Version="6.0.2" />
|
<!--<PackageReference Include="NLog" Version="6.0.2" />-->
|
||||||
<!-- WEB 自宿主 -->
|
<!-- WEB 自宿主 -->
|
||||||
<PackageReference Include="ZJW.NancySwagger" Version="2.0.1" />
|
<PackageReference Include="ZJW.NancySwagger" Version="2.0.1" />
|
||||||
<PackageReference Include="Nancy.Hosting.Self" Version="2.0.0" />
|
<PackageReference Include="Nancy.Hosting.Self" Version="2.0.0" />
|
||||||
<!-- 界面UI-->
|
<!-- 界面UI-->
|
||||||
<PackageReference Include="HandyControl" Version="3.5.1" />
|
<PackageReference Include="HandyControl" Version="3.5.1" />
|
||||||
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
|
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" />
|
||||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
|
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<!-- WEB 自宿主 -->
|
||||||
<Content Include="Upload\0.jpg">
|
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="9.0.9" />
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<PackageReference Include="Microsoft.AspNet.WebApi.Owin" version="5.3.0" />
|
||||||
</Content>
|
<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>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user