C#开发的Windows服务运行正常但文件打印迁移任务不持续执行如何解决
问题原因
你当前的代码只在服务启动的OnStart方法中执行了一次Print(),处理完启动时目录里的现有文件后就没有后续监听逻辑,自然不会自动处理后续新增的文件。
解决方案
使用.NET 内置的FileSystemWatcher组件即可实现目录变化的自动监听,不需要写复杂的轮询逻辑,修改成本极低,你原来的打印、移动文件的代码完全不用改动,只需要新增监听相关的逻辑即可。
完整修改后代码
using System.IO; using System.ServiceProcess; using System.Threading; public partial class Service1 : ServiceBase { // 新增全局目录监听器变量 private FileSystemWatcher _fileWatcher; public Service1() { InitializeComponent(); } protected override void OnStart(string[] args) { try { // 先处理服务启动时已经存在的文件 Print(); // 初始化监听器,绑定你的源文件目录 _fileWatcher = new FileSystemWatcher(@"C:\fold"); // 绑定新文件创建的触发事件 _fileWatcher.Created += OnNewFileCreated; // 开启监听 _fileWatcher.EnableRaisingEvents = true; } catch (Exception ex) { File.AppendAllText(@"C:\fold1\Log.txt", $"服务启动失败:{ex.ToString()}{Environment.NewLine}"); } } // 新增:新文件创建时自动触发的方法 private void OnNewFileCreated(object sender, FileSystemEventArgs e) { try { // 等待1秒,确保大文件完全复制完成,避免文件占用报错 Thread.Sleep(1000); // 直接调用你原来的打印逻辑即可 Print(); } catch (Exception ex) { File.AppendAllText(@"C:\fold1\Log.txt", $"新文件处理失败:{ex.ToString()}{Environment.NewLine}"); } } public static void Print() { //Print & Move the files after printing DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold"); DirectoryInfo target = new DirectoryInfo(@"C:\fold1"); foreach (FileInfo fi in sourceinfo.GetFiles()) { if (fi.Length != 0) { System.Diagnostics.Process process = new System.Diagnostics.Process(); process.StartInfo.CreateNoWindow = true; process.StartInfo.Verb = "print"; process.StartInfo.FileName = fi.FullName; process.StartInfo.UseShellExecute = true; process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; process.Start(); if (!process.WaitForExit(10000)) process.Kill(); } MoveFile(fi.FullName); } } public static void MoveFile(string Filename) { string SourcePath = @"C:\fold"; string targetpath = @"C:\fold1"; if (!Directory.Exists(targetpath)) { Directory.CreateDirectory(targetpath); } string[] sourceFiles = Directory.GetFiles(SourcePath); foreach (string sourcefile in sourceFiles) { string mfilename = Path.GetFullPath(sourcefile); string mname = Path.GetFileName(sourcefile); if (mfilename == Filename) { string distnition = Path.Combine(targetpath, mname); File.Move(mfilename, distnition); } } } protected override void OnStop() { try { // 停止监听并释放资源 if (_fileWatcher != null) { _fileWatcher.EnableRaisingEvents = false; _fileWatcher.Dispose(); } // 处理服务停止时还留在源目录的文件 DirectoryInfo sourceinfo = new DirectoryInfo(@"C:\fold"); DirectoryInfo target = new DirectoryInfo(@"C:\fold1"); foreach (FileInfo fi in sourceinfo.GetFiles()) { MoveFile(fi.FullName); } } catch (Exception ex) { File.AppendAllText(@"C:\fold1\Log.txt", $"服务停止出错:{ex.ToString()}{Environment.NewLine}"); } } }
注意事项
- 给服务运行的账号开放
C:\fold和C:\fold1两个目录的读写权限,否则会出现文件操作报错 - 如果需要处理超大文件,可以把
Thread.Sleep(1000)的等待时间调长,避免文件还没复制完成就被读取 - 单个文件处理出错不会影响整个服务运行,错误日志都会写入
C:\fold1\Log.txt方便排查
内容的提问来源于stack exchange,提问作者Ramadan Abdinour
相关产品推荐
相关产品推荐

