Что нового

[Файловая система] Как корректно найти иконку файла ?

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Yashied
Кстати, у меня тоже самое (WinXP SP2) :(
Вот что показывает код из "Ответ(а) #16"
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Да кто-нибудь мне все-таки скажет, что у вас записано в

HKEY_CLASSES_ROOT\htmlfile\DefaultIcon
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Ну ребята, вы что, в первый раз иконки в реестре смотрите?

Код:
ConsoleWrite(RegRead('HKCR\' & RegRead('HKCR\.html', '') & '\DefaultIcon', '') & @CR)


Что показывает?
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Yashied [?]
Да кто-нибудь мне все-таки скажет, что у вас записано в
HKEY_CLASSES_ROOT\htmlfile\DefaultIcon

Код:
$var = RegRead("HKEY_CLASSES_ROOT\htmlfile\DefaultIcon", "")
MsgBox(4096, "DefaultIcon:", $var)


Получил : "%1"
 

Garrett

Модератор
Локальный модератор
Сообщения
3,999
Репутация
967
Yashied [?]
Ну ребята, вы что, в первый раз иконки в реестре смотрите?
Вроде нет :blink:
Я же написал - C:\Program Files\Internet Explorer\IEXPLORE.EXE,-17
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
Yashied
У меня на Windows XP SP3 тоже не корректно отображается иконка.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Вот и ответ на твой вопрос. с параметром ".html", функция не может возвратить иконку, т.к. "%1" означает, что иконка берется непосредственно из файла. Аналогичная ситуация и с ".exe", т.е. для каждого ярлыка своя иконка. Просто поменяй "%1" на на конкретный путь и индекс иконки.
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Спасибо, Yashied
Да, но все же это не совсем корректное решение.
На других компьютерах программа не будет корректна.
Т.е. получается все зависит от типа установленной Винды. :(
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
"%1" означает, что у данного типа переменная иконка. Например файлы .cur, .exe, .ico, .url и т.д. Для таких файлов ты не можешь узнать иконку, только по их разрешению, нужен полный путь к файлу. Некоторые программы даже прописывают в раздел "shellex" свобственные ActiveX компоненты для определения иконок, например Adobe Illustrator и др. Я думаю, что в твоем случае, Explorer берет иконку для ".html" из CLSID. Попробуй так:

Код:
$Key = RegRead('HKCR\.html', '')
$CLSID = RegRead('HKCR\' & $Key & '\CLSID', '')
If $CLSID Then
	$Icon = RegRead('HKCR\CLSID\' & $CLSID & '\DefaultIcon', '')
Else
	$Icon = RegRead('HKCR\' & $Key & '\DefaultIcon', '')
EndIf

ConsoleWrite($Icon & @CR)
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Я лично использую это:

Код:
#include <GUIConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <WinAPI.au3>

$FileFolderFullPath = @DesktopDir & "\AutoIt.html"

GUICreate("Get File/Folder Type & Icon", 300, 150)

$aIconInfo = _FileGetIcon($FileFolderFullPath)
$sIconType = _FileGetType($FileFolderFullPath)

GUICtrlCreateButton("", 130, 50, 36, 36, $BS_ICON)
GUICtrlSetImage(-1, $aIconInfo[1], $aIconInfo[2])
GUICtrlCreateLabel($sIconType, 0, 90, 300, 20, $ES_CENTER)

GUISetState()

While GUIGetMsg() <> -3
WEnd

Func _FileGetType($sFile)
	Local $iOld_Opt_EES = Opt("ExpandEnvStrings", 1)
	Local $sRegDefault, $sRegType = "", $sExt
	
	If StringInStr(FileGetAttrib($sFile & "\"), "D") Then
		$sRegDefault = RegRead("HKCR\Folder", "")
		
		If $sRegDefault <> "" Then
			$sRegType = $sRegDefault
		EndIf
	Else
		$sExt = StringRegExpReplace($sFile, '^.*\.(.{0,5})$', '.\1')
		
		If @extended = 0 Or $sExt = $sFile Then
			$sExtSaerch = FileFindFirstFile($sFile & ".*")
			$sExt = StringRegExpReplace(FileFindNextFile($sExtSaerch), '^.*\.', '.')
			$sFile &= $sExt
		EndIf
		
		$sRegDefault = RegRead("HKCR\" & $sExt, "")
		
		If $sRegDefault <> "" Then
			$sRegType = RegRead("HKCR\" & $sRegDefault, "")
		EndIf
		
		If $sRegType = "" Then
			$sRegType = $sExt & "-File"
		EndIf
	EndIf
	
	Opt("ExpandEnvStrings", $iOld_Opt_EES)
	Return $sRegType
EndFunc

Func _FileGetIcon($sFile)
	Local $iOld_Opt_EES = Opt("ExpandEnvStrings", 1)
	Local $sRegDefault = "", $sDefIcon = "", $sExecutable, $sExt, $a_LinkInfo, $hSearch, $sIconFile, $nIcon = 0, $iError = 0, $aRet[3]
	
	If StringInStr(FileGetAttrib($sFile & "\"), "D") Then
		$sRegDefault = RegRead("HKCR\Folder", "")
		
		If $sRegDefault <> "" Then
			$sDefIcon = RegRead("HKCR\Folder\DefaultIcon", "")
		EndIf
	Else
		$sExt = StringRegExpReplace($sFile, '^.*\.', '.')
		
		If $sExt = ".exe" And FileExists($sFile) Then
			Opt("ExpandEnvStrings", $iOld_Opt_EES)
			
			Dim $aRet[3] = [2, $sFile, 0]
			Return $aRet
		EndIf
		
		If $sExt = ".lnk" Then
			$aLinkInfo = FileGetShortcut($sFile)
			
			If Not @error Then
				Opt("ExpandEnvStrings", $iOld_Opt_EES)
				
				If Not FileExists($aLinkInfo[4]) Then
					$a_LinkInfo = _FileGetIcon($aLinkInfo[0])
					
					If Not @error Then
						$aLinkInfo[4] = $a_LinkInfo[1]
						$aLinkInfo[5] = $a_LinkInfo[2]
					EndIf
				EndIf
				
				If $aLinkInfo[5] > 0 Then
					$aLinkInfo[5] = BitNOT($aLinkInfo[5])
				ElseIf $aLinkInfo[5] < 0 Then
					$aLinkInfo[5] = BitNOT($aLinkInfo[5])+1
				EndIf
				
				Dim $aRet[3] = [2, $aLinkInfo[4], $aLinkInfo[5]]
				Return $aRet
			EndIf
		EndIf
		
		If $sExt = $sFile Then
			$hSearch = FileFindFirstFile($sFile & ".*")
			$sExt = StringRegExpReplace(FileFindNextFile($hSearch), '^.*\.', '.')
			$sFile &= $sExt
			FileClose($hSearch)
		EndIf
		
		$sRegDefault = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt, "ProgID")
		
		If $sRegDefault = "" Then
			$sRegDefault = RegRead("HKCR\" & $sExt, "")
		EndIf
		
		If $sRegDefault <> "" Then
			$sDefIcon = RegRead("HKCR\" & $sRegDefault & "\DefaultIcon", "")
			
			If $sDefIcon = "" Then
				$sDefIcon = RegRead("HKCR\" & $sExt & "\DefaultIcon", "")
			EndIf
		Else
			$sRegDefault = RegRead("HKCR\" & $sExt, "PerceivedType")
			
			If $sRegDefault <> "" Then
				$sRegDefault = RegRead("HKCR\SystemFileAssociations\" & $sRegDefault & "\DefaultIcon", "")
			EndIf
		EndIf
	EndIf
	
	If $sDefIcon = "" And $sRegDefault <> "" Then
		$sDefIcon = RegRead("HKCR\" & $sRegDefault & "\CurVer", "") ; ADOBE PERVERSION....
		
		If $sDefIcon Then
			$sDefIcon = RegRead("HKCR\" & $sDefIcon & "\DefaultIcon", "")
		Else
			$sDefIcon = RegRead("HKCR\" & $sRegDefault & "\shell\open\command", "")
			$sDefIcon = StringReplace($sDefIcon, ' "%1"', '')
		EndIf
	EndIf
	
	If $sDefIcon = "" Then
		$sIconFile = "shell32.dll"
	ElseIf Not StringRegExp($sDefIcon, '\A"*%1"*\z') Then
		If StringRegExpReplace($sFile, "^.*\\", "") = "shell32.dll" Then
			$sIconFile = $sFile
			$nIcon = 0
		Else
			Local $aDefIconSplit = StringSplit($sDefIcon, ",")
			
			If IsArray($aDefIconSplit) Then
				$sIconFile = $aDefIconSplit[1]
				
				If $aDefIconSplit[0] > 1 Then
					$nIcon = $aDefIconSplit[2]
				EndIf
			Else
				$iError = 1
			EndIf
		EndIf
	Else
		$sIconFile = $sFile
		$nIcon = 0
	EndIf
	
	If Not FileExists($sIconFile) And Not FileExists(@SystemDir & "\" & $sIconFile) Then
		$sExecutable = _WinAPI_FindExecutable($sFile)
		
		If FileExists($sExecutable) Then
			$sIconFile = $sExecutable
		EndIf
	EndIf
	
	Opt("ExpandEnvStrings", $iOld_Opt_EES)
	
	If $nIcon > 0 Then
		$nIcon = BitNOT($nIcon)
	ElseIf $nIcon < 0 Then
		$nIcon = BitNOT($nIcon)+1
	EndIf
	
	Dim $aRet[3] = [2, StringRegExpReplace($sIconFile, '\A"+|"+\z', ''), $nIcon]
	Return SetError($iError, 0, $aRet)
EndFunc
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
Yashied [?]

Находит, но почему то в виде :
Код:
C:\Program Files\Internet Explorer\iexplore.exe.mui,-17
Приходится избавляться от ".mui"
Откуда это и у всех ли ? (у меня XP SP3)

CreatoR [?]
Я лично использую это:
Определяется "%1"
Кстати если там исправить ошибку (заменить "%1" на '"%1"')
и использовать последний вариант от Yashied , то получим работоспособную ф-ию :
Код:
#include <GUIConstants.au3>
#include <ButtonConstants.au3>
#include <EditConstants.au3>

;$FileFolderFullPath = @DesktopDir & "\AutoIt.html"
$FileFolderFullPath = @ScriptDir & "\1.htm"
;$FileFolderFullPath = @ScriptDir & "\1.lnk"
;$FileFolderFullPath = @ScriptDir & "\2.lnk"
;$FileFolderFullPath = @ScriptDir & "\2.au3"

GUICreate("Get File/Folder Type & Icon", 300, 150)

$aIconInfo = _FileGetIcon($FileFolderFullPath)
$sIconType = _FileGetType($FileFolderFullPath)

GUICtrlCreateButton("", 130, 50, 36, 36, $BS_ICON)
GUICtrlSetImage(-1, $aIconInfo[1], $aIconInfo[2])
GUICtrlCreateLabel($sIconType, 0, 90, 300, 20, $ES_CENTER)

GUISetState()

While GUIGetMsg() <> -3
WEnd

Func _FileGetType($sFile)
    Local $iOld_Opt_EES = Opt("ExpandEnvStrings", 1)
    Local $sRegDefault, $sRegType = "", $sExt
    
    If StringInStr(FileGetAttrib($sFile & "\"), "D") Then
        $sRegDefault = RegRead("HKCR\Folder", "")
        
        If $sRegDefault <> "" Then
            $sRegType = $sRegDefault
        EndIf
    Else
        $sExt = StringRegExpReplace($sFile, '^.*\.(.{0,5})$', '.\1')
        
        If @extended = 0 Or $sExt = $sFile Then
            $sExtSaerch = FileFindFirstFile($sFile & ".*")
            $sExt = StringRegExpReplace(FileFindNextFile($sExtSaerch), '^.*\.', '.')
            $sFile &= $sExt
        EndIf
        
        $sRegDefault = RegRead("HKCR\" & $sExt, "")
        
        If $sRegDefault <> "" Then
            $sRegType = RegRead("HKCR\" & $sRegDefault, "")
        EndIf
        
        If $sRegType = "" Then
            $sRegType = $sExt & "-File"
        EndIf
    EndIf
    
    Opt("ExpandEnvStrings", $iOld_Opt_EES)
    Return $sRegType
EndFunc

Func _FileGetIcon($sFile)
    Local $iOld_Opt_EES = Opt("ExpandEnvStrings", 1)
    Local $sRegDefault = "", $sDefIcon = "", $sExt, $a_LinkInfo, $hSearch, $sIconFile, $nIcon = 0, $iError = 0, $aRet[3]
    
    If StringInStr(FileGetAttrib($sFile & "\"), "D") Then
        $sRegDefault = RegRead("HKCR\Folder", "")
        
        If $sRegDefault <> "" Then
            $sDefIcon = RegRead("HKCR\Folder\DefaultIcon", "")
        EndIf
    Else
        $sExt = StringRegExpReplace($sFile, '^.*\.', '.')
        
        If $sExt = ".exe" And FileExists($sFile) Then
            Opt("ExpandEnvStrings", $iOld_Opt_EES)
            
            Dim $aRet[3] = [2, $sFile, 0]
            Return $aRet
        EndIf
        
        If $sExt = ".lnk" Then
            $aLinkInfo = FileGetShortcut($sFile)
            
            If Not @error Then
                Opt("ExpandEnvStrings", $iOld_Opt_EES)
                
                If Not FileExists($aLinkInfo[4]) Then
                    $a_LinkInfo = _FileGetIcon($aLinkInfo[0])
                    
                    If Not @error Then
                        $aLinkInfo[4] = $a_LinkInfo[1]
                        $aLinkInfo[5] = $a_LinkInfo[2]
                    EndIf
                EndIf
                
                If $aLinkInfo[5] > 0 Then
                    $aLinkInfo[5] = BitNOT($aLinkInfo[5])
                ElseIf $aLinkInfo[5] < 0 Then
                    $aLinkInfo[5] = BitNOT($aLinkInfo[5])+1
                EndIf
                
                Dim $aRet[3] = [2, $aLinkInfo[4], $aLinkInfo[5]]
                Return $aRet
            EndIf
        EndIf
        
        If $sExt = $sFile Then
            $hSearch = FileFindFirstFile($sFile & ".*")
            $sExt = StringRegExpReplace(FileFindNextFile($hSearch), '^.*\.', '.')
            $sFile &= $sExt
            FileClose($hSearch)
        EndIf
        
        $sRegDefault = RegRead("HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\" & $sExt, "ProgID")
        
        If $sRegDefault = "" Then
            $sRegDefault = RegRead("HKCR\" & $sExt, "")
        EndIf
        
        If $sRegDefault <> "" Then
            $sDefIcon = RegRead("HKCR\" & $sRegDefault & "\DefaultIcon", "")
        EndIf
    EndIf
    
    If $sDefIcon = "" Then
        $sIconFile = "shell32.dll"
   ; ElseIf $sDefIcon <> "%1" Then
     ElseIf $sDefIcon <> '"%1"' Then   
		If StringRegExpReplace($sFile, "^.*\\", "") = "shell32.dll" Then
            $sIconFile = $sFile
            $nIcon = 0
        Else
            Local $aDefIconSplit = StringSplit($sDefIcon, ",")
            
            If IsArray($aDefIconSplit) Then
                $sIconFile = $aDefIconSplit[1]
                
                If $aDefIconSplit[0] > 1 Then
                    $nIcon = $aDefIconSplit[2]
                EndIf
            Else
                $iError = 1
            EndIf
        EndIf
    ElseIf $sDefIcon = '"%1"' Then
	  ;ElseIf $sDefIcon = "%1" Then
	  ; $sIconFile = $sFile
	  ; $nIcon = 0
	  $Key = RegRead('HKCR\' &  $sExt, '')
	  $CLSID = RegRead('HKCR\' & $Key & '\CLSID', '')
	  If $CLSID Then
		 $Icon = RegRead('HKCR\CLSID\' & $CLSID & '\DefaultIcon', '')
	  Else
		 $Icon = RegRead('HKCR\' & $Key & '\DefaultIcon', '')
	  EndIf
	  $aIconInfo=StringSplit($Icon, ",")
	  $sIconFile =StringRegExpReplace($aIconInfo[1],"\.mui","")
	  $nIcon =$aIconInfo[2]
	 ConsoleWrite($Icon)
	EndIf
    
    Opt("ExpandEnvStrings", $iOld_Opt_EES)
    
    If $nIcon > 0 Then
        $nIcon = BitNOT($nIcon)
    ElseIf $nIcon < 0 Then
        $nIcon = BitNOT($nIcon)+1
    EndIf
    
    Dim $aRet[3] = [2, StringRegExpReplace($sIconFile, '\A"+|"+\z', ''), $nIcon]
    Return SetError($iError, 0, $aRet)
EndFunc
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
gregaz, _WinAPI_ShellExtractAssociatedIcon() - это системная функция SHGetFileInfo(), и она прекрасно работает (протестировал). Если возвращается неверная иконка, то скорее всего, у тебя какие-нибудь неверные записи в реестре, которые появились с недавних пор.
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
CreatoR [?]
На htm-файле

У меня она и так работоспособная.

Но ведь появляется значение с кавычками : ' "%1" ' , а в функции проверка условий без кавычек : "%1"

Yashied [?]
gregaz, _WinAPI_ShellExtractAssociatedIcon() - это системная функция SHGetFileInfo(), и она прекрасно работает (протестировал)

Тестировал на XP ?
Ведь вроде у Garrett и madmasles тоже было на XP ?



Добавлено:
Сообщение автоматически объединено:

Yashied [?]
Если возвращается неверная иконка, то скорее всего, у тебя какие-нибудь неверные записи в реестре, которые появились с недавних пор.
Да вроде только 10 дней как поставил XP SP3,ну и обновил.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
gregaz [?]
Но ведь появляется значение с кавычками
У меня - нет. Но можно на этот случай добавить рег. выражение. Поправил функцию.
 
Автор
G

gregaz

AutoIT Гуру
Сообщения
1,166
Репутация
299
CreatoR [?]
У меня - нет. Но можно на этот случай добавить рег. выражение. Поправил функцию.

CreatoR
Просьба разъяснить :

Теперь у меня на htm-файле выдается имя самого файла (не приложения).
Да ведь в ф-ии так и заложено :
Код:
If $sDefIcon = "" Then
        $sIconFile = "shell32.dll"
    ElseIf Not StringRegExp($sDefIcon, '\A"*%1"*\z') Then
       ;.............................
    Else
        $sIconFile = $sFile ; ведь это сам файл, а не его приложение  ???
        $nIcon = 0
    EndIf

Разве сам htm-файл даст иконку ?
Разве не надо искать его приложение: C:\Program Files\Internet Explorer\IEXPLORE.EXE ?
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
gregaz [?]
Разве сам htm-файл даст иконку ?
Вообще то если уже дело дошло до этого, значит поиск иконки завершился неудачно, и видимо это проблема в настройке типа файла.
 
Верх