How do I programmatically or regularly clear the O

2020-04-11 07:12发布

问题:

We are trying to do some in-house print auditing for printers we have running on a Windows Server 2008 R2. After enabling the log via Event Viewer in:

Applications and Services Logs -> Microsoft -> Windows -> PrintService -> Operational

I'm successfully grabbing events with the ID 307 by tailoring the answer to this question to my needs and then storing those events in a database for use in other applications.

        // Build formatted query string
        string eventID = "307";
        string logSource = "Microsoft-Windows-PrintService/Operational";
        string sQuery = String.Format("*[System/EventID={0}]", eventID);

        // Define query and reader
        var elQuery = new EventLogQuery(logSource, PathType.LogName, sQuery);
        var elReader = new System.Diagnostics.Eventing.Reader.EventLogReader(elQuery);

        // List for holding events
        List<EventRecord> eventList = new List<EventRecord>();
        for (EventRecord eventInstance = elReader.ReadEvent();
            null != eventInstance; eventInstance = elReader.ReadEvent())
        {
            eventList.Add(eventInstance);
        }

What I am unable to do now is clear that log after saving those events.

It allows me to manually clear this log from the Event Viewer, but running:

public static void PrintLogs()
    {
        foreach (var eventLog in EventLog.GetEventLogs())
        {
            Console.WriteLine(eventLog.Log.ToString());
        }
    }

only outputs the higher level logs listed under "Applications and Services Logs":

Application
HardwareEvents
Internet Explorer
Key Management Service   
OAlerts                     // Not sure where OAlerts and
PreEmptive                  // PreEmptive are in the Event Viewer
Security
System
Windows PowerShell

The answer to this question hints that you can't use the EventLog class to access Microsoft-Windows-* event logs.

Is there anything I can do to programmatically clear this specific event log (not just 307 events, but the other ones in the Operational log as well)?

I'd like to set this little program up to run every few minutes, hours, or days automatically, but right now it would be a lot of checking the database for existing events and just adding the few that are new since the last time it ran.

回答1:

I wasn't able to figure out how to do this with existing classes for working with the Event Log, but calling wevtutil from the application seems to be working.

static void Main(string[] args){        
    const string logSource = "Microsoft-Windows-PrintService/Operational";

    /* store print jobs */

    ClearLog(logSource);
}

public static void ClearLog(string logName)
    {            
        var psi = new ProcessStartInfo(
            "wevtutil.exe",
            String.Format("cl {0}", logName));
        psi.Verb = "runas"; // Run as administrator

        using (var p = new Process())
        {
            p.StartInfo = psi;                
            p.Start();              
        }
    }

I set this up to run every hour using the Task Scheduler on our print server and it is working for the time being. Since it is set to run at the highest level, I don't know if "runas" is needed but to clear the log the process does need administration rights.

I realize this has the potential to miss something if a new job hits between the query and clearing the log but we only have about 30 printers and we're not using these numbers for anything more than seeing if there are any we can remove due to low usage.



标签: c# event-log