2012-01-09 26 views
2

我试图打开使用OpenBackupEventLog功能在Windows 7 x64的机器上采用.evtx文件,但是我不断获取ERROR_FILE_NOT_FOUND(错误代码2)即使该文件确实存在。ERROR_FILE_NOT_FOUND意外返回OpenBackupEventLog功能

我的P/Invoke声明/地步,我所说的文件是:

[DllImport("advapi32.dll", SetLastError = true, ExactSpelling = false, EntryPoint = "OpenBackupEventLog")] 
public static extern IntPtr OpenBackupEventLog(
    [MarshalAs(UnmanagedType.LPTStr)]string uncServerName, 
    [MarshalAs(UnmanagedType.LPTStr)]string fileName); 

IntPtr ptr = NativeMethods.OpenBackupEventLog(null, filename); 
if (ptr == IntPtr.Zero && File.Exists(filename)) 
{ 
    // This exception is thrown and so the file does exist 
    throw new Win32Exception(string.Format("Failed to open event log archive '{0}'", filename)); 
} 

注意,这是一个x86的过程中。

我能想到的唯一的问题是,问题归结为Unicode/ANSI编组(以前我记得取而代之的是ERROR_INVALID_PARAMETER),但是我仔细检查过,并且在编组时没有任何效果。

为什么无法打开文件/我该如何诊断?

+1

由于您怀疑字符串编组,我建议尝试没有这些显式属性的字符串参数。至于进一步诊断:检查此方法是否由[ProcMon](http://technet.microsoft.com/en-us/sysinternals/bb896645)记录;如果是这样,它会显示您正在访问的文件的确切名称。 – 2012-01-09 14:10:38

+0

噢,还有_do_在x64过程中尝试它以消除重定向层将您搞砸的可能性。这些文件在'%SYSTEMROOT%\ system32'中吗? (C:\ Windows \ system32) - 那肯定是一个很大的嫌疑犯。 – 2012-01-09 14:12:10

+0

@romkyns这些文件在我的桌面 – Justin 2012-01-09 17:54:09

回答

1
[DllImport("advapi32.dll", ..., EntryPoint = "OpenBackupEventLog")] 

EntryPoint属性是您的问题来源。导出的函数名称是OpenBackupEventLogA和OpenBackupEventLogW。分别是ANSI和这个函数的Unicode版本。您的声明将使用ANSI版本,因为您没有指定CharSet属性。

当ExactSpelling = false(默认值)时,pinvoke编组器可以自动查找A和W版本。但是,当你明确指定名称时不行。

使用ANSI版本没有意义,请使用CharSet.Auto并省略EntryPoint。 MarshalAs也是不必要的,字符串已经被封送为LPTStr。因此:

[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern IntPtr OpenBackupEventLog(string uncServerName, string fileName); 
0

由于这是一个64位操作系统和您使用的是32位的应用程序访问文件,此异常的最可能的原因是,OS非常“有益” automatically redirects requestsSystem目录(C:\Windows\system,如)到SysWOW64目录C:\Windows\SysWOW64

幸运的是,内置解决方法:sysnative目录。

当您生成路径文件名,可以使用类似以下内容:

字符串文件路径= @ “%WINDIR%\ sysnative \ winevt \日志\ mylog.evtx”;

但是,只有在将应用程序保留为32位应用程序时才能执行此操作。它无法正确解析为64位应用程序。

+0

根据OP的评论,这不是问题,虽然我也怀疑这个... – 2012-01-09 19:30:44

0

这是一个 编码 Unicode与ANSI问题 - 我似乎设法得到这个以某种方式再次开始工作,但后来意识到它是返回ANSI字符串而不是UNICODE字符串 - 显然我不小心开始使用ANSI这些功能的版本不好。

它现在用以下的PInvoke声明

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "OpenBackupEventLogW")] 
public static extern EventLogHandle OpenBackupEventLog(
    string uncServerName, 
    string fileName); 

的关键点是,我的工作:

  • 删除了MarshalAs属性
  • 添加了CharSet = CharSet.Unicdoe参数设置为我DllImport声明
  • 将W添加到入口点名称
  • 的末尾

请注意,它也似乎工作,如果我从入口点名称的末尾删除W,只要CharSet = CharSet.Unicdoe参数在那里。

+0

这不是一个编码问题。 – 2012-01-11 15:27:24