WPF程序注册开机自启后启动找不到Icon.ico抛出IO异常
故障根因
通过注册表Run项触发开机自启时,Windows为程序分配的默认工作目录为C:\Windows\System32,并非exe文件自身所在的目录。你的托盘图标加载逻辑使用了相对路径"Icon.ico",程序会默认在当前工作目录下查找该文件,因路径不匹配触发文件找不到的IO异常。
手动双击启动exe时,资源管理器会自动将程序工作目录设置为exe所在文件夹,相对路径可以正常定位到Icon.ico,因此运行无异常。
修复方案
选择以下任意一种方案修复即可,优先推荐嵌入资源或绝对路径方案,稳定性最高:
- 方案1:加载文件时使用基于exe所在目录的绝对路径,完全不依赖工作目录
不要直接写相对文件名,先获取程序集自身所在目录,再拼接完整文件路径:using System.Reflection; using System.IO; // 初始化NotifyIcon部分代码修改为 HandyOrderPOSIcon = new System.Windows.Forms.NotifyIcon(); // 获取当前exe所在文件夹的绝对路径,不要用Environment.CurrentDirectory取值,该值可能被程序内其他逻辑修改 string appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string iconFullPath = Path.Combine(appPath, "Icon.ico"); HandyOrderPOSIcon.Icon = new System.Drawing.Icon(iconFullPath); HandyOrderPOSIcon.Visible = true; HandyOrderPOSIcon.ContextMenuStrip = menuStrip; HandyOrderPOSIcon.MouseClick += delegate (object sender, System.Windows.Forms.MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Right) { menuStrip.Show(); } }; - 方案2:程序启动入口处主动修正工作目录
在App.xaml.cs的OnStartup方法或者MainWindow构造函数最开头,加入如下代码全局修正工作目录,原有相对路径逻辑可以不用改动:using System.Reflection; using System.IO; string appDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); Environment.CurrentDirectory = appDir; - 方案3(最优,无外部文件依赖):将Icon.ico作为嵌入资源打包进程序集,直接从内存加载
右键项目中的Icon.ico文件,将属性栏的「生成操作」改为「嵌入的资源」,之后直接从程序集资源流加载图标,完全不需要依赖外部文件,彻底避免各类路径问题:using System.Reflection; // 注意将字符串中的「你的项目默认命名空间」替换为项目实际的根命名空间 using (Stream iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("你的项目默认命名空间.Icon.ico")) { HandyOrderPOSIcon.Icon = new System.Drawing.Icon(iconStream); }
额外说明:你当前写的注册表开机自启逻辑没有问题,
Process.GetCurrentProcess().MainModule.FileName获取的是exe的完整绝对路径,这部分代码不需要修改。
内容的提问来源于stack exchange,提问作者JY Lee
相关产品推荐
相关产品推荐

