2012-01-09 23 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