如何判断默认打印机何时更改?

时间:2013-12-11 20:16:08

标签: c# printing pinvoke rdp

我正在寻找一种方法来检测何时在RDP会话上更改默认打印机。基本上我们正在尝试记录用户上次默认打印机,我觉得执行此任务的最简单方法是检测用户何时更改打印机而不是在注销时捕获默认值。到目前为止,我已经看了几个选项,其中一些是下面的。

解决方案1 ​​

尝试连接到本地打印监视器以检查默认打印机的更改。我找到了这个网址FindPrinterFirstChangeNotification。我认为通过使用PRINTER_CHANGE_SET_PRINTER标志进行过滤可以起作用。但是,当我在UI中更改默认打印机时,我没有收到任何事件。

解决方案2

下一个选项是可能创建一个新的驱动程序,WDK会在打印机更改默认值时捕获。

有没有其他人有关于捕获此事件的任何想法?我不知道是否有任何其他方法可以实现它。

以下是我用于FindFirstPrinterChangeNotification的代码。我能够捕获打印作业本身的事件,但我无法捕获有关更改默认打印机的任何内容。

IntPtr test = IntPtr.Zero;
PRINTER_DEFAULTS defaults = new PRINTER_DEFAULTS { DesiredAccess = PrinterAccessRights.READ_CONTROL };
Printer.OpenPrinter("Microsoft XPS Document Writer", out test, ref defaults);
Operations.Log(new Win32Exception(Marshal.GetLastWin32Error()).Message, System.Diagnostics.EventLogEntryType.Error, 4);
Printer.FindChangedEvent(test);

捕获事件的方法。

public static void FindChangedEvent(IntPtr handle) {
    IntPtr ptr = FindFirstPrinterChangeNotification(handle, (uint)Printer_Change.ALL, 0, null);
    Operations.Log(new Win32Exception(Marshal.GetLastWin32Error()).Message, System.Diagnostics.EventLogEntryType.Error, 4);
    ManualResetEvent _ManualResetEvent = new ManualResetEvent(false);
    _ManualResetEvent.SafeWaitHandle = new SafeWaitHandle(ptr, true);
    RegisteredWaitHandle _RegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(_ManualResetEvent, new WaitOrTimerCallback(PrinterNotifyWaitCallback), null, -1, true);
}

事件方法

private static void PrinterNotifyWaitCallback(object state, bool timedOut) {
    if (timedOut) {
        //Should not happen 
        return;
    } else {

    }
}   

旗帜的结构

[Flags]
public enum Printer_Change : uint {
    ADD_PRINTER = 0x00000001,
    SET_PRINTER = 0x00000002,
    DELETE_PRINTER = 0x00000004,
    FAILED_CONNECTION_PRINTER = 0x00000008,
    PRINTER = 0x000000FF,
    ADD_JOB = 0x00000100,
    SET_JOB = 0x00000200,
    DELETE_JOB = 0x00000400,
    WRITE_JOB = 0x00000800,
    JOB = 0x0000FF00,
    ADD_FORM = 0x00010000,
    SET_FORM = 0x00020000,
    DELETE_FORM = 0x00040000,
    FORM = 0x00070000,
    ADD_PORT = 0x00100000,
    CONFIGURE_PORT = 0x00200000,
    DELETE_PORT = 0x00400000,
    PORT = 0x00700000,
    ADD_PRINT_PROCESSOR = 0x01000000,
    DELETE_PRINT_PROCESSOR = 0x04000000,
    PRINT_PROCESSOR = 0x07000000,
    ADD_PRINTER_DRIVER = 0x10000000,
    SET_PRINTER_DRIVER = 0x20000000,
    DELETE_PRINTER_DRIVER = 0x40000000,
    PRINTER_DRIVER = 0x70000000,
    TIMEOUT = 0x80000000,
    ALL = 0x7777FFFF
}

1 个答案:

答案 0 :(得分:4)

PRINTER_CHANGE_SET_PRINTER标志仅在打印机本身发生更改时触发事件。设置默认打印不会更改该打印机对象。

如果您想要更改默认打印机的通知,请使用注册表监视器监控Device密钥下的HKCU\Software\Microsoft\Windows NT\CurrentVersion\Windows值。

实施RegNotifyChangeKeyValue或使用以下内容: http://www.codeproject.com/Articles/4502/RegistryMonitor-a-NET-wrapper-class-for-RegNotifyC