Terenz Posted November 12, 2014 Share Posted November 12, 2014 (edited) I have some problem to find a solution for this, hope you guys has an idea. Pratically: 1) Create a shortcut of a text file ( it can be anything, not only a text file ) 2) Get the icon of that shortcut The main problem is number 2, how i can get the icon from the shortcut of a file? With the build in not work, i have empty value for [4] ;~ FileCreateShortcut(@ScriptDir & "\Text.txt", @DesktopDir & "\TEXT.LINK", @DesktopDir, "") $aShort = FileGetShortcut(@DesktopDir & "\TEXT_LINK.lnk") If IsArray($aShort) Then MsgBox(0, 0, $aShort[4]) MsgBox(0, 0, $aShort[5]) EndIf After i get the executable and the icon index, i need to: 3) Change the path of the shortcut ( like anothereditor.exe Text.txt ) 4) Use the icon from number two ( because if i don't change the icon it will use the anothereditor.exe icon and i don't what it ) So my problem is only one, how to get the executable-icon index from a shortcut of a file. Thanks Edited November 12, 2014 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
Spider001 Posted November 12, 2014 Share Posted November 12, 2014 (edited) i made something in c# for extracting icon's i can't get it to work in autoit script expandcollapse popupusing System; using System.IO; using System.Threading; using System.Drawing; using System.Runtime.InteropServices; namespace Icon_extractor { class Program { static void Main(string[] args) { switch (args.Length) { case 0: uitleg(); break; case 1: if (args[0] == "/?") { uitleg(); } break; case 4: Icon myIcon = Getpicture(Convert.ToString(args[0]), Convert.ToBoolean(args[1])); if (Convert.ToBoolean(args[3])) { Bitmap bmp = myIcon.ToBitmap(); using (FileStream fs = new FileStream(Convert.ToString(args[2]) + ".bmp", FileMode.Create)) bmp.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp); } else { using (FileStream fs = new FileStream(Convert.ToString(args[2]) + ".ico", FileMode.Create)) myIcon.Save(fs); } break; } } static Icon Getpicture(string fName, Boolean smallicon) { Shfileinfo shinfo = new Shfileinfo(); //Use this to get the small Icon if (smallicon) { IntPtr hImgSmall = Win32.SHGetFileInfo(fName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.ShgfiIcon | Win32.ShgfiSmallicon); } else { //Use this to get the large Icon IntPtr hImgLarge = Win32.SHGetFileInfo(fName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.ShgfiIcon | Win32.ShgfiLargeicon); } //The icon is returned in the hIcon member of the shinfo //struct return Icon.FromHandle(shinfo.hIcon); } private static void uitleg() { Console.WriteLine("extract icon to .ico file"); Console.WriteLine("1st parameter file to extract"); Console.WriteLine("2de parameter true = small false = big icon"); Console.WriteLine("3de parameter place and name to save with give no extension"); Console.WriteLine("3de parameter true = bmp false = ico"); Thread.Sleep(10000); } } [StructLayout(LayoutKind.Sequential)] public struct Shfileinfo { public IntPtr hIcon; public IntPtr iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; class Win32 { public const uint ShgfiIcon = 0x100; public const uint ShgfiLargeicon = 0x0; // 'Large icon public const uint ShgfiSmallicon = 0x1; // 'Small icon [DllImport("shell32.dll")] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref Shfileinfo psfi, uint cbSizeFileInfo, uint uFlags); } } compile c# script i do with this bat file dir you must change to yours set oldp=%PATH% set PATH=%PATH%;C:\WINDOWS\Microsoft.NET\Framework\v3.5 csc /out:Icon_extractor.exe /win32icon:icon.ico /platform:anycpu program.cs set PATH=oldp pause on autoit i do it this way If FileExists(@ScriptDir & '\iconsprog\icon.bmp') = 0 Then Run(@ScriptDir & '\Icon_extractor.exe "' & file to extract & '" False "' & @ScriptDir & '\iconsprog\' & name file bmp & '" true', @ScriptDir, @SW_HIDE) Do Sleep(2 * 1000) Until Not ProcessExists("Icon_extractor.exe") EndIf $button = GUICtrlCreateButton('this is button', $posl, $post, $bw, $bh, $BS_MULTILINE) ; icon before text $hImagebtn3 = _GUIImageList_Create(32, 32, 5) _GUIImageList_AddBitmap($hImagebtn3, @ScriptDir & '\iconsprog\' & ico file & ".bmp") _GUICtrlButton_SetImageList($button, $hImagebtn3) .bmp is working best in autoit Edited November 12, 2014 by Spider001 Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 Thanks but i don't think i'll use your solution. I don't need to extract the icon for use it in a shortcut, i'd like the shortcut use the icon registered for that extension. Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
jguinch Posted November 12, 2014 Share Posted November 12, 2014 (edited) Try with this (it looks into the registry) : expandcollapse popup#Include <Array.au3> ; Just for _ArrayDisplay() $aIcon = _GetDefaultIcon(".txt") _ArrayDisplay($aIcon) Func _GetDefaultIcon($sExt) Local $aRet[2] If NOT StringRegExp($sExt, "^\.") Then $sExt = "." & $sExt Local $sFileType = RegRead("HKCR\" & $sExt, "") If $sFileType = "" Then Return SetError(1, 0, "") Local $sDefaultIcon = StringReplace ( RegRead("HKCR\" & $sFileType & "\DefaultIcon", ""), '"', '') If $sDefaultIcon = "" Then Return SetError(1, 0, "") If StringRegExp($sDefaultIcon, ",-?\d+$") Then $aRet = StringRegExp($sDefaultIcon, "(.*),(-?\d+)$", 3) Else $aRet[0] = $sDefaultIcon $aRet[1] = 0 EndIf ; Replaces each environment variable by its expanded value $aRet[0] = _ExpandEnvStrings($aRet[0]) Return $aRet EndFunc Func _ExpandEnvStrings($sString) Local $aVars = StringRegExp($sString, "%([^%]+)%", 3) Local $iCount = 0 If IsArray($aVars) Then For $i = 0 To UBound($aVars) - 1 $sVal = EnvGet($aVars[$i]) If $sVal <> "" Then $sString = StringReplace($sString, "%" & $aVars[$i] & "%", $sVal ) $iCount += 1 EndIf Next SetExtended( $iCount ) Else SetExtended(0) EndIf Return $sString EndFunc Edited November 12, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 Partially work me, 0 is empty and 1 is equal to -102 Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
jguinch Posted November 12, 2014 Share Posted November 12, 2014 (edited) Which extension did you try with ? Can you try to comment to line $aRet[0] = Execute ...... ? Also, what does the ConsoleWrite says ? Edited November 12, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 (edited) Just copy-paste your example. I don't have see the ConsoleWrite The console is correct: %SystemRoot%\system32\imageres.dll,-102 But the $aRet[0] = Execute i think has some problem in it because in the arraydisplay i don't see nothing for 0 EDIT: Insted of all that Execute, a simply StringSplit with the comma don't give the same result? Why we need to expand that string? FileCreateShortcut(@ScriptDir & "\Text.txt", @DesktopDir & "\TEXT.LINK", @DesktopDir, "", "", "%SystemRoot%\system32\imageres.dll", "", "-102", @SW_SHOW) Edited November 12, 2014 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
jguinch Posted November 12, 2014 Share Posted November 12, 2014 I edited my code. Can you try now ? Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 (edited) Work, good. I think you need just add a 0 in [1] for the extension without comma, like "au3" or in that case [1] is equal to nothing: ; etc Else $aRet[0] = $sDefaultIcon $aRet[1] = 0 ; etc Or Local $aRet[2] = [0,0] Can you answer my question, "Why we need to expand that string?" I'm here to learn Edited November 12, 2014 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
jguinch Posted November 12, 2014 Share Posted November 12, 2014 (edited) OK, I make made the modification. For you question : because for some extensions, the registry entry uses an environment variable. For example, on my computer, the value in HKEY_CLASSES_ROOTtxtfileDefaultIcon is %SystemRoot%system32imageres.dll,-102. Autoit do not see %SystemRoot% as a valid path, so we have to either expand the value (like I did, or with an other function), or use an AutoIt option (AutoItSetOption) Edit : if you want to have the real value, uncomment the _ExpandEnvStrings line. I'm curious to see what other members will offer .. (WinAPI way ?) Edited November 12, 2014 by jguinch Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 (edited) The WINAPI way is SHGetFileInfo + SHGFI_ICONLOCATION but seems not work well, anyway my knowledge of struct is limited. If there aren't better alternative i'll put the thread as solved. Thank you for the explaination Edited November 12, 2014 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 (edited) jguinch i have a problem, check this: $aIcon = _GetDefaultIcon("rtf") ;[0]|"C:\Program Files (x86)\Windows NT\Accessories\WORDPAD.EXE" ;[1]|1 ; Not work FileCreateShortcut("", @DesktopDir & "\RTF1.lnk", "", '"' & @DesktopDir & '\Test.rtf' & '"', "", $aIcon[0], "", $aIcon[1], @SW_SHOW) ; This work FileCreateShortcut("", @DesktopDir & "\RTF2.lnk", "", '"' & @DesktopDir & '\Test.rtf' & '"', "", "C:\Program Files (x86)\Windows NT\Accessories\WORDPAD.EXE", "", "1", @SW_SHOW) Result: My OS is x64 but i don't think is that the issue, probably is a stupid thing but i can't see any error Edited November 12, 2014 by Terenz Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
jguinch Posted November 12, 2014 Share Posted November 12, 2014 I just edited my code. The problem was the " in the string read from the registry. Can you try again please ? Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Terenz Posted November 12, 2014 Author Share Posted November 12, 2014 Confirmed, work. I didn't notice the extra quote from the return value Thanks again Nothing is so strong as gentleness. Nothing is so gentle as real strength Link to comment Share on other sites More sharing options...
jguinch Posted November 12, 2014 Share Posted November 12, 2014 Glad to help you Spoiler Network configuration UDF, _DirGetSizeByExtension, _UninstallList Firefox ConfigurationArray multi-dimensions, Printer Management UDF Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now