C#winfrom.net48 实现自动检测文件夹实现自动打印

主界面区域

  1. 打印机设置:选择3个打印机(按优先级)
  2. 文件夹设置:设置监控和已打印文件夹
  3. 控制按钮:开始/停止监控
  4. 打印队列:显示当前等待打印的文件
  5. 状态信息:显示程序运行状态和日志
    在这里插入图片描述
    在这里插入图片描述
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Printing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Compression;

namespace AutoPrintMonitor
{
    public partial class MainForm : Form
    {
        private FileSystemWatcher fileWatcher;
        private List<string> selectedPrinters;
        private Dictionary<string, bool> printerStatus; // 打印机状态:true=忙碌,false=空闲
        private Queue<PrintJob> printQueue;
        private string saveFolderPath;
        private string printedFolderPath;
        private HashSet<string> processedFiles; // 已处理的文件集合,防止重复打印
        
        private AppSettings appSettings;
        
        public MainForm()
        {
            InitializeComponent();
            InitializeComponents();
            this.FormClosing += MainForm_FormClosing;
        }

        private void InitializeComponents()
        {
            // 加载应用程序设置
            appSettings = AppSettings.Load();
            
            // 初始化变量
            selectedPrinters = new List<string>();
            printerStatus = new Dictionary<string, bool>();
            printQueue = new Queue<PrintJob>();
            processedFiles = new HashSet<string>();
            
            // 设置文件夹路径(优先使用保存的设置)
            saveFolderPath = !string.IsNullOrEmpty(appSettings.SaveFolder) ? 
                appSettings.SaveFolder : Path.Combine(Application.StartupPath, "SAVE");
            printedFolderPath = !string.IsNullOrEmpty(appSettings.PrintedFolder) ? 
                appSettings.PrintedFolder : Path.Combine(Application.StartupPath, "已打印");
            
            // 创建必要的文件夹
            Directory.CreateDirectory(saveFolderPath);
            Directory.CreateDirectory(printedFolderPath);
            
            // 显示文件夹路径
            txtSaveFolder.Text = saveFolderPath;
            txtPrintedFolder.Text = printedFolderPath;
            
            // 恢复已处理的文件列表
            foreach (var file in appSettings.ProcessedFiles)
            {
                processedFiles.Add(file);
            }
            
            // 初始化文件监控器
            InitializeFileWatcher();
            
            // 加载可用的打印机
            LoadAvailablePrinters();
            
            // 恢复打印机选择
            if (!string.IsNullOrEmpty(appSettings.Printer1))
                cmbPrinter1.Text = appSettings.Printer1;
            if (!string.IsNullOrEmpty(appSettings.Printer2))
                cmbPrinter2.Text = appSettings.Printer2;
            if (!string.IsNullOrEmpty(appSettings.Printer3))
                cmbPrinter3.Text = appSettings.Printer3;
        }

        private void InitializeFileWatcher()
        {
            fileWatcher = new FileSystemWatcher(saveFolderPath);
            fileWatcher.Filter = "*.pdf";
            fileWatcher.Created += OnFileCreated;
            fileWatcher.EnableRaisingEvents = true;
        }

        private void LoadAvailablePrinters()
        {
            // 获取系统所有打印机
            var printServer = new LocalPrintServer();
            var printQueues = printServer.GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
            
            foreach (var queue in printQueues)
            {
                if (!queue.IsInError && !queue.IsOffline)
                {
                    cmbPrinter1.Items.Add(queue.Name);
                    cmbPrinter2.Items.Add(queue.Name);
                    cmbPrinter3.Items.Add(queue.Name);
                }
            }
        }

