I want my C# executable to write to the Application event log using a custom Source name so I can quickly find my events. My application must run under non-admin credentials but creating a custom log name requires administrative credentials. Since I also want to install everything with an Inno-based installer, I can use the period of time I am installing as an admin to setup the custom log name.
Step 1 – Add Installer Callable Method to Create Log Name
I want the Inno installer to call my application after it has installed everything so it can handle the log source creation. I will do this by passing a magic token to my app on the command line that will not occur in production code. I will create the C# application first.
public class Program { /// <summary> /// Specific event log for this app. Will be used for all log writes. /// </summary> public static EventLog AppEventLog { get; set; } /// <summary> /// Name of event log - Same as application without EXE. /// </summary> public static string EventLogSourceName { get; set; } /// <summary> /// If receive this string on commandline at startup, will perform initialization function. /// (Random Guid with dashes removed.) /// </summary> public const string InitializingApplication = "f44e99c47467477f9282b6c1d753924d"; /// <summary> /// Application entry method with command line arguments. /// </summary> /// <param name="args"></param> /// <returns></returns> public static int Main(string[] args) { // Initialize event log name for this app. EventLogSourceName = Assembly.GetExecutingAssembly().GetName().Name; AppEventLog = new EventLog(); AppEventLog.Source = EventLogSourceName; // Test for startup initialization where the Application log Source is created using admin credentials. // Initialization will create log source then exit. // Generally only called from INNO installer. if (args.Count() == 1 && String.Compare(args[0], InitializingApplication, ignoreCase: true) == 0) { InitializeApplication(AppEventLog); return 0; } // Execution picks up here if not called by Inno installer. WriteLocalEventLog("Starting application...", EventLogEntryType.Information); ... } /// <summary> /// Register a new source name in the Application log if not already there. /// </summary> /// <param name="appEventLog">Used to get desired log source name.</param> private static void InitializeApplication(EventLog appEventLog) { // Preforming write will create source in Application log if we have admin creds. if (!EventLog.SourceExists(appEventLog.Source)) { // Source doesn't exist. Create it. appEventLog.WriteEntry("Created event log source for AutoDocGen Renderer."); } }
Step 2 – Create Helper for App to Write to Event Log
Below is a simple implementation of logger. In my actual implementation, I massage the user message to add required header information – but this is sufficient.
/// <summary> /// Write message format to Event Log with specified level. /// </summary> /// <param name="msg">Event log message.</param> /// <param name="eventType">Specify Error/Warning/Information. Defaults to Error if not furnished.</param> public static void WriteLocalEventLog(string msg, EventLogEntryType eventType = EventLogEntryType.Error) { AppEventLog.WriteEntry(msg, eventType); }
Step 3 – Add Install-Time Call By Inno to Application
The final step is to modify the installer so I calls the application with the magic token so it can create the potentially new log Source name. It requires two Inno installer features. Add the following lines to the Package.iss
file. Be aware that the “\
” is the default line continuation character for Inno.
[Setup] ; Force installer to run with administrative credentials. Default message will be used by Inno. PrivilegesRequired=admin
[Run] ; Run the application with a single command line parameter - the magic token. Filename: "{app}\{#MyAppEXE}"; Description: "Register Application log Source Name if necessary"; \ Parameters: "607f7defd8ab406da789daca53a9c073"; StatusMsg: "Register Application Log source name..."; \ Flags: runascurrentuser runhidden
Related
When a log Source is created, it writes information to register. The primary location is Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System
\<SourceName>`. More information on EventLog Sources.