LocalPrintServer.GetDefaultPrintQueue()在windows服务中不起作用

本文关键字:服务 不起作用 windows GetDefaultPrintQueue LocalPrintServer | 更新日期: 2023-09-27 18:02:04

我想当用户打印一切时弹出一个消息框。下面的代码可以很好地完成这项工作:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Printing;
using System.Management;
using System.Windows.Forms;
namespace CatchByWMI
{
    class Program
    {
        static String prevJobName;
        static void Main(string[] args)
        {
            String strComputerName = "localhost";
            // Create event query to be notified within 1 second of 
            // a change in a service
            WqlEventQuery query = new WqlEventQuery("SELECT * FROM __InstanceOperationEvent WITHIN 0.1 WHERE TargetInstance ISA '"Win32_PrintJob'"");
            ManagementEventWatcher watcher = new ManagementEventWatcher();
            watcher.Scope = new ManagementScope("''''" + strComputerName + "''root''CIMV2");
            watcher.Query = query;
            // times out watcher.WaitForNextEvent in 5 seconds
            watcher.Options.Timeout = new TimeSpan(0, 0, 5);
            watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
            // Start listening
            watcher.Start();
            // Do something in the meantime
            System.Threading.Thread.Sleep(100000);
            // Stop listening
            watcher.Stop();
        }
        private static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
        {
            try
            {
                PrintQueue printQueue = LocalPrintServer.GetDefaultPrintQueue();
                PrintJobInfoCollection coll = printQueue.GetPrintJobInfoCollection();
                String n = Environment.NewLine;
                foreach (PrintSystemJobInfo job in coll)
                {
                    if (!job.Name.Equals(prevJobName))
                    {
                        job.Pause();
                        Console.WriteLine(job.Name);
                        // MB_TOPMOST
                        MessageBox.Show("hello", "Header", MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1, (MessageBoxOptions)0x40000);
                        job.Resume();
                        prevJobName = job.Name;
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}       

然而,当我将它转换为windows服务时,它提示以下错误消息:

获取默认打印机时发生异常。Win32错误,系统找不到指定的文件。

LocalPrintServer.GetDefaultPrintQueue()在windows服务中不起作用

如果有任何解决方案,我将不胜感激。

下面是可行的代码:

        try
        {
            WqlObjectQuery sql = new WqlObjectQuery("SELECT * FROM Win32_PrintJob");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(sql);
            foreach (ManagementObject printJob in searcher.Get())
            {
                if (!prevJobName.Equals(printJob["Name"]))
                {
                    Console.WriteLine(printJob["Name"] + ":" + printJob["Status"]);
                    printJob.InvokeMethod("Pause", null);
                    prevJobName = (String)printJob["Name"];
                    Interop.ShowMessageBox("Click Ok To continue", "MyService Message");
                    printJob.InvokeMethod("Resume", null);
                }
            }
        }
        catch (Exception ex)
        {
            this.EventLog.WriteEntry(ex.ToString());
        }

Interop.cs源代码(该对象用于弹出消息):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace PrintJobMonitor
{
    class Interop
    {
        public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
        public static void ShowMessageBox(string message, string title)
        {
            int resp = 0;
            WTSSendMessage(
                WTS_CURRENT_SERVER_HANDLE,
                WTSGetActiveConsoleSessionId(),
                title, title.Length,
                message, message.Length,
                0, 0, out resp, true);
        }
        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern int WTSGetActiveConsoleSessionId();
        [DllImport("wtsapi32.dll", SetLastError = true)]
        public static extern bool WTSSendMessage(
            IntPtr hServer,
            int SessionId,
            String pTitle,
            int TitleLength,
            String pMessage,
            int MessageLength,
            int Style,
            int Timeout,
            out int pResponse,
            bool bWait);
    }
}

参考网站