找回密码
 加入
搜索
查看: 18210|回复: 48

如何根据文件后缀名获取其系统关联的图标

 火... [复制链接]
发表于 2010-1-29 16:06:55 | 显示全部楼层 |阅读模式
悬赏100金钱已解决
本帖最后由 sanmoking 于 2010-2-5 12:39 编辑

急需,记得论坛好像有,没搜出来.现写怕写错了....


已解决,这会忙,回头把自己的方法发出来...

最佳答案

查看完整内容

回复 24# sanmoking 得寸进尺…… 真没错

评分

参与人数 1金钱 +10 收起 理由
pusofalse + 10 感谢主动修改帖子分类为[已解决]。

查看全部评分

发表于 2010-1-29 16:06:56 | 显示全部楼层
回复 24# sanmoking


    得寸进尺…… 真没错
#include <GUIListView.au3>
#include <GUIImageList.au3>
#include <WinAPIEx.au3>
#include <WindowsConstants.au3>
#include <File.au3>

Dim $folder = FileSelectFolder('请选择目标文件夹', '', 4, @MyDocumentsDir)
If @error Then Exit (Msgbox(48, '退出', '没有选择文件夹,退出'))
Dim $a = _FileListToArray($folder, '*', 1)
If $a = 0 Then Exit (Msgbox(48, '退出', '没有选择文件夹,退出'))

GUICreate('MyIconGUI', 280, 400)
$ListView = GUICtrlCreateListView('', 10, 10, 260, 344, $LVS_NOCOLUMNHEADER)
_GUICtrlListView_SetView($ListView, 1)
_GUICtrlListView_InsertColumn($ListView, 0, '', 220)
$hImageList = _GUIImageList_Create(32, 32, 6)
_GUICtrlListView_SetImageList($ListView, $hImageList, 0)
$Button = GUICtrlCreateButton('退出', 105, 361, 70, 23)

For $i = 1 To $a[0]
        $Ext = $folder & '\' & $a[$i]
        $tSHFILEINFO = _WinAPI_ShellGetFileInfo($Ext, BitOR($SHGFI_ICON, $SHGFI_USEFILEATTRIBUTES))
        $hIcon = DllStructGetData($tSHFILEINFO, 'hIcon')
        _GUIImageList_ReplaceIcon($hImageList, -1, $hIcon)
        _GUICtrlListView_AddItem($ListView, $a[$i], $i -1)
        _WinAPI_FreeIcon($hIcon)
Next
GUISetState()

While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3, $Button
                        ExitLoop
        EndSwitch
WEnd
 楼主| 发表于 2010-1-29 16:17:26 | 显示全部楼层
已解决 ....
发表于 2010-1-29 16:24:00 | 显示全部楼层
你牛 刚贴出来就自己解决了
发表于 2010-1-29 19:08:20 | 显示全部楼层
我试来获取关联的命令行的,你参考一下!
Const $watchfiletype = ".torrent"
$filetype = RegRead("HKCR" & $watchfiletype, "")
$runexe = RegRead("HKCR" & $filetype & "\shell\open\command", "")
发表于 2010-1-29 19:42:30 | 显示全部楼层
已解决 ....
sanmoking 发表于 2010-1-29 16:17

这。。。算是骗分吗?
发表于 2010-1-29 19:43:34 | 显示全部楼层
很早前写过,用的读取注册表办法,记的有个UDF有问题,如果是未知扩展名,会导致程序异常报错,改改那个UDF就行了。。

不知楼主用的什么办法。。
 楼主| 发表于 2010-1-29 22:04:02 | 显示全部楼层
