我有一個VB6應用程序獲取文件路徑,並且必須檢查此路徑是否指向實際文件,而不是LPT設備,管道等。我正在使用API CreateFile,GetFileType,然後CloseHandle。我是否正確使用CreateFile/GetFileType/CloseHandle?
雖然這段代碼有效,但是當我將一個調試程序附加到程序中時,調試程序斷開了一個異常,說CloseHandle試圖關閉一個不存在的句柄(或者有時會說「無效參數」)。即使我檢查(從代碼中可以看到)處理<> INVALID_HANDLE_VALUE,也會發生這種情況。
我有兩個問題。
首先,我想我需要改變調用的CreateFile,從
handle = CreateFile(FilePath, 0, 0, ByVal 0&, OPEN_EXISTING, 0&, 0&)
...到
handle = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ Or FILE_SHARE_WRITE, 0&, OPEN_EXISTING, FILE_ATTRIBUTES_ENUM.FA_NORMAL, 0&)
我會糾正這個嗎?我只使用CreateFile將句柄傳遞給GetFileType。我實際上沒有對這個文件做任何事情。
二,爲什麼會發生這種情況?我正在檢查是否處理<> INVALID_HANDLE_VALUE,但仍然出現此錯誤!
轉儲結果附在代碼後面。
Private Const OPEN_EXISTING As Long = 3
Private Const FILE_SHARE_READ As Long = &H1
Private Const INVALID_HANDLE_VALUE As Long = -1
Private Const FILE_TYPE_DISK As Long = &H1
Private Const FILE_TYPE_CHAR As Long = &H2
Private Const FILE_TYPE_PIPE As Long = &H3
Private Const FILE_TYPE_REMOTE As Long = &H8000
Private Const FILE_TYPE_UNKNOWN As Long = &H0
Private Declare Function CloseHandle_API Lib "kernel32" Alias "CloseHandle" (ByVal hObject As Long) As Long
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Private Declare Function GetFileType_API Lib "kernel32" Alias "GetFileType" (ByVal hFile As Long) As Long
Private Function IsAnActualFile(FilePath As String, fileType As Long) As Boolean
On Error GoTo errHandle
Dim handle As Long
Dim lpSecurityAttributes As Long
lpSecurityAttributes = 0
handle = CreateFile(FilePath, 0, 0, ByVal 0&, OPEN_EXISTING, 0&, 0&)
If handle <> INVALID_HANDLE_VALUE Then
fileType = GetFileType_API(handle)
If fileType = FILE_TYPE_DISK Then
IsAnActualFile = True
End If
CloseHandle_API handle
End If
errHandle:
If handle <> INVALID_HANDLE_VALUE Then CloseHandle_API handle
End Function
這裏是轉儲:
0:000> kb
ChildEBP RetAddr Args to Child
0018edf0 74ebc463 000038ec 000038ec 0018ee10 ntdll!NtClose+0x12
0018ee00 75141418 000038ec 00000001 0018ee68 KERNELBASE!CloseHandle+0x2d
0018ee10 1107ee38 000038ec 0018f32c 00000000 kernel32!CloseHandleImplementation+0x3f
0018ee68 1107d3ef 19cb5968 0018f32c 0018f158 MyProgram!Document::IsAnActualFile+0xb8
哇,這是尷尬。我甚至沒有注意到我每次都會進入錯誤處理程序。感謝雷米! – user884248