导出事件日志(.evtx)而不“以管理员身份运行”

时间:2016-12-14 02:52:53

标签: c# event-log

问题:是否可以在不以“以管理员身份运行”的流程中导出事件日志?

我正在关注https://msdn.microsoft.com/en-us/library/bb671203(v=vs.90).aspx

的示例代码
using (var els = new EventLogSession())
{
    els.ExportLogAndMessages("Security", PathType.LogName, "*", @"c:\temp\security.evtx");
}

当我使用“以管理员身份运行”运行流程时,此代码成功运行,但在“不以管理员身份运行且异常

时失败”
  

System.UnauthorizedAccessException的:   “试图执行未经授权的操作。”

使用类似的代码访问我的应用程序的事件日志

using (var els = new EventLogSession())
{
    els.ExportLogAndMessages("MyAppLog", PathType.LogName, "*", @"c:\temp\myapplog.evtx");
}

除了异常不同之外,我得到了类似的结果:

  

System.Diagnostics.Eventing.Reader.EventLogException:“目录名无效”

我做错了什么,或者是否有不同的方法可以让我将事件日志导出到.evtx文件而不需要管理员权限?

备注:

3 个答案:

答案 0 :(得分:1)

使用pinvoke.net上显示的方法,对我的自定义应用程序日志(即上例中的MyAppLog)没有管理员权限。这不适用于上面显示的Security日志示例(但我认为这是预期的):

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern IntPtr OpenEventLog(string UNCServerName, string sourceName);

[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern bool BackupEventLog(IntPtr hEventLog, string backupFile);

[DllImport("advapi32.dll", SetLastError = true)]
static extern bool CloseEventLog(IntPtr hEventLog);

void SaveLog(string eventLogName, string destinationDirectory)
{
    string exportedEventLogFileName = Path.Combine(destinationDirectory, eventLogName + ".evtx");

    IntPtr logHandle = OpenEventLog(Environment.MachineName, eventLogName);

    if (IntPtr.Zero != logHandle)
    {
       bool retValue = BackupEventLog(logHandle, exportedEventLogFileName);
       //If false, notify.
       CloseEventLog(logHandle);
    }
}

答案 1 :(得分:1)

  

问题:是否可以在不以"以管理员身份运行的流程中导出事件日志"?

是的,您可以,但前提是您有权访问要导出的事件日志。

然而,你的问题似乎更像是

  

为什么我无法使用EventLogSession导出应用程序的事件日志?弹出EventLogException消息"目录名无效"。

查看EventLogSession的源代码,您可以看到对ExportLogAndMessages的调用将调用本机函数EvtExportLog。如果此函数失败,则通过调用GetLastError来检索错误代码。然后,此本机Windows错误代码为mapped to one of several exceptions

如果发生以下任何错误,则会抛出您遇到的异常:

  • ERROR_FILE_NOT_FOUND(2):系统找不到指定的文件。
  • ERROR_PATH_NOT_FOUND(3):系统找不到指定的路径。
  • ERROR_EVT_CHANNEL_NOT_FOUND(15007):找不到指定的频道。检查通道配置。
  • ERROR_EVT_MESSAGE_NOT_FOUND(15027):消息资源已存在,但在字符串/消息表中找不到该消息。
  • ERROR_EVT_MESSAGE_ID_NOT_FOUND(15028):找不到所需消息的消息ID。
  • ERROR_EVT_PUBLISHER_METADATA_NOT_FOUND(15002):无法在资源中找到发布商元数据。

如果指定了错误的事件日志名称,则ERROR_EVT_CHANNEL_NOT_FOUND是您遇到的错误。我猜这是你的问题。

但是,您可以自己调用EvtExportLog并检查本机错误代码,以便更好地理解调用失败的原因:

[DllImport("kernel32.dll")]
static extern uint GetLastError();

[DllImport("wevtapi.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool EvtExportLog(IntPtr session, string channelPath, string query, string targetFilePath, int flags);

var success = EvtExportLog(IntPtr.Zero, "MyAppLog", "*", @"c:\temp\myapplog.evtx", 1);
if (!success)
{
    var error = GetLastError();
    Console.WriteLine(error);
}

本机错误代码应该能够清楚地表明底层问题是什么。

答案 2 :(得分:0)

这有点陈旧,但是在尝试解决相同的问题时,我又多次提到它。在不提供管理员凭据的情况下,我不知道使用EventLogSession的任何方法。

但是,Windows命令wevtutil将允许您导出到evtx文件,而无需管理员权限。例如,在命令窗口中运行wevtutil epl Application Downloads\export-Application.evtx将导出应用程序事件日志。

要从C#程序运行,可以使用以下方法:

/// <summary>
/// Run wevtutil with the given parameters.
/// </summary>
/// <param name="programPath">Path to wevtutil</param>
/// <param name="programParameters">wevutil parameters</param>
/// <returns></returns>
/// <remarks>https://stackoverflow.com/a/37138255/468523</remarks>
private static (string info, string err) RunWevtUtil(string programPath, string programParameters)
{
    var process = new Process
    {
        StartInfo =
        {
            FileName = programPath,
            Arguments = programParameters,
            UseShellExecute = false,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        }
    };

    process.Start();
    var outputData = process.StandardOutput.ReadToEnd();
    var errorData = process.StandardError.ReadToEnd();
    process.WaitForExit();
    return (outputData, errorData);
}

对于programPath,请提供指向wevtutil的完整路径,通常为@“ C:\ Windows \ System32 \ wevtutil.exe”。对于programParameters,您可以使用@“ epl Application Downloads \ export-Application.evtx”。它返回给出标准和错误输出的字符串元组。

您可以使用Windows命令行来测试您的参数,然后在程序中使用它们。