title: NTEventLogHandler from a Python executable
body: <pre><code>import logging, logging.handlers
  
  def main():
      ntl = logging.handlers.NTEventLogHandler("Python Logging Test")
      logger = logging.getLogger("")
      logger.setLevel(logging.DEBUG)
      logger.addHandler(ntl)
      logger.error("This is a '%s' message", "Error")
  
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>The Python (2.7.x) script above writes "This is a 'Error' message" to the Windows Event Viewer. When I run it as a script, I get the expected output. If I convert the script to an executable via PyInstaller, I get an entry in the event log but it says something completely different. </p>
  
  <blockquote>
    <p>The description for Event ID ( 1 ) in Source ( Python Logging Test ) cannot be found. The local computer may not have the necessary registry information or message DLL files to display messages from a remote computer. You may be able to use the /AUXSOURCE= flag to retrieve this description; see Help and Support for details. The following information is part of the event: This is a 'Error' message.</p>
  </blockquote>
  
  <p>This is the command I use to convert the script into an executable: <code>pyinstaller.py --onefile --noconsole my_script.py</code> though the command line parameters do not appear to have any impact on this behaviour and it will suffice to just call <code>pyinstaller.py my_script.py</code>.</p>
  
  <p>I would appreciate any help in understanding what is going on and how I go about fixing this.</p>
  
  <p><strong>Final solution</strong></p>
  
  <p>I didn't want to go down the resource hacker route, as that is going to be a difficult step to automate. Instead, the approach I took was to grab the <code>win32service.pyd</code> file from c:\Python27\Lib\site-packages\win32 and place it next to my executable. The script was then modified pass the full path to the copy of the <code>win32service.pyd</code> file and this works in both script and exe form. The final script is included below:</p>
  
  <pre><code>import logging, logging.handlers
  import os
  import sys
  
  def main():
      base_dir = os.path.dirname(sys.argv[0])
      dllname = os.path.join(base_dir, "win32service.pyd")
  
      ntl = logging.handlers.NTEventLogHandler("Python Logging Test", dllname=dllname)
      logger = logging.getLogger("")
      logger.setLevel(logging.DEBUG)
      logger.addHandler(ntl)
      logger.error("This is a '%s' message", "Error")
  
  
  if __name__ == "__main__":
      main()
  </code></pre>