sanmoking 发表于 2010-1-29 16:06:55

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

本帖最后由 sanmoking 于 2010-2-5 12:39 编辑

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


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

afan 发表于 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
        $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

sanmoking 发表于 2010-1-29 16:17:26

已解决 ....

非典男人 发表于 2010-1-29 16:24:00

你牛 刚贴出来就自己解决了

maxkingmax 发表于 2010-1-29 19:08:20

我试来获取关联的命令行的,你参考一下!Const $watchfiletype = ".torrent"
$filetype = RegRead("HKCR\" & $watchfiletype, "")
$runexe = RegRead("HKCR\" & $filetype & "\shell\open\command", "")

3mile 发表于 2010-1-29 19:42:30

已解决 ....
sanmoking 发表于 2010-1-29 16:17 http://www.autoitx.com/images/common/back.gif
这。。。算是骗分吗?

llztt 发表于 2010-1-29 19:43:34

很早前写过,用的读取注册表办法,记的有个UDF有问题,如果是未知扩展名,会导致程序异常报错,改改那个UDF就行了。。

不知楼主用的什么办法。。

sanmoking 发表于 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 = ".lnk" Then
                                        $tinfo = FileGetShortcut($p & $flist[$i])
                                        if FileExists($tinfo) then
                                                $ico = $tinfo
                                                if FileExists($ico) then
                                                        $icc = $tinfo
                                                Else
                                                        $ico = $tinfo
                                                EndIf
                                        EndIf
;~                                 Elseif $filename = ".url" Then
;~                                         $tinfo = FileGetShortcut($p & $flist[$i])
;~                                         if StringInStr($tinfo, "\") = 0 Then
;~                                                 $ico = @SystemDir & "\" & $tinfo
;~                                         Else
;~                                                 $ico = StringReplace(StringReplace($tinfo, "%ProgramFiles%", @ProgramFilesDir), "%SystemRoot%\system32", @SystemDir)
;~                                         EndIf
;~                                         if FileExists($ico) then
;~                                                 $icc = $tinfo
;~                                         Else
;~                                                 $tem = RegRead("HKEY_CLASSES_ROOT\" & $filename, "")
;~                                                 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
;~                                                                         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 = ".exe" Then
                                        $ico = $p & $flist[$i]
                                Elseif $filename = "" Then
                                        $ico = @SystemDir & "\user32.dll"
                                Else
                                        $tem = RegRead("HKEY_CLASSES_ROOT\" & $filename, "")
;~                                         MsgBox(0, 0, $filename & @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上。

sanmoking 发表于 2010-1-29 22:05:36

如果有高人能够把上述代码修改的更合理,完善,会选为最佳答案。。。

itljl 发表于 2010-1-29 23:01:06

昨天我刚好写过这个,但源码丢了。
就是通过注册表先读取文件的后缀,如.bat得到文件类型,如.batfile
再从.batfile读取出图标。得到的结果是如
c:\windows\system32\shell32.dll,-3
这样一个图标所有的文件和位置。

sanmoking 发表于 2010-1-30 12:41:50

昨天我刚好写过这个,但源码丢了。
就是通过注册表先读取文件的后缀,如.bat得到文件类型,如.batfile
再 ...
itljl 发表于 2010-1-29 23:01 http://www.autoitx.com/images/common/back.gif


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

itljl 发表于 2010-1-30 13:06:57

回复 10# sanmoking


“去球”?兄弟陕西还是河南?

netegg 发表于 2010-1-30 13:25:12

本帖最后由 netegg 于 2010-1-30 13:38 编辑

#Include <WinAPIEx.au3>
_WinAPI_ShellGetFileInfo

不过要是考虑上面那哥们的情况就不好说了

figons 发表于 2010-1-30 13:45:06

10#说的有道理。。。

sanmoking 发表于 2010-2-1 12:49:51

本帖最后由 sanmoking 于 2010-2-1 12:52 编辑

#Include
_WinAPI_ShellGetFileInfo

不过要是考虑上面那哥们的情况就不好说了
netegg 发表于 2010-1-30 13:25 http://www.autoitx.com/images/common/back.gif

没找到_WinAPI_ShellGetFileInfo这个函数
也没找到WinAPIEx.au3这个文件..麻烦大侠给个门
页: [1] 2 3 4
查看完整版本: 如何根据文件后缀名获取其系统关联的图标