[VB.NET]用FindExecutable API取得開啟文件用的執行檔位置
FindExecutable API可用來取得開啟文件用的執行檔位置,像是Doc檔就用Word開啟、Pdf檔就用Adobe開啟,這道API就是可以找到開啟文件用的執行檔位置。
該API的函式原型如下:
HINSTANCE FindExecutable(
__in LPCTSTR lpFile,
__in_opt LPCTSTR lpDirectory,
__out LPTSTR lpResult
);
在VB.NET可像下面這樣宣告該API
Private Shared Function FindExecutable(ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As StringBuilder) As Integer
End Function
傳入文件路徑、 預設目錄、與存放開啟用執行檔位置的變數即可。值得注意的是,該API的回傳值若大於32,則表示該API執行無誤。若回傳的值小於32,則有可能是檔案找不到、文件類型未設定預設開啟的執行檔、或是記憶體不足等。
SE_ERR_FNF (2) | 指定的檔案不存在 |
SE_ERR_NOASSOC (31) | 沒有對應用來開啟的執行檔 |
SE_ERR_OOM (8) | Windows XP only. 系統記憶體資源不足 |
為方便使用該API,可整理成下面類別
Imports System.Text
Imports System.IO
Public Class NoAssociatedFileTypeException
Inherits ApplicationException
End Class
Public Class Win32API
Const SE_ERR_FNF As Integer = 2
Const SE_ERR_OOM As Integer = 8
Const SE_ERR_NOASSOC As Integer = 31
<Runtime.InteropServices.DllImport("shell32.DLL", EntryPoint:="FindExecutable")> _
Private Shared Function FindExecutable(ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As StringBuilder) As Integer
End Function
Public Shared Function GetAssociatedExeFile(ByVal file As String, Optional ByVal throwException As Boolean = True) As String
Dim sb As New StringBuilder(512)
Dim result As Integer = FindExecutable(file, Nothing, sb)
If result > 32 Then
Return sb.ToString
Else
If Not throwException Then
Return String.Empty
End If
Select Case result
Case SE_ERR_FNF
Throw New FileNotFoundException
Case SE_ERR_NOASSOC
Throw New NoAssociatedFileTypeException
Case SE_ERR_OOM
Throw New OutOfMemoryException
End Select
Throw New Exception
End If
End Function
End Class
或整理成擴充FileInfo類別的方法
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.IO
Public Class NoAssociatedFileTypeException
Inherits ApplicationException
End Class
Module FileInfoExtension
Const SE_ERR_FNF As Integer = 2
Const SE_ERR_OOM As Integer = 8
Const SE_ERR_NOASSOC As Integer = 31
<Runtime.InteropServices.DllImport("shell32.DLL", EntryPoint:="FindExecutable")> _
Private Function FindExecutable(ByVal lpFile As String, ByVal lpDirectory As String, ByVal lpResult As StringBuilder) As Integer
End Function
<Extension()> _
Public Function GetAssociatedExeFile(ByVal fileInfo As FileInfo, Optional ByVal throwException As Boolean = True) As String
Dim sb As New StringBuilder(512)
Dim result As Integer = FindExecutable(fileInfo.FullName, Nothing, sb)
If result > 32 Then
Return sb.ToString
Else
If Not throwException Then
Return String.Empty
End If
Select Case result
Case SE_ERR_FNF
Throw New FileNotFoundException
Case SE_ERR_NOASSOC
Throw New NoAssociatedFileTypeException
Case SE_ERR_OOM
Throw New OutOfMemoryException
End Select
Throw New Exception
End If
End Function
End Module
使用上就會像下面這樣: