使用WindowsFormsApplicationBase实现引导界面
1.需要添加对Microsoft.VisualBasic 引用,
2.准备frmMain,frmSplash两个窗口
说明:
frmSplash在主线程上建立,但是在独立线程上进行消息循环
当protected override void OnCreateMainForm 方法执行完毕,会隐藏frmSplash
可以在OnCreateMainForm中执行预加载操作,或者在frmMain的构造里执行,不要在frmMain的OnLoad事件中进行
当需要改边frmSplash窗体上控件属性时(如显示加载提示等)需要使用控件的Invoke

using System; using System.Collections.Generic; using System.Windows.Forms; namespace SplashLoader { static class Program { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(String[] args) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); new SplashApp().Run(args); } } }

using System; using System.Collections.Generic; using System.Text; using Microsoft.VisualBasic.ApplicationServices; using System.Diagnostics; using System.Windows.Forms; using System.IO; using System.Threading; using System.Reflection; using System.Configuration; using ISplashLoader; namespace SplashLoader { public class SplashApp : WindowsFormsApplicationBase { private frmSplash _frmSplash = null; protected override void OnCreateSplashScreen() { //在主UI线程上运行 Console.WriteLine("OnCreateSplashScreen:" + Thread.CurrentThread.ManagedThreadId); //这里调用是在主线程上的 //但是SplashForm的消息循环是在独立线程上的 //可以在SplashForm的OnLoad事件中看到是一个独立的线程 //因此OnCreateMainForm即使阻塞了,SplashForm也能正常绘制 //可以把数据初试化操作放在frmMain的构造函数中 //但是不要放在OnLoad事件中,因为在OnLoad时UI界面已经绘制完成 //如果在里面放置一些阻塞型的操作会导致界面卡死 //SplashForm在frmMain的OnLoad调用时隐藏(没有发现调用close事件--会有短暂延迟) // _frmSplash = new frmSplash(); SplashScreen = _frmSplash; SplashScreen.ShowInTaskbar = false; SplashScreen.Cursor = System.Windows.Forms.Cursors.AppStarting; } private bool CheckUpgrade() { if (this.CommandLineArgs.Count > 0) { if (string.Compare(CommandLineArgs[0], "Upgrade:Skip", true) == 0) { return false; } } return true; } protected override void OnCreateMainForm() { try { //在主UI线程上运行 Console.WriteLine("OnCreateMainForm:" + Thread.CurrentThread.ManagedThreadId); //注意使用SplashForm 后,可以在主窗体的构造中加载数据 //或者在SplashApp的OnCreateMainForm()中,不要放在frmMain的OnLoad事件中 if (CheckUpgrade()) { _frmSplash.SetTips("检测是否有新的版本..."); Process pa = new Process(); pa.StartInfo.UseShellExecute = false; pa.StartInfo.FileName = Path.Combine(Application.StartupPath, @"UpdateApp.exe"); pa.StartInfo.Arguments = "AppStart"; pa.Start(); while (!pa.HasExited) ; } String assembley = ConfigurationManager.AppSettings["MainAssembly"]; String type = ConfigurationManager.AppSettings["MainForm"]; MainForm = CreateForm(assembley, type, _frmSplash); } catch (Exception e) { //处理动态加载过程中的异常 MessageBox.Show(e.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error); } } /// <summary> /// 动太加载窗体 /// </summary> /// <param name="assembly">如:FIStudio.WinUI.(exe|dll)</param> /// <param name="type">FIStudio.WinUI.UI.frmCooperatorMgr</param> /// <returns></returns> private Form CreateForm(String assembly,String type,ILoadTips loadTips) { String a = System.IO.Path.GetFileNameWithoutExtension(assembly); Type t = Assembly.Load(a).GetType(type, true); Form frm = Activator.CreateInstance(t, new Object[] { loadTips }) as Form; return frm; } } }

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; using ISplashLoader; namespace SplashLoader { public partial class frmSplash : Form ,ILoadTips { public frmSplash() { InitializeComponent(); BackgroundImageLayout = ImageLayout.Stretch; FormBorderStyle = FormBorderStyle.None; StartPosition = FormStartPosition.CenterScreen; Console.WriteLine("SplashForm:" + Thread.CurrentThread.ManagedThreadId); } delegate void SetTipsHandle(String tips); public void SetTips(String tips) { if (lblTips.InvokeRequired) { lblTips.Invoke(new SetTipsHandle(SetTips), tips); } else { lblTips.Text = tips; } } private void frmSplash_Load(object sender, EventArgs e) { Console.WriteLine("SplashForm_Load:" + Thread.CurrentThread.ManagedThreadId); } } }
Demo:参考华为网盘/软件测试与任务/引导窗体
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述