diff --git a/Solution/WPF-Control.sln b/Solution/WPF-Control.sln
index 36665aef..8ab80bba 100644
--- a/Solution/WPF-Control.sln
+++ b/Solution/WPF-Control.sln
@@ -267,9 +267,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.Controls.ColorPicker", ".
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.Extensions.Unit", "..\Source\Extensions\H.Extensions.Unit\H.Extensions.Unit.csproj", "{E4ECBFB2-BCD6-4BEB-B88E-932E3587E04B}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.Controls.QRCoderBox", "..\Source\Controls\H.Controls.QRCoderBox\H.Controls.QRCoderBox.csproj", "{AEC475E3-607E-4290-93B6-5EDFE0229F6C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.Controls.QRCoderBox", "..\Source\Controls\H.Controls.QRCoderBox\H.Controls.QRCoderBox.csproj", "{AEC475E3-607E-4290-93B6-5EDFE0229F6C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.Controls.ScheduleBox", "..\Source\Controls\H.Controls.ScheduleBox\H.Controls.ScheduleBox.csproj", "{24785305-3565-4A79-B83D-CC990D20C42B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "H.Controls.ScheduleBox", "..\Source\Controls\H.Controls.ScheduleBox\H.Controls.ScheduleBox.csproj", "{24785305-3565-4A79-B83D-CC990D20C42B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "H.Extensions.Mail", "..\Source\Extensions\H.Extensions.Mail\H.Extensions.Mail.csproj", "{7374B023-7B0F-4F6E-9E43-C6B81B8DB564}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -751,6 +753,10 @@ Global
{24785305-3565-4A79-B83D-CC990D20C42B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24785305-3565-4A79-B83D-CC990D20C42B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24785305-3565-4A79-B83D-CC990D20C42B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7374B023-7B0F-4F6E-9E43-C6B81B8DB564}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7374B023-7B0F-4F6E-9E43-C6B81B8DB564}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7374B023-7B0F-4F6E-9E43-C6B81B8DB564}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7374B023-7B0F-4F6E-9E43-C6B81B8DB564}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -877,6 +883,7 @@ Global
{E4ECBFB2-BCD6-4BEB-B88E-932E3587E04B} = {09F8FD00-E76A-4D72-AAB4-7FA06DBE12D4}
{AEC475E3-607E-4290-93B6-5EDFE0229F6C} = {9E63ED70-6F96-4CB2-8B9D-EAEC77D0548E}
{24785305-3565-4A79-B83D-CC990D20C42B} = {9E63ED70-6F96-4CB2-8B9D-EAEC77D0548E}
+ {7374B023-7B0F-4F6E-9E43-C6B81B8DB564} = {09F8FD00-E76A-4D72-AAB4-7FA06DBE12D4}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DF825C3D-F4F4-4E62-BBFF-B42A5E81112F}
diff --git a/Source/Extensions/H.Extensions.Mail/AssemblyInfo.cs b/Source/Extensions/H.Extensions.Mail/AssemblyInfo.cs
new file mode 100644
index 00000000..5378cbc6
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/AssemblyInfo.cs
@@ -0,0 +1,20 @@
+using System.Windows;
+using System.Windows.Markup;
+
+[assembly: ThemeInfo(
+ ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+ //(used if a resource is not found in the page,
+ // or application resource dictionaries)
+ ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+ //(used if a resource is not found in the page,SMRZQEVBPSMJXTNG
+ // app, or any theme specific resource dictionaries) BMJGKKNPMBWLIOEO
+)]
+
+[assembly: XmlnsDefinition("QQ:908293466", "H.Extensions.Mail")]
+[assembly: XmlnsPrefix("QQ:908293466", "h")]
+
+[assembly: XmlnsDefinition("https://github.com/HeBianGu", "H.Extensions.Mail")]
+[assembly: XmlnsPrefix("https://github.com/HeBianGu", "h")]
+
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "H.Extensions.Mail")]
+[assembly: XmlnsPrefix("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "h")]
\ No newline at end of file
diff --git a/Source/Extensions/H.Extensions.Mail/Extention.cs b/Source/Extensions/H.Extensions.Mail/Extention.cs
new file mode 100644
index 00000000..8ce9bb7a
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/Extention.cs
@@ -0,0 +1,32 @@
+
+using H.Extensions.Mail;
+using H.Providers.Ioc;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace System
+{
+ public static class Extention
+ {
+ ///
+ /// 注册
+ ///
+ ///
+ public static IServiceCollection AddMail(this IServiceCollection services, Action setupAction = null)
+ {
+ services.AddOptions();
+ services.TryAdd(ServiceDescriptor.Singleton());
+ services.TryAdd(ServiceDescriptor.Singleton());
+ if (setupAction != null)
+ services.Configure(setupAction);
+ return services;
+ }
+
+ public static IApplicationBuilder UseMail(this IApplicationBuilder builder, Action option = null)
+ {
+ SettingDataManager.Instance.Add(SmtpSendOptions.Instance);
+ option?.Invoke(SmtpSendOptions.Instance);
+ return builder;
+ }
+ }
+}
diff --git a/Source/Extensions/H.Extensions.Mail/H.Extensions.Mail.csproj b/Source/Extensions/H.Extensions.Mail/H.Extensions.Mail.csproj
new file mode 100644
index 00000000..8bc6d7e8
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/H.Extensions.Mail.csproj
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Source/Extensions/H.Extensions.Mail/IMailLogService.cs b/Source/Extensions/H.Extensions.Mail/IMailLogService.cs
new file mode 100644
index 00000000..db9b9e11
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/IMailLogService.cs
@@ -0,0 +1,7 @@
+namespace H.Extensions.Mail
+{
+ public interface IMailLogService
+ {
+ bool Send(string subject, string body, out string message);
+ }
+}
\ No newline at end of file
diff --git a/Source/Extensions/H.Extensions.Mail/IMailService.cs b/Source/Extensions/H.Extensions.Mail/IMailService.cs
new file mode 100644
index 00000000..92404fc3
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/IMailService.cs
@@ -0,0 +1,9 @@
+using H.Extensions.Mail;
+
+namespace H.Extensions.Mail
+{
+ public interface IMailService
+ {
+ bool Send(MailMessageItem messageItem, bool isBodyHtml, out string message);
+ }
+}
\ No newline at end of file
diff --git a/Source/Extensions/H.Extensions.Mail/MailLogService.cs b/Source/Extensions/H.Extensions.Mail/MailLogService.cs
new file mode 100644
index 00000000..02006ec2
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/MailLogService.cs
@@ -0,0 +1,19 @@
+using System;
+using H.Extensions.Mail;
+
+namespace H.Extensions.Mail
+{
+ public class MailLogService : IMailLogService
+ {
+ public bool Send(string subject, string body, out string message)
+ {
+ message = null;
+ MailMessageItem mail = new MailMessageItem();
+ mail.Subject = subject;
+ mail.Body = body;
+ mail.From = SmtpSendOptions.Instance.User;
+ mail.To = new string[] { SmtpSendOptions.Instance.User };
+ return Ioc.Instance?.Send(mail, SmtpSendOptions.Instance.IsBodyHtml, out message) == true;
+ }
+ }
+}
diff --git a/Source/Extensions/H.Extensions.Mail/MailService.cs b/Source/Extensions/H.Extensions.Mail/MailService.cs
new file mode 100644
index 00000000..75ca17ab
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/MailService.cs
@@ -0,0 +1,81 @@
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Mail;
+using System.Net.Mime;
+using H.Extensions.Mail;
+
+namespace H.Extensions.Mail
+{
+ public class MailService : IMailService
+ {
+ public bool Send(MailMessageItem messageItem, bool isBodyHtml, out string message)
+ {
+ message = null;
+ SmtpClient smtp = new SmtpClient()
+ {
+ Host = SmtpSendOptions.Instance.Host,
+ Port = SmtpSendOptions.Instance.Port,
+ EnableSsl = SmtpSendOptions.Instance.EnableSsl,
+ DeliveryMethod = SmtpDeliveryMethod.Network,
+ UseDefaultCredentials = false,
+ Credentials = new NetworkCredential(SmtpSendOptions.Instance.User, SmtpSendOptions.Instance.Password)
+ };
+
+ using MailMessage msg = new();
+ msg.From = new MailAddress(messageItem.From);
+ foreach (var to in messageItem.To)
+ {
+ msg.To.Add(new MailAddress(to));
+ }
+
+ if (messageItem.Cc != null)
+ {
+ foreach (var cc in messageItem.Cc)
+ {
+ msg.CC.Add(new MailAddress(cc));
+ }
+ }
+
+ if (messageItem.Bcc != null)
+ {
+ foreach (var bcc in messageItem.Bcc)
+ {
+ msg.Bcc.Add(new MailAddress(bcc));
+ }
+ }
+
+ msg.Subject = messageItem.Subject;
+ msg.Body = messageItem.Body;
+ msg.BodyEncoding = System.Text.Encoding.UTF8;
+ msg.IsBodyHtml = isBodyHtml;
+ msg.SubjectEncoding = System.Text.Encoding.UTF8;
+ if (messageItem.Attachments != null)
+ {
+ foreach (var attachment in messageItem.Attachments)
+ {
+ Attachment data = new(attachment.FullName, MediaTypeNames.Application.Octet);
+ var disposition = data.ContentDisposition;
+ disposition!.CreationDate = File.GetCreationTime(attachment.FullName);
+ disposition.ModificationDate = File.GetLastWriteTime(attachment.FullName);
+ disposition.ReadDate = File.GetLastAccessTime(attachment.FullName);
+ msg.Attachments.Add(data);
+ }
+ }
+ try
+ {
+ smtp.Send(msg);
+ }
+ catch (System.Exception ex)
+ {
+ message = ex.Message;
+ IocLog.Instance?.Error(ex);
+ return false;
+ }
+ return true;
+ }
+
+
+ }
+
+}
diff --git a/Source/Extensions/H.Extensions.Mail/Provider/MailMessageItem.cs b/Source/Extensions/H.Extensions.Mail/Provider/MailMessageItem.cs
new file mode 100644
index 00000000..bbae5051
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/Provider/MailMessageItem.cs
@@ -0,0 +1,19 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace H.Extensions.Mail
+{
+ public class MailMessageItem
+ {
+ public string From { get; set; } = SmtpSendOptions.Instance.User;
+ public string[] To { get; set; } = { SmtpSendOptions.Instance.User };
+ public string[] Cc { get; set; }
+ public string[] Bcc { get; set; }
+ public string Subject { get; set; }
+ public string Body { get; set; }
+ public FileInfo[] Attachments { get; set; }
+ }
+}
diff --git a/Source/Extensions/H.Extensions.Mail/Provider/SendMainCommand.cs b/Source/Extensions/H.Extensions.Mail/Provider/SendMainCommand.cs
new file mode 100644
index 00000000..efae6941
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/Provider/SendMainCommand.cs
@@ -0,0 +1,20 @@
+using H.Providers.Mvvm;
+using System;
+
+namespace H.Extensions.Mail
+{
+ public class SendMainCommand : MarkupCommandBase
+ {
+ public override void Execute(object parameter)
+ {
+ if (parameter is MailMessageItem messageItem)
+ Ioc.Instance?.Send(messageItem, SmtpSendOptions.Instance.IsBodyHtml, out string message);
+ }
+
+ public override bool CanExecute(object parameter)
+ {
+ return Ioc.Instance != null;
+ }
+ }
+
+}
diff --git a/Source/Extensions/H.Extensions.Mail/SmtpSendOptions.cs b/Source/Extensions/H.Extensions.Mail/SmtpSendOptions.cs
new file mode 100644
index 00000000..44aae290
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/SmtpSendOptions.cs
@@ -0,0 +1,99 @@
+using H.Extensions.Setting;
+using H.Providers.Ioc;
+using System.ComponentModel;
+using System.ComponentModel.DataAnnotations;
+
+namespace H.Extensions.Mail
+{
+ [Display(Name = "邮件外发设置", GroupName = SettingGroupNames.GroupSystem, Description = "邮件外发设置的信息")]
+ public class SmtpSendOptions : IocOptionInstance
+ {
+ private string _host;
+ [Required]
+ [DefaultValue("smtp.163.com")]
+ [ReadOnly(true)]
+ [Display(Name = "服务器")]
+ public string Host
+ {
+ get { return _host; }
+ set
+ {
+ _host = value;
+ RaisePropertyChanged();
+ }
+ }
+
+
+ private int _port;
+ [DefaultValue(25)]
+ [ReadOnly(true)]
+ [Display(Name = "端口号")]
+ public int Port
+ {
+ get { return _port; }
+ set
+ {
+ _port = value;
+ RaisePropertyChanged();
+ }
+ }
+
+
+ private bool _enableSsl;
+ [DefaultValue(true)]
+ [Display(Name = "启用SSL")]
+ public bool EnableSsl
+ {
+ get { return _enableSsl; }
+ set
+ {
+ _enableSsl = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ private string _user;
+ [Required]
+ [DefaultValue("HeBianGu2024@163.com")]
+ [Display(Name = "用户名")]
+ [ReadOnly(true)]
+ public string User
+ {
+ get { return _user; }
+ set
+ {
+ _user = value;
+ RaisePropertyChanged();
+ }
+ }
+
+
+ private string _password;
+ [Required]
+ [Display(Name = "密码")]
+ [Browsable(false)]
+ public string Password
+ {
+ get { return _password; }
+ set
+ {
+ _password = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ private bool _isBodyHtml;
+ [Display(Name = "启用HTML格式")]
+ public bool IsBodyHtml
+ {
+ get { return _isBodyHtml; }
+ set
+ {
+ _isBodyHtml = value;
+ RaisePropertyChanged();
+ }
+ }
+
+ }
+
+}
diff --git a/Source/Extensions/H.Extensions.Mail/Themes/Generic.xaml b/Source/Extensions/H.Extensions.Mail/Themes/Generic.xaml
new file mode 100644
index 00000000..ec27ee08
--- /dev/null
+++ b/Source/Extensions/H.Extensions.Mail/Themes/Generic.xaml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Modules/H.Modules.Messages.Dialog/AdonerDialog/AdornerDialogPresenter.xaml b/Source/Modules/H.Modules.Messages.Dialog/AdonerDialog/AdornerDialogPresenter.xaml
index a2768838..a0f5cbd7 100644
--- a/Source/Modules/H.Modules.Messages.Dialog/AdonerDialog/AdornerDialogPresenter.xaml
+++ b/Source/Modules/H.Modules.Messages.Dialog/AdonerDialog/AdornerDialogPresenter.xaml
@@ -4,9 +4,11 @@
xmlns:h="https://github.com/HeBianGu"
xmlns:local="clr-namespace:H.Modules.Messages.Dialog">
-
+
-
+
-
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
+
diff --git a/Source/Modules/H.Modules.Setting/SettingViewPresenter.xaml b/Source/Modules/H.Modules.Setting/SettingViewPresenter.xaml
index dcd30d80..1c53f6f2 100644
--- a/Source/Modules/H.Modules.Setting/SettingViewPresenter.xaml
+++ b/Source/Modules/H.Modules.Setting/SettingViewPresenter.xaml
@@ -54,15 +54,19 @@
FontWeight="Bold"
Text="{Binding Name}"
ToolTip="{Binding Description}" />
-
-
+
+
+
+
+
diff --git a/Source/Tests/H.Test.Test/App.xaml.cs b/Source/Tests/H.Test.Test/App.xaml.cs
index 5ac39f23..c662bd31 100644
--- a/Source/Tests/H.Test.Test/App.xaml.cs
+++ b/Source/Tests/H.Test.Test/App.xaml.cs
@@ -67,6 +67,7 @@ protected override void ConfigureServices(IServiceCollection services)
});
services.AddSchedule();
+ services.AddMail();
}
protected override void Configure(IApplicationBuilder app)
@@ -77,6 +78,8 @@ protected override void Configure(IApplicationBuilder app)
{
x.LibvlcPath = "G:\\BaiduNetdiskDownload\\libvlc\\win-x64";
});
+
+ app.UseMail();
}
}
}
diff --git a/Source/Tests/H.Test.Test/H.Test.Test.csproj b/Source/Tests/H.Test.Test/H.Test.Test.csproj
index 9e1656a6..90ccb5de 100644
--- a/Source/Tests/H.Test.Test/H.Test.Test.csproj
+++ b/Source/Tests/H.Test.Test/H.Test.Test.csproj
@@ -27,6 +27,7 @@
+
diff --git a/Source/Tests/H.Test.Test/MainWindow.xaml b/Source/Tests/H.Test.Test/MainWindow.xaml
index 705da1f9..4a0deb62 100644
--- a/Source/Tests/H.Test.Test/MainWindow.xaml
+++ b/Source/Tests/H.Test.Test/MainWindow.xaml
@@ -581,7 +581,8 @@
PropertyName="Value1" />
-
+
-
+
@@ -930,6 +931,17 @@
+
+
+
+
+
+
+
+