Dim $szDrive, $szDir, $szFName, $szExt, $ico = "", $tem, $icc = 0, $cc
                                $filename = _PathSplit($p & $flist[$i], $szDrive, $szDir, $szFName, $szExt)
                                if $filename[4] = ".lnk" Then
                                        $tinfo = FileGetShortcut($p & $flist[$i])
                                        if FileExists($tinfo[0]) then
                                                $ico = $tinfo[4]
                                                if FileExists($ico) then
                                                        $icc = $tinfo[5]
                                                Else
                                                        $ico = $tinfo[0]
                                                EndIf
                                        EndIf
;~                                 Elseif $filename[4] = ".url" Then
;~                                         $tinfo = FileGetShortcut($p & $flist[$i])
;~                                         if StringInStr($tinfo[4], "") = 0 Then
;~                                                 $ico = @SystemDir & "" & $tinfo[4]
;~                                         Else
;~                                                 $ico = StringReplace(StringReplace($tinfo[4], "%ProgramFiles%", @ProgramFilesDir), "%SystemRoot%\system32", @SystemDir)
;~                                         EndIf
;~                                         if FileExists($ico) then
;~                                                 $icc = $tinfo[5]
;~                                         Else
;~                                                 $tem = RegRead("HKEY_CLASSES_ROOT" & $filename[4], "")
;~                                                 if $tem <> "" Then
;~                                                         $tem = RegRead("HKEY_CLASSES_ROOT" & $tem & "\DefaultIcon", "")
;~                                                         if $tem <> "" Then
;~                                                                 $cc = StringInStr($tem, ",", 0, -1)
;~                                                                 if $cc > 0 Then
;~                                                                         $ico = StringLeft($tem, $cc - 1)
;~                                                                         if StringInStr($ico, "") = 0 Then
;~                                                                                 $ico = @SystemDir & "" & $tinfo[4]
;~                                                                         Else
;~                                                                                 $ico = StringReplace(StringReplace($ico, "%ProgramFiles%", @ProgramFilesDir), "%SystemRoot%\system32", @SystemDir)
;~                                                                         EndIf
;~                                                                         if FileExists($ico) = 0 then
;~                                                                                 $ico = @SystemDir & "\user32.dll"
;~                                                                                 $icc = 0
;~                                                                         Else
;~                                                                                 $icc = Abs(StringTrimLeft($tem, $cc))
;~                                                                         EndIf
;~                                                                 Else
;~                                                                         $ico = @SystemDir & "\user32.dll"
;~                                                                 EndIf
;~                                                         Else
;~                                                                 $ico = @SystemDir & "\user32.dll"
;~                                                         EndIf
;~                                                 Else
;~                                                         $ico = @SystemDir & "\user32.dll"
;~                                                 EndIf
;~                                         EndIf
                                Elseif $filename[4] = ".exe" Then
                                        $ico = $p & $flist[$i]
                                Elseif $filename[4] = "" Then
                                        $ico = @SystemDir & "\user32.dll"
                                Else
                                        $tem = RegRead("HKEY_CLASSES_ROOT" & $filename[4], "")
;~                                         MsgBox(0, 0, $filename[4] & @CR & $tem)
                                        if $tem <> "" Then
                                                $tem = RegRead("HKEY_CLASSES_ROOT" & $tem & "\DefaultIcon", "")
;~                                                 MsgBox(0, 0, $tem)
                                                if $tem <> "" Then
                                                        $cc = StringInStr($tem, ",", 0, -1)
                                                        if $cc > 0 Then
                                                                $ico = StringLeft($tem, $cc - 1)
                                                                if StringInStr($ico, "") = 0 Then
                                                                        $ico = @SystemDir & "" & $ico
                                                                Else
                                                                        $ico = StringReplace(StringReplace($ico, "%ProgramFiles%", @ProgramFilesDir), "%SystemRoot%\system32", @SystemDir)
                                                                EndIf
                                                                if FileExists($ico) = 0 then
                                                                        $ico = @SystemDir & "\user32.dll"
                                                                        $icc = 0
                                                                Else
;~                                                                         if StringTrimLeft($tem, $cc) <= 0 Then
                                                                        $icc = Abs(StringTrimLeft($tem, $cc))
