最近有一个工控程序,基于net4.5.2开发的,尝试增加win10系统的Toast通知消息,网络收集到如下结论:
1. Toast功能需要net4.8的高版本,调用Microsoft.Toolkit.Uwp.Notifications.dll —— 工控程序不可能升级的
2. 低版本net都是使用winform自己画的窗体,然后自定义动画 —— 成品效果不好
后续自己做了一些尝试:
1. 新建一个高版本net Demo,将Toast功能输出为dll,低版本去调用这个dll —— 环境报错,不可行
2. 新建一个高版本net Demo,将Toast功能输出为exe,低版本去调用这个exe —— 可行,但是发布程序时要额外附带一个exe,令客户诧异
3. 新建一个高版本net Demo,将Toast功能输出为exe,在低版本将exe添加为工程资源,然后从工程资源中调用exe —— 可行,发布程序时也只有一个exe
其中方式3又经过多次优化
1. 低版本调用:工程资源/Toast,硬件本地/Microsoft.Toolkit.Uwp.Notifications.dll —— 发布程序是要额外附带一个dll
1. 低版本调用:工程资源/Toast,工程资源/Microsoft.Toolkit.Uwp.Notifications.dll —— 发布程序时只有一个exe,但是开发操作时要调用两个资源
1. 高版本调用:工程资源/Microsoft.Toolkit.Uwp.Notifications.dll ,低版本调用:工程资源/Toast —— 发布程序时只有一个exe,开发操作时也只需要添加调用一个资源
首先是高版本Demo,创建为net4.8版本,在NuGet程序包中添加Microsoft.Toolkit.Uwp.Notifications功能,微软官网有详细介绍
using Microsoft.Toolkit.Uwp.Notifications; using System; using System.Threading.Tasks; namespace TryToast { public class TryToast { //参考https://developer.aliyun.com/article/1094575 //.NET中如果使用Microsoft.Toolkit.Uwp.Notifications,必须指定Windows TFM,且要指定window版本,至少为net6.0-windows10.0.17763.0或更高。否则,将报错找不到Show()方法。 //右键项目,编辑项目文件,将TargetFramework指定为如下: //<TargetFramework>net6.0-windows10.0.17763.0</TargetFramework> //通常,指定TFM后,启动调试会报错没有xxx的目标,确保已运行还原...等错误。 //解决办法是:清理项目,并重新生成一次即可。 //有时候还会报错 net6.0-windows10.0.17763.0与.Net框架版本不一致, //需要修改为 net5.0-windows10.0.17763.0。或者改为net5后生成无错再改回net6;或者 直接清理项目并重新生成一次。 public bool Show(string t1,string t2) { bool res = false; try { ToastNotificationManagerCompat.History.Clear(); // Requires Microsoft.Toolkit.Uwp.Notifications NuGet package version 7.0 or greater new ToastContentBuilder() //.AddArgument("action", "viewConversation") //.AddArgument("conversationId", 9813) //.AddHeader("6289", "Camping!!", "action=openConversation&id=6289") .AddText(t1) .AddText(t2) .Show( toast => { toast.ExpirationTime = DateTime.Now.AddHours(3); } ); // Not seeing the Show() method? Make sure you have version 7.0, and if you're using .NET 6 (or later), then your TFM must be net6.0-windows10.0.17763.0 or greater res = true; } catch (Exception ex) { Console.WriteLine($"在程序集TryToast中:{ex.Message}"); } return res; } } }
然后在高版本Demo的MAIN程序中编写参数调用逻辑,需要将NuGet包自动下载的Microsoft.Toolkit.Uwp.Notifications.dll添加到工程资源中,形成如下工程结构
需要注意的是CurrentDomain_AssemblyResolve方法,网络上博客都没有考虑大数组的内存溢出问题,这里用一个静态数组规避。
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace TryToast { internal static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { if (args.Length == 0) return; //在InitializeComponent()之前调用 不需要设置为嵌入资源 bb = new byte[Properties.Resources.Microsoft_Toolkit_Uwp_Notifications.Length]; Array.Copy(Properties.Resources.Microsoft_Toolkit_Uwp_Notifications, bb, bb.Length); AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); if (args.Length == 1) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else if (args.Length == 3) { var t1 = new TryToast(); t1.Show(args[1], args[2]); } } static byte[] bb = null; static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { // byte[] bytes = Properties.Resources.Microsoft_Toolkit_Uwp_Notifications;这样直接调用内存会溢出 return System.Reflection.Assembly.Load(bb); } } }
高版本编译生成exe后,接下来在低版本net程序中就可以调用了
1.低版本net工程资源中添加刚编译好的exe
2.新建一个BUTTON点击事件
private void button1_Click(object sender, EventArgs e) { string[] the_args = { "1","hello","toast" }; byte[] buffer = Properties.Resources.TryToast;//资源数据缓存数组 Assembly asm = Assembly.Load(buffer); //加载数据 MethodInfo pointInfo = asm.EntryPoint;//获取程序入口点 //pointInfo.Invoke(null, new string[][new string[3],new string [3]);//运行 //invoke在你传参的时候,如果是单参数当然是没有问题, //如果是多参数就需要注意了,你需要将参数都装到一个object数组(object[])里, //然后进栈的时候程序会将数组内容push进去,而不是数组object[] 这个变量, //而参数在出栈的时候根据委托的参数表一一对应栈中的每个元素安排出栈。 pointInfo.Invoke(null, new object[] { the_args });//运行 注意资源属性是否设置为嵌入式 }
标签:4.5,Toast,调用,C#,Uwp,Toolkit,Notifications,exe,Microsoft From: https://www.cnblogs.com/xianghrs/p/18531632