        private void OnFileCreated(object sender, FileSystemEventArgs e)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<object, FileSystemEventArgs>(OnFileCreated), sender, e);
                return;
            }

            // 检查文件是否已处理
            if (processedFiles.Contains(e.FullPath))
                return;

            // 等待文件完全写入
            System.Threading.Thread.Sleep(1000);

            // 添加5秒延迟后再执行打印操作
            UpdateStatus($"检测到新文件: {e.Name},等待5秒后开始处理...");
            
            // 使用Task.Delay实现异步延迟
            Task.Delay(5000).ContinueWith(t =>
            {
                if (InvokeRequired)
                {
                    Invoke(new Action(() => ProcessFileAfterDelay(e)));
                }
                else
                {
                    ProcessFileAfterDelay(e);
                }
            });
        }

        private void ProcessFileAfterDelay(FileSystemEventArgs e)
        {
            // 再次检查文件是否已处理(防止重复处理)
            if (processedFiles.Contains(e.FullPath))
                return;

            // 检查文件名是否符合规则格式
            if (!IsFileNameValid(e.Name))
            {
                UpdateStatus($"文件名不符合规则格式,跳过处理: {e.Name}");
                processedFiles.Add(e.FullPath); // 标记为已处理,避免重复检查
                return;
            }

            // 解析文件名获取打印参数
            var printParams = ParseFileName(Path.GetFileNameWithoutExtension(e.Name));
            
            // 创建打印任务
            var printJob = new PrintJob
            {
                FilePath = e.FullPath,
                FileName = e.Name,
                PrintParams = printParams,
                CreatedTime = DateTime.Now
            };

            // 添加到打印队列
            printQueue.Enqueue(printJob);
            processedFiles.Add(e.FullPath);
            
            // 更新界面
            UpdateQueueDisplay();
            
            UpdateStatus($"开始处理文件: {e.Name}");
            
            // 开始打印处理
            ProcessPrintQueue();
        }

        private bool IsFileNameValid(string fileName)
        {
            // 移除文件扩展名
            string fileNameWithoutExt = Path.GetFileNameWithoutExtension(fileName);
            
            // 移除"打印"后缀(如果存在)
            if (fileNameWithoutExt.EndsWith("打印"))
            {
                fileNameWithoutExt = fileNameWithoutExt.Substring(0, fileNameWithoutExt.Length - 2);
            }
            
            // 检查文件名格式:文件名-姓名-单面/双面-纸张大小
            var parts = fileNameWithoutExt.Split('-');
            
            // 文件名必须包含至少4个部分
            if (parts.Length < 4)
            {
                return false;
            }
            
            // 检查每个部分是否为空
            foreach (var part in parts)
            {
                if (string.IsNullOrWhiteSpace(part))
                {
                    return false;
                }
            }
            
            // 检查打印面格式(第3部分)
            string printSide = parts[2].Trim();
            if (!printSide.Contains("单面") && !printSide.Contains("双面"))
            {
                return false;
            }
            
            // 检查纸张大小格式(第4部分)
            string paperSize = parts[3].Trim();
            if (!paperSize.Contains("A3") && !paperSize.Contains("A4"))
            {
                return false;
            }
            
            return true;
        }

        private PrintParameters ParseFileName(string fileName)
        {
            var parameters = new PrintParameters();
            
            // 移除"打印"后缀(如果存在)
            if (fileName.EndsWith("打印"))
            {
                fileName = fileName.Substring(0, fileName.Length - 2);
            }
            
            // 解析文件名格式:文件名-姓名-单面/双面-纸张大小
            var parts = fileName.Split('-');
            
            if (parts.Length >= 4)
            {
                parameters.FileName = parts[0].Trim();
                parameters.PersonName = parts[1].Trim();
                
                // 解析打印面
                string printSide = parts[2].Trim();
                if (printSide.Contains("双面"))
                {
                    parameters.Duplex = true;
                    if (printSide.Contains("长边"))
                        parameters.DuplexMode = "长边";
                    else if (printSide.Contains("短边"))
                        parameters.DuplexMode = "短边";
                    else
                        parameters.DuplexMode = "长边"; // 默认长边
                }
                else
                {
                    parameters.Duplex = false;
                    parameters.DuplexMode = "";
                }
                
                // 解析纸张大小
                string paperSize = parts[3].Trim();
                if (paperSize.Contains("A4"))
                    parameters.PaperSize = "A4";
                else if (paperSize.Contains("A3"))
                    parameters.PaperSize = "A3";
                else
                    parameters.PaperSize = "A4"; // 默认A4
                
                // 解析彩色打印信息(如果文件名包含"彩色""color",则认为是彩色打印)
                parameters.IsColorPrint = fileName.ToLower().Contains("彩色") || fileName.ToLower().Contains("color");
            }
            else
            {
                // 如果文件名格式不符合预期,使用默认设置
                parameters.FileName = fileName;
                parameters.PersonName = "未知";
                parameters.Duplex = false;
                parameters.PaperSize = "A4";
                parameters.IsColorPrint = false;
            }
            
            return parameters;
        }

        private void ProcessPrintQueue()
        {
            if (printQueue.Count == 0) return;

            // 获取下一个打印任务(但不从队列中移除)
            var nextJob = printQueue.Peek();
            
            // 查找空闲打印机(根据打印参数)
            string availablePrinter = FindAvailablePrinter(nextJob.PrintParams);
            
            if (!string.IsNullOrEmpty(availablePrinter))
            {
                var printJob = printQueue.Dequeue();
                
                // 标记打印机为忙碌状态
                printerStatus[availablePrinter] = true;
                
                // 开始打印
                Task.Run(() => ExecutePrintJob(printJob, availablePrinter));
            }
        }

        private string FindAvailablePrinter(PrintParameters printParams = null)
        {
            // 如果启用了智能打印机选择且有打印参数,使用打印机配置系统
            if (appSettings.EnableSmartPrinterSelection && printParams != null)
            {
                string smartPrinter = appSettings.PrinterConfig.GetPrinterForParameters(printParams, printerStatus);
                if (!string.IsNullOrEmpty(smartPrinter))
                {
                    UpdateStatus("智能选择打印机: " + smartPrinter);
                    return smartPrinter;
                }
            }
            
            // 如果指定了打印参数且为彩色打印,直接使用第3号打印机(兼容旧逻辑)
            if (printParams != null && printParams.IsColorPrint)
            {
                string printer3 = cmbPrinter3.Text;
                if (!string.IsNullOrEmpty(printer3) && 
                    printerStatus.ContainsKey(printer3) && 
                    !printerStatus[printer3])
                {
                    UpdateStatus("检测到彩色打印,直接使用第3号打印机");
                    return printer3;
                }
            }
            
            // 按优先级检查打印机状态
            var printers = new[] { cmbPrinter1.Text, cmbPrinter2.Text, cmbPrinter3.Text };
            
            foreach (var printer in printers)
            {
                if (!string.IsNullOrEmpty(printer) && 
                    printerStatus.ContainsKey(printer) && 
                    !printerStatus[printer])
                {
                    return printer;
                }
            }
            
            return null;
        }

        private void ExecutePrintJob(PrintJob job, string printerName)
        {
            try
            {
                // 检查打印参数并添加相应提示
                string printModeInfo = "";
                if (job.PrintParams != null)
                {
                    // 检查双面打印
                    if (job.PrintParams.Duplex)
                    {
                        printModeInfo = $" (双面{job.PrintParams.DuplexMode} - {job.PrintParams.PaperSize})";
                        UpdateStatus($"检测到双面打印配置: 模式={job.PrintParams.DuplexMode}, 纸张={job.PrintParams.PaperSize}");
                    }
                    
                    // 检查彩色打印
                    if (job.PrintParams.IsColorPrint)
                    {
                        printModeInfo += " [彩色打印]";
                        UpdateStatus($"检测到彩色打印配置,使用第3号打印机");
                    }
                }
                
                UpdateStatus($"开始打印: {job.FileName} -> {printerName}{printModeInfo}");
                
                // 使用PDF打印服务进行实际打印
                var pdfPrintService = new PdfPrintService();
                bool printSuccess = pdfPrintService.PrintPdfFile(job.FilePath, printerName, job.PrintParams);
                
                if (printSuccess)
                {
                    // 打印完成后移动文件到已打印文件夹
                    MoveFileToPrintedFolder(job.FilePath);
                    UpdateStatus($"打印完成: {job.FileName}{printModeInfo}");
                }
                else
                {
                    UpdateStatus($"打印失败: {job.FileName}");
                }
                
                // 标记打印机为空闲状态
                printerStatus[printerName] = false;
                
                // 继续处理队列中的下一个任务
                ProcessPrintQueue();
            }
            catch (Exception ex)
            {
                UpdateStatus($"打印错误: {ex.Message}");
                printerStatus[printerName] = false;
                ProcessPrintQueue();
            }
        }

        private void MoveFileToPrintedFolder(string filePath)
        {
            try
            {
                string fileName = Path.GetFileName(filePath);
                string destPath = Path.Combine(printedFolderPath, fileName);
                
                // 如果目标文件已存在,添加时间戳
                if (File.Exists(destPath))
                {
                    string timeStamp = DateTime.Now.ToString("yyyyMMddHHmmss");
                    string newFileName = $"{Path.GetFileNameWithoutExtension(fileName)}_{timeStamp}{Path.GetExtension(fileName)}";
                    destPath = Path.Combine(printedFolderPath, newFileName);
                }
                
                File.Move(filePath, destPath);
            }
            catch (Exception ex)
            {
                UpdateStatus($"移动文件错误: {ex.Message}");
            }
        }

        private void UpdateQueueDisplay()
        {
            if (InvokeRequired)
            {
                Invoke(new Action(UpdateQueueDisplay));
                return;
            }

            lstQueue.Items.Clear();
            foreach (var job in printQueue)
            {
                lstQueue.Items.Add($"{job.FileName} - {job.CreatedTime:HH:mm:ss}");
            }
        }

        private void UpdateStatus(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(UpdateStatus), message);
                return;
            }

            txtStatus.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}\r\n");
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            // 验证打印机选择
            if (string.IsNullOrEmpty(cmbPrinter1.Text) || 
                string.IsNullOrEmpty(cmbPrinter2.Text) || 
                string.IsNullOrEmpty(cmbPrinter3.Text))
            {
                MessageBox.Show("请选择所有三个打印机", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            // 初始化打印机状态
            selectedPrinters.Clear();
            printerStatus.Clear();
            
            selectedPrinters.Add(cmbPrinter1.Text);
            selectedPrinters.Add(cmbPrinter2.Text);
            selectedPrinters.Add(cmbPrinter3.Text);
            
            foreach (var printer in selectedPrinters)
            {
                printerStatus[printer] = false; // 初始状态为空闲
            }

            // 启动文件监控
            fileWatcher.EnableRaisingEvents = true;
            
            btnStart.Enabled = false;
            btnStop.Enabled = true;
            
            UpdateStatus("自动打印监控已启动");
        }

        private void btnStop_Click(object sender, EventArgs e)
        {
            fileWatcher.EnableRaisingEvents = false;
            
            btnStart.Enabled = true;
            btnStop.Enabled = false;
            
            UpdateStatus("自动打印监控已停止");
        }

        private void btnBrowseSaveFolder_Click(object sender, EventArgs e)
        {
            using (var folderDialog = new FolderBrowserDialog())
            {
                folderDialog.Description = "选择监控文件夹";
                folderDialog.SelectedPath = saveFolderPath;
                
                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    saveFolderPath = folderDialog.SelectedPath;
                    txtSaveFolder.Text = saveFolderPath;
                    
                    // 更新设置
                    appSettings.SaveFolder = saveFolderPath;
                    appSettings.Save();
                    
                    // 重新初始化文件监控器
                    fileWatcher.Path = saveFolderPath;
                }
            }
        }

        private void btnBrowsePrintedFolder_Click(object sender, EventArgs e)
        {
            using (var folderDialog = new FolderBrowserDialog())
            {
                folderDialog.Description = "选择已打印文件存放文件夹";
                folderDialog.SelectedPath = printedFolderPath;
                
                if (folderDialog.ShowDialog() == DialogResult.OK)
                {
                    printedFolderPath = folderDialog.SelectedPath;
                    txtPrintedFolder.Text = printedFolderPath;
                    
                    // 更新设置
                    appSettings.PrintedFolder = printedFolderPath;
                    appSettings.Save();
                }
            }
        }

        private void btnPrinterConfig_Click(object sender, EventArgs e)
        {
            using (var configForm = new PrinterConfigForm())
            {
                // 传递当前设置
                configForm.PrinterConfiguration = appSettings.PrinterConfig;
                configForm.EnableSmartPrinterSelection = appSettings.EnableSmartPrinterSelection;
                
                if (configForm.ShowDialog() == DialogResult.OK)
                {
                    // 保存新的配置
                    appSettings.PrinterConfig = configForm.PrinterConfiguration;
                    appSettings.EnableSmartPrinterSelection = configForm.EnableSmartPrinterSelection;
                    appSettings.Save();
                    
                    UpdateStatus("打印机配置已更新");
                }
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 保存当前设置
            appSettings.Printer1 = cmbPrinter1.Text;
            appSettings.Printer2 = cmbPrinter2.Text;
            appSettings.Printer3 = cmbPrinter3.Text;
            
            // 保存已处理的文件列表
            appSettings.ProcessedFiles.Clear();
            appSettings.ProcessedFiles.AddRange(processedFiles);
            
            appSettings.Save();
        }
    }

    public class PrintJob
    {
        public string FilePath { get; set; }
        public string FileName { get; set; }
        public PrintParameters PrintParams { get; set; }
        public DateTime CreatedTime { get; set; }
    }

    public class PrintParameters
    {
        public string FileName { get; set; }
        public string PersonName { get; set; }
        public bool Duplex { get; set; }
        public string DuplexMode { get; set; }
        public string PaperSize { get; set; }
        public bool IsColorPrint { get; set; }
    }
}

源码:https://download.csdn.net/download/weixin_43050480/92230433

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