- 标题:
通过文件后缀名获取关联可执行程序 - 标签:
AutoHotkey | AHK | DllCall | P/Invoke | 平台调用 | associated executable | 关联可执行程序 | file suffix name | 文件后缀名 | run program | 启动程序 | open file | 打开文件 | Windows develop | Windows开发 | Win32 APP | Win32 API | 外部函数 | 外部调用 - 标注:
https://www.jianshu.com/p/522ecf122b07
https://www.jianshu.com/u/1275d25b625e
在尝试打开文件时,我们有时需要预先获取文件的关联程序。这么做可以获取程序的进程信息,以便对变化做出及时的响应。
本文是这篇文章的移植。
-
预置声明
为方便起见,函数需要预置一些必要声明。您也可以自行剔除不必要的部分。
class Winerror { static S_OK := 0x00000000 static E_ABORT := 0x80004004 static E_ACCESSDENIED := 0x80070005 static E_FAIL := 0x80004005 static E_HANDLE := 0x80070006 static E_INVALIDARG := 0x80070057 static E_NOINTERFACE := 0x80004002 static E_NOTIMPL := 0x80004001 static E_OUTOFMEMORY := 0x8007000E static E_POINTER := 0x80004003 static E_UNEXPECTED := 0x8000FFFF } ; Winerror class Windef { static MAX_PATH := 260 } ; Windef class Shlwapi { ; https://learn.microsoft.com/zh-cn/windows/win32/shell/str class ASSOCF { static NONE := 0x00000000 static INIT_NOREMAPCLSID := 0x00000001 static INIT_BYEXENAME := 0x00000002 static OPEN_BYEXENAME := 0x00000002 static INIT_DEFAULTTOSTAR := 0x00000004 static INIT_DEFAULTTOFOLDER := 0x00000008 static NOUSERSETTINGS := 0x00000010 static NOTRUNCATE := 0x00000020 static VERIFY := 0x00000040 static REMAPRUNDLL := 0x00000080 static NOFIXUPS := 0x00000100 static IGNOREBASECLASS := 0x00000200 static INIT_IGNOREUNKNOWN := 0x00000400 static INIT_FIXED_PROGID := 0x00000800 static IS_PROTOCOL := 0x00001000 static INIT_FOR_FILE := 0x00002000 } ; https://learn.microsoft.com/zh-cn/windows/win32/api/shlwapi/ne-shlwapi-assocstr class ASSOCSTR { static COMMAND := 1 static EXECUTABLE := 2 static FRIENDLYDOCNAME := 3 static FRIENDLYAPPNAME := 4 static NOOPEN := 5 static SHELLNEWVALUE := 6 static DDECOMMAND := 7 static DDEIFEXEC := 8 static DDEAPPLICATION := 9 static DDETOPIC := 10 static INFOTIP := 11 static QUICKTIP := 12 static TILEINFO := 13 static CONTENTTYPE := 14 static DEFAULTICON := 15 static SHELLEXTENSION := 16 static DROPTARGET := 17 static DELEGATEEXECUTE := 18 static SUPPORTED_URI_PROTOCOLS := 19 static PROGID := 20 static APPID := 21 static APPPUBLISHER := 22 static APPICONREFERENCE := 23 static MAX := 24 } } ; Shlwapi
-
函数实现
; 查询与指定后缀名相关联的可执行文件路径. ; FileSuffixName: 可供系统响应的完整后缀名. 例如`.txt`. ; -> 关联程序的标准化完整路径. 失败时返回false. static GetAssociatedExecutablePath(FileSuffixName) { Result_IsValid := false, AQS := Winerror.E_FAIL ; 定义内部判别默认值. ; 此段查询关联程序的DDE名称, 可能得到缺省值OpenWith. OT_Result := Buffer(Windef.MAX_PATH * 16 / 8), IO_ResultCount := NumPut("int", Windef.MAX_PATH, Buffer(32)) DllCall("Shlwapi\AssocQueryString" ; 重新初始化参数LPTSTR*和DWORD*. , "int", Shlwapi.ASSOCF.NONE, "int", Shlwapi.ASSOCSTR.DDEAPPLICATION, "str", FileSuffixName, "str", "open" , "ptr", OT_Result, "int*", IO_ResultCount, "int") if (StrGet(OT_Result) IO_ResultCount == "OpenWith") goto EXIT ; 此段查询关联的可执行程序, (经由先前分支所致)不会得到缺省值OpenWith的路径(打开未知文件的系统交互程序). OT_Result := Buffer(Windef.MAX_PATH * 16 / 8), IO_ResultCount := NumPut("int", Windef.MAX_PATH, Buffer(32)) AQS := DllCall("Shlwapi\AssocQueryString" ; 重新初始化参数LPTSTR*和DWORD*. , "int", Shlwapi.ASSOCF.NONE, "int", Shlwapi.ASSOCSTR.EXECUTABLE, "str", FileSuffixName, "str", "open" , "ptr", OT_Result, "int*", IO_ResultCount, "int") if (AQS == Winerror.S_OK) { Result_IsValid := true goto EXIT } EXIT: ; 函数唯一返回点. return Result_IsValid ? StrGet(OT_Result) : false } ; GetAssociatedExecutablePath(FileSuffixName)
至此,已可通过指定后缀名获取关联程序。