diff --git a/Bin/net40/SunnyUI.Demo.exe b/Bin/net40/SunnyUI.Demo.exe index 003e9b33..74bc891c 100644 Binary files a/Bin/net40/SunnyUI.Demo.exe and b/Bin/net40/SunnyUI.Demo.exe differ diff --git a/Bin/net40/SunnyUI.dll b/Bin/net40/SunnyUI.dll index 9f24cf9d..e21ee2ac 100644 Binary files a/Bin/net40/SunnyUI.dll and b/Bin/net40/SunnyUI.dll differ diff --git a/Bin/net462/SunnyUI.dll b/Bin/net462/SunnyUI.dll index 6a3d2fe6..bc03ffae 100644 Binary files a/Bin/net462/SunnyUI.dll and b/Bin/net462/SunnyUI.dll differ diff --git a/Bin/net5.0-windows/SunnyUI.dll b/Bin/net5.0-windows/SunnyUI.dll index 7327b256..831569a9 100644 Binary files a/Bin/net5.0-windows/SunnyUI.dll and b/Bin/net5.0-windows/SunnyUI.dll differ diff --git a/Bin/net5.0-windows/ref/SunnyUI.dll b/Bin/net5.0-windows/ref/SunnyUI.dll index 751a0504..8629d6a1 100644 Binary files a/Bin/net5.0-windows/ref/SunnyUI.dll and b/Bin/net5.0-windows/ref/SunnyUI.dll differ diff --git a/Bin/netcoreapp3.1/SunnyUI.dll b/Bin/netcoreapp3.1/SunnyUI.dll index b1209297..77e91a47 100644 Binary files a/Bin/netcoreapp3.1/SunnyUI.dll and b/Bin/netcoreapp3.1/SunnyUI.dll differ diff --git a/SunnyUI/Controls/UIListBox.cs b/SunnyUI/Controls/UIListBox.cs index 4e49ad5f..185a68e1 100644 --- a/SunnyUI/Controls/UIListBox.cs +++ b/SunnyUI/Controls/UIListBox.cs @@ -37,7 +37,7 @@ namespace Sunny.UI { [DefaultEvent("ItemClick")] [DefaultProperty("Items")] - public sealed partial class UIListBox : UIPanel, IToolTip + public sealed class UIListBox : UIPanel, IToolTip { private readonly ListBoxEx listbox = new ListBoxEx(); private readonly UIScrollBar bar = new UIScrollBar(); diff --git a/SunnyUI/Static/UFile.cs b/SunnyUI/Static/UFile.cs index a8eeda8c..49f00737 100644 --- a/SunnyUI/Static/UFile.cs +++ b/SunnyUI/Static/UFile.cs @@ -766,6 +766,25 @@ namespace Sunny.UI crc ^= 0xFFFFFFFF; return crc.ToString("X").PadLeft(8, '0'); } + + public static bool IsValidFileName(string name) + { + if (name.IsNullOrEmpty()) + { + return false; + } + + string[] errorStr = { "/", "\\", ":", ",", "*", "?", "\"", "<", ">", "|" }; + foreach (var str in errorStr) + { + if (name.Contains(str)) + { + return false; + } + } + + return true; + } } /// diff --git a/SunnyUI/Units/UMMFile.cs b/SunnyUI/Units/UMMFile.cs new file mode 100644 index 00000000..214012fd --- /dev/null +++ b/SunnyUI/Units/UMMFile.cs @@ -0,0 +1,160 @@ +/****************************************************************************** + * SunnyUI 开源控件库、工具类库、扩展类库、多页面开发框架。 + * CopyRight (C) 2012-2021 ShenYongHua(沈永华). + * QQ群:56829229 QQ:17612584 EMail:SunnyUI@QQ.Com + * + * Blog: https://www.cnblogs.com/yhuse + * Gitee: https://gitee.com/yhuse/SunnyUI + * GitHub: https://github.com/yhuse/SunnyUI + * + * SunnyUI.dll can be used for free under the GPL-3.0 license. + * If you use this code, please keep this note. + * 如果您使用此代码,请保留此说明。 + ****************************************************************************** + * 文件名称: UMMFile.cs + * 文件说明: 多进程通信类 + * 当前版本: V3.0 + * 创建日期: 2021-09-05 + * + * 2021-09-05: V3.0.6 增加文件说明 +******************************************************************************/ + +using System; +using System.IO.MemoryMappedFiles; +using System.Text; +using System.Threading; + +namespace Sunny.UI +{ + public sealed class MMFile : BackgroundWorkerEx, IDisposable + { + public string MapName { get; } + public int Capacity { get; } + + public MMFile(string mapName, int capacity = 4096) + { + if (!FileEx.IsValidFileName(mapName)) + { + throw new Exception("MapName is not valid."); + } + + MapName = mapName; + WorkerDelay = 10; + Capacity = Math.Max(4096, capacity); + + var mmf = MemoryMappedFile.CreateOrOpen(MapName, Capacity, MemoryMappedFileAccess.ReadWrite); + using (var accessor = mmf.CreateViewAccessor(0, Capacity)) + { + var value = accessor.ReadBoolean(0); + if (!value) accessor.Write(0, false); + } + } + + public event MMFileEventHandler OnMessage; + + protected override void DoWorker() + { + try + { + if (ExistsValue()) + { + var message = Read(); + OnMessage?.Invoke(this, new MMFileEventArgs(message.Source, message.Value)); + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + public void Write(string dest, string message) + { + var mmf = MemoryMappedFile.CreateOrOpen(dest, Capacity, MemoryMappedFileAccess.ReadWrite); + using (var accessor = mmf.CreateViewAccessor(0, Capacity)) + { + if (accessor.ReadBoolean(0)) + { + Thread.Sleep(10); + } + + var data = Encoding.Unicode.GetBytes(MapName); + accessor.Write(128, data.Length); + accessor.WriteArray(128 + 4, data, 0, data.Length); + + data = Encoding.Unicode.GetBytes(message); + accessor.Write(1024, data.Length); + accessor.WriteArray(1024 + 4, data, 0, data.Length); + + accessor.Write(0, true); + } + } + + private Message Read() + { + Message message = new Message(); + var mmf = MemoryMappedFile.CreateOrOpen(MapName, Capacity, MemoryMappedFileAccess.ReadWrite); + using (var accessor = mmf.CreateViewAccessor(0, Capacity)) + { + accessor.Write(0, false); + var len = accessor.ReadInt32(128); + var data = new byte[len]; + accessor.ReadArray(128 + 4, data, 0, len); + message.Source = Encoding.Unicode.GetString(data); + + len = accessor.ReadInt32(1024); + data = new byte[len]; + accessor.ReadArray(1024 + 4, data, 0, len); + message.Value = Encoding.Unicode.GetString(data); + return message; + } + } + + private bool ExistsValue() + { + var mmf = MemoryMappedFile.CreateOrOpen(MapName, Capacity, MemoryMappedFileAccess.ReadWrite); + using (var accessor = mmf.CreateViewAccessor(0, Capacity)) + { + return accessor.ReadBoolean(0); + } + } + + internal struct Message + { + public string Source { get; set; } + public string Value { get; set; } + } + + public void Dispose() + { + Stop(); + try + { + var mmf = MemoryMappedFile.OpenExisting(MapName); + mmf.Dispose(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + ~MMFile() + { + Dispose(); + } + } + + public delegate void MMFileEventHandler(object sender, MMFileEventArgs e); + public class MMFileEventArgs : EventArgs + { + public string Source { get; set; } + public string Value { get; set; } + + public MMFileEventArgs(string source, string value) + { + Source = source; + Value = value; + } + } +} \ No newline at end of file