zoukankan      html  css  js  c++  java
  • HowTO: Create an Event Log Source in code, without the Permission errors

    在我的程序中需要使用EventLog来写日志,在一般的计算机上可以工作,但是在用户一个受限的计算机上却报错误:“The source was not found,but some or all event logs could not be searched, inaccessible logs:secturity. ”的错误。对此感到很奇怪。在网上搜索找到一篇文章,特转发于此。希望对遇到相同问题的朋友有帮助。
    原帖网址: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=439267&SiteID=1

    Permissions for the Event log are driven through the registry. Each event log has an entry in the registry under the following key:
    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog

    To allow the ASP.NET account access to create an event source, you need to have read permission on this and all sub keys, and write permission on the event to which you want to create the event source. Part of your error message says " Inaccessible logs: Security.". Note that "Virtual Server" seems to be another common inaccessible log. This means that for the Security log, the ASP.NET account (MachineName\ASPNET) does not have read access to that key.

    For reasons that I can't explain, the
    EventLog.CreateEventSource() method attempts to search Event Sources under all event logs, not just the event log for which you want to create the source. There are two solutions to this. The first, easiest, and most insecure, is just to give read/write access to all event logs for the ASP.NET account. To do this, follow these steps:
    1. Start -> Run -> regedit.exe
    2. Navigate to My Computer > HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog
    3. Right click this key, select Permissions, and grant the ASPNET account read/write permissions as described above. Note that for the "inaccessible" logs (ie. Security, Virtual Server), you'll also need to grant read access, as permissions have been set to not inherity from the parent key.
    4. Restart IIS (start -> Run  -> iisreset)
    5. Cause the code line that creates the event source to be executed (EventLog.CreateEventSource())
    I don't like this solution because it means that every time a new program that installs its own log (an hence premissions) is installed, the same problem will be encountered.

    The second solution is to bypass the use of the EventLog.CreateEventSource() code, and write your own Event Source addition code, by directly editing adding it to the registry (using code, not regedit!).

    Each event source appears as a key below the event log name. So an event source named "MediaManager" under the event log "Hoksoft" would appear as HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\Hoksoft\MediaManager.

    An "Event Message File" contains resource strings which format your message content based on parameters. The default .NET message file, EventLogMessages.dll, simply has one parameter "%1", which means that your text is inserted as the message content in its entirity. For further reading on this topic, read http://www.codeproject.com/dotnet/evtvwr.asp. Anyway, to avoid message text similar to the following being displayed...

    The description for Event ID ( 0 ) in Source ( MediaManager ) 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:

    ..., it's necessary to set the EventMessageFile parameter (registry string value) under the subkey for the Event Source. The default location of this file is in the following directory:  c:\WINNT\Microsoft.NET\Framework\v2.0.50727\, where v2.0.50727 is the version of the framework you are using (starting with v1.1.x).

    The following partial snippet of code should contain enough detail to dynamically create the event log source, without requiring access to other event logs. To use this code snippet, ensure that the following permissions are set:
    1. Read access to ASPNET on the EventLog key: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog
    2. Read + Write (Full Control OK) on the custom Event Log for your application, eg., for event Log "Hoksoft", on key: HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog\Hoksoft
    3. Ensure that the permissions are set to apply to "this key and subkeys".

    string eventLogName = "Hoksoft";
    string sourceName = "MediaManager";
    EventLog hoksoftLog;
    hoksoftLog = new EventLog();
    hoksoftLog.Log = eventLogName;

    // set default event source (to be same as event log name) if not passed in
    if((sourceName == null) || (sourceName.Trim().Length == 0))
    {
        sourceName = eventLogName;
    }

    hoksoftLog.Source = sourceName;

    // Extra Raw event data can be added (later) if needed
    byte[] rawEventData = Encoding.ASCII.GetBytes("");

    /// Check whether the Event Source exists. It is possible that this may
    /// raise a security exception if the current process account doesn't
    /// have permissions for all sub-keys under
    /// HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\EventLog

    // Check whether registry key for source exists

    string keyName = @"SYSTEM\CurrentControlSet\Services\EventLog\" + eventLogName;

    RegistryKey rkEventSource = Registry.LocalMachine.OpenSubKey(keyName + @"\" + sourceName);

    // Check whether key exists
    if(rkEventSource == null)
    {
        /// Key does not exist. Create key which represents source
        Registry.LocalMachine.CreateSubKey(keyName + @"\" + sourceName);
    }

    /// Now validate that the .NET Event Message File, EventMessageFile.dll (which correctly
    /// formats the content in a Log Message) is set for the event source
    object eventMessageFile = rkEventSource.GetValue("EventMessageFile");

    /// If the event Source Message File is not set, then set the Event Source message file.
    if(eventMessageFile == null)
    {
        /// Source Event File Doesn't exist - determine .NET framework location,
        /// for Event Messages file.
        RegistryKey dotNetFrameworkSettings = Registry.LocalMachine.OpenSubKey(
            @"SOFTWARE\Microsoft\.NetFramework\");

        if(dotNetFrameworkSettings != null)
        {

            object dotNetInstallRoot = dotNetFrameworkSettings.GetValue(
                "InstallRoot",
                null,
                RegistryValueOptions.None);

            if(dotNetInstallRoot != null)
            {
                string eventMessageFileLocation =
    dotNetInstallRoot.ToString() +
    "v" +
    System.Environment.Version.Major.ToString() + "." +
    System.Environment.Version.Minor.ToString()  + "." +
    System.Environment.Version.Build.ToString() +
    @"\EventLogMessages.dll";

                /// Validate File exists
                if(System.IO.File.Exists(
    eventMessageFileLocation))
                {
    /// The Event Message File exists in the anticipated location on the
    /// machine. Set this value for the new Event Source

    // Re-open the key as writable
    rkEventSource = Registry.LocalMachine.OpenSubKey(
        keyName + @"\" + sourceName,
        true);

    // Set the "EventMessageFile" property
    rkEventSource.SetValue(
        "EventMessageFile",
        eventMessageFileLocation,
        RegistryValueKind.String);
                }
            }
        }

        dotNetFrameworkSettings.Close();
    }

    rkEventSource.Close();

    /// Log the message
    hoksoftLog.WriteEntry(
        logMessage,
        type,
        eventId,
        0,
        rawEventData);
  • 相关阅读:
    POI向Excel的单元格中写入图片
    POI导出excel提示ClassNotFoundException: org.apache.commons.codec.digest.DigestUtils
    POI设置Excel单元格样式
    MySQL数据库删除重复数据
    NAVICAT FOR MYSQL 快捷键
    【Eclipse】系统切换JDK版本后,Eclipse中出现JDK版本不一致的错误
    jxl导入Excel文件抛出java.lang.StringIndexOutOfBoundsException异常
    MySQL数据库
    jquery DOM操作
    触发事件
  • 原文地址:https://www.cnblogs.com/yanrongpi/p/585010.html
Copyright © 2011-2022 走看看