;~                                                                         Else
;~                                                                         $icc = Abs(StringTrimLeft($tem, $cc))+1
;~                                                                         EndIf
                                                                EndIf
;~                                                                 MsgBox(0, 0, $ico & @CR & $icc)
                                                        Else
                                                                $ico = @SystemDir & "\user32.dll"
                                                        EndIf
                                                Else
                                                        $ico = @SystemDir & "\user32.dll"
                                                EndIf
                                        Else
                                                $ico = @SystemDir & "\user32.dll"
                                        EndIf
                                EndIf
$ico是图标(库)文件,$icc是图标序号。
不过以上代码再有些情况下获取不到图标,比如mp3等文件关联到有一些播放器时,关联的图标是相关播放器内置图标,貌似au3能获取到图标文件跟序号,但是现实不到gui上。

评分

参与人数 1金钱 +20 收起 理由
afan + 20

查看全部评分

 楼主| 发表于 2010-1-29 22:05:36 | 显示全部楼层
如果有高人能够把上述代码修改的更合理,完善,会选为最佳答案。。。
发表于 2010-1-29 23:01:06 | 显示全部楼层
昨天我刚好写过这个,但源码丢了。
就是通过注册表先读取文件的后缀,如.bat得到文件类型,如.batfile
再从.batfile读取出图标。得到的结果是如
c:\windows\system32\shell32.dll,-3
这样一个图标所有的文件和位置。
 楼主| 发表于 2010-1-30 12:41:50 | 显示全部楼层
昨天我刚好写过这个,但源码丢了。
就是通过注册表先读取文件的后缀,如.bat得到文件类型,如.batfile
再 ...
itljl 发表于 2010-1-29 23:01



    大的原理上是这样的,但是还是有很多特殊情况,比如lnk文件,有些有自定义图标,所以你得读取他的自定义图标跟图表编号,这个au3有专门的函数,但是读出来还得检测它的图标文件是否存在有效,如果没自定义图标就得读取被他快捷的那个文件,如果是exe,就得读取exe本身的图标,如果是其他文件就得读取注册表,但是各种在注册表里也不一定是一样的,比如装了acdsee的系统,图片文件显示的图标就是acdsee的自定义图标,但是注册表里的指向还是原本的系统内置图标,如果你像上述方法读注册表,是读不到的,再比如有些音视频文件关联到自定义播放器后,图标就是播放器内置的,虽然你读取出来了图标位置跟编号,但是au3却不能从这播放器里提取出来图标,貌似跟这程序加了壳有关,还有什么url类型的图标也可以自定义图标,如果没自定义的图标,就得用html的图标,跟lnk又不一样,还有什么屏幕保护文件,其实就是exe,数不胜数的扩展名。。。总之整个过程太浩大了,有一步读错就去求了。。。
发表于 2010-1-30 13:06:57 | 显示全部楼层
回复 10# sanmoking


“去球”?兄弟陕西还是河南?
发表于 2010-1-30 13:25:12 | 显示全部楼层
本帖最后由 netegg 于 2010-1-30 13:38 编辑

#Include <WinAPIEx.au3>
_WinAPI_ShellGetFileInfo

不过要是考虑上面那哥们的情况就不好说了
发表于 2010-1-30 13:45:06 | 显示全部楼层
10#说的有道理。。。
 楼主| 发表于 2010-2-1 12:49:51 | 显示全部楼层
本帖最后由 sanmoking 于 2010-2-1 12:52 编辑
#Include
_WinAPI_ShellGetFileInfo

不过要是考虑上面那哥们的情况就不好说了
netegg 发表于 2010-1-30 13:25


没找到_WinAPI_ShellGetFileInfo这个函数
也没找到WinAPIEx.au3这个文件..麻烦大侠给个门
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-5-10 22:44 , Processed in 0.083303 second(s), 23 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表