Setting printer's “KeepPrintedDocuments” prope

2019-04-27 12:44发布

问题:

Here's what we're trying to do:

We want an unobtrusive way of taking everything a client prints on their computer (all of our clients are running POS systems and use Windows XP exclusively) and sending it to us, and we've decided the best way to do that is to create a c# app that sends us their spool files, which we can already parse easily.

However, this requires setting "Keep All Printed Documents" to true. We want to do this in our app rather than manually, for the following reason: some (hundreds) of our clients are, for lack of a better word, dumb. We don't want to force them to mess around in control panel... our tech support people are busy enough as it is.

Here's where I've run into a problem:

string searchQuery = "SELECT * FROM Win32_Printer";
ManagementObjectSearcher searchPrinters = new ManagementObjectSearcher(searchQuery);
ManagementObjectCollection printerCollection = searchPrinters.Get();


foreach (ManagementObject printer in printerCollection)
{
    PropertyDataCollection printerProperties = printer.Properties;
    foreach (PropertyData property in printerProperties)
    {
        if (property.Name == "KeepPrintedJobs")
        {
            printerProperties[property.Name].Value = true;
        }
    }
}

This should, as far as I can tell from several hours of WMI research, set the KeepPrintedJobs property of each printer to true... but its not working. As soon as the foreach loop ends, KeepPrintedJobs is set back to false. We'd prefer to use WMI and not mess around in the registry, but I can't spend forever trying to make this work. Any ideas on what's missing?

回答1:

Try adding a call to Put() on the ManagementObject to explicitly persist the change, like this:

foreach (ManagementObject printer in printerCollection)
{
    PropertyDataCollection printerProperties = printer.Properties;
    foreach (PropertyData property in printerProperties)
    {
        if (property.Name == "KeepPrintedJobs")
        {
            printerProperties[property.Name].Value = true;
        }
    }
    printer.Put();
}

Hope that helps.