Click to See Complete Forum and Search --> : How can I get icon of a exe file?
MrPolite
Oct 14th, 2002, 01:53 AM
that is, without APIs...
I cant do it. Drawing.Icon seems to only be able to load .ICO files. How can I get the icon of an exe file then?
Slow_Learner
Oct 14th, 2002, 02:22 AM
Doesn't seem to be a Framework function that does it, but here's an API call from AllAPI (have you got this thing?), again in VB6:
'This project needs a PictureBox, called 'Picture1'
'In general section
Private Declare Function DrawIcon Lib "user32" Alias "DrawIcon" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long
Private Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
Private Declare Function GetWindowsDirectory Lib "kernel32" Alias "GetWindowsDirectoryA" (ByVal lpBuffer As String, ByVal nSize As Long) As Long
Private Sub Form_Load()
'KPD-Team 1998
'URL: http://www.allapi.net/
'E-Mail: KPDTeam@Allapi.net
Dim Path as String, strSave as string
'Create a buffer string
strSave = String(200, Chr$(0))
'Get the windows directory and append '\REGEdit.exe' to it
Path = Left$(strSave, GetWindowsDirectory(strSave, Len(strSave))) + "\REGEdit.exe"
'No pictures
Picture1.Picture = LoadPicture()
'Set graphicmode to 'persistent
Picture1.AutoRedraw = True
'Extract the icon from REGEdit
return1& = ExtractIcon(Me.hWnd, Path, 2)
'Draw the icon on the form
return2& = DrawIcon(Picture1.hdc, 0, 0, return1&)
End Sub
MrPolite
Oct 14th, 2002, 02:30 AM
hey, I'm killing myself to make this work with .NET, but it doesnt do anything!!!
I changed all the LONGS to INTEGERS and I'm using me.Handle.Toint32 to draw the icon on the form. Doesnt give me any error, but it doesnt do anything (I put the code in Form_Paint so it would autoredraw, but no luck)
can you help me convert this to vb.net?
MrPolite
Oct 14th, 2002, 02:33 AM
here's what I'm doing:
Dim mIcon As Integer = ExtractIcon(Me.Handle.ToInt32, "C:\windows\regedit.exe", 2)
DrawIcon(Me.Handle.ToInt32, 0, 0, mIcon)
Slow_Learner
Oct 14th, 2002, 03:50 AM
I really really suck at API calls, even under c++ where type conversion is less of an issue. I'll beat on it some though and see if I can help.
ExtractIcon(Me.Handle.ToInt32, "C:\windows\regedit.exe", 2)
· hInst
Identifies the instance of the application calling the function.
· lpszExeFileName
Points to a null-terminated string specifying the name of an executable file, DLL, or icon file.
^^^^ For one thing your string isn't null-teriminated ^^^^
^^^^ aside from that I have no idea how to represent a long pointer in VB, have you read: ^^^^
^^^^ ms-help://MS.VSCC/MS.MSDNVS/cpguide/html/cpcondefaultmarshalingforstrings.htm ^^^^
· nIconIndex
Specifies the index of the icon to retrieve. If this value is 0, the function returns the handle of the first icon in the specified file. If this value is -1, the function returns the total number of icons in the specified file.
Slow_Learner
Oct 14th, 2002, 04:39 AM
For another Int32 is too small to hold the return value (at least on my machine) but Int64 - even though it prevents the overflow crash - doesn't work either.
Annoyed! :confused: Seems to me that this should work:
Dim strFoo() As Char = "c:\winnt\regedit.exe" + ChrW(0)
Dim iFoo& = ExtractIcon(Me.Handle.ToInt64, strFoo, 1)
DrawIcon(Me.Handle.ToInt64, 10, 10, iFoo&)
but while it doesn't crash, it doesn't work either!
sunburnt
Oct 14th, 2002, 03:17 PM
This worked for me. It's in C#, but it should be easy to convert.
[DllImport("user32")]
static extern int DrawIcon(int hdc, int x, int y, int hIcon);
[DllImport("shell32")]
static extern int ExtractIcon(int hInst, string ExeName, int IconIndex);
int mIcon = ExtractIcon(this.Handle.ToInt32() , "C:\\windows\\regedit.exe", 0);
int hdc = this.CreateGraphics().GetHdc().ToInt32();
DrawIcon(hdc, 0, 0, mIcon);
Notice that DrawIcon wants the HDC not the Handle :D
Keep in mind the actual Icon of the program is stored at ResourceIndex 0 (isn't it?)
MrPolite
Oct 14th, 2002, 04:01 PM
Originally posted by sunburnt
This worked for me. It's in C#, but it should be easy to convert.
[DllImport("user32")]
static extern int DrawIcon(int hdc, int x, int y, int hIcon);
[DllImport("shell32")]
static extern int ExtractIcon(int hInst, string ExeName, int IconIndex);
int mIcon = ExtractIcon(this.Handle.ToInt32() , "C:\\windows\\regedit.exe", 0);
int hdc = this.CreateGraphics().GetHdc().ToInt32();
DrawIcon(hdc, 0, 0, mIcon);
Notice that DrawIcon wants the HDC not the Handle :D
Keep in mind the actual Icon of the program is stored at ResourceIndex 0 (isn't it?)
it worked!!!!!! THANKS! :)
Just soemthing that doesnt make sense: GetHdc doesnt show up in intellisense (in createGraphics() 's properties):confused:
also thanks Slow_Learner for the help
Slow_Learner
Oct 14th, 2002, 04:51 PM
Hate to be the last guy to get it, but I don't see what I'm doing wrong here:
Public Declare Auto Function DrawIcon Lib "user32" Alias "DrawIcon" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal hIcon As Long) As Long
Public Declare Auto Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim mIcon As Int64 = ExtractIcon(Me.Handle.ToInt32, "c:\winnt\regedit.exe", 0)
Dim hdc As Int32 = Me.CreateGraphics.GetHdc.ToInt32
DrawIcon(hdc, 10, 10, mIcon)
End Sub
MrPolite, how did you get it to work? I still need to use Int64 for mIcon or else it overflows.
MrPolite
Oct 14th, 2002, 05:28 PM
well you are putting it in form_load so it's erased on a form_paint event
if you use me.creategraphics, it wont draw on the background image of the form. Just put that code in form_paint
also you could use graphics.fromimage (me.backgroundimage). This way you will draw on the form and you wont need to repaint the picture (the problem is that you can't call that sub if your background image is NULL)
anyways I'm still having problems. I can use this to draw on a form, but I cant draw on a bitmap object. Basically I want to write a function which would return the icon of My Computer:
Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Integer, ByVal lpszExeFileName As String, ByVal nIconIndex As Integer) As Integer
Private Declare Function DrawIconEx Lib "user32" (ByVal hdc As Integer, ByVal xLeft As Integer, ByVal yTop As Integer, ByVal hIcon As Integer, ByVal cxWidth As Integer, ByVal cyWidth As Integer, ByVal istepIfAniCur As Integer, ByVal hbrFlickerFreeDraw As Integer, ByVal diFlags As Integer) As Integer
Private Declare Function DrawIcon Lib "user32" Alias "DrawIcon" (ByVal hdc As Integer, ByVal x As Integer, ByVal y As Integer, ByVal hIcon As Integer) As Integer
Private Function getMyComputerIcon() As Icon
Const MY_COMPUTER As String = "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
Dim reg As RegistryKey = Registry.ClassesRoot.OpenSubKey(MY_COMPUTER & "\DefaultIcon\")
Dim IconPath As String = reg.GetValue("").ToString()
' Icon() 's path contains a "," that separates the path and parameters (default windows setting)
' Get the path only
IconPath = IconPath.Substring(0, IconPath.IndexOf(","))
Dim bmpIcon As New Bitmap(32, 32)
Dim myCompIcon As Icon
Dim iconIndex As Integer = ExtractIcon(Me.Handle.ToInt32, IconPath, 0)
Dim hwnd As Integer = Graphics.FromImage(bmpIcon).GetHdc.ToInt32()
DrawIcon(hwnd, 0, 0, iconIndex)
myCompIcon = Icon.FromHandle(bmpIcon.GetHicon())
' It returns SOMETHING, but if you try to draw it, it will draw nothing!!!!
Return myCompIcon
End Function
well, I'm creating a new bitmap (32x32) and I'm drawing the icon
in the bitmap. Then I'm converting that bitmap to an icon
(conversion works correctly, it's just the bitmap that doesnt
contain the drawn icon for some reason:confused: )
if this wasnt an exe file and it was just an ico file, I could just get the icon by saying icon = new icon (iconPath). But it doesnt work like this for exe files :( maybe there is a better way
Slow_Learner
Oct 14th, 2002, 06:42 PM
Dang, you're getting more out of it than I am - can't make it return and draw an icon in VB.NET *OR* c#. *goes to stare at MSDN for a while*
Slow_Learner
Oct 14th, 2002, 06:53 PM
maybe the attached sample project (from the 101 .Net samples) will bring some enlightenment.
MrPolite
Oct 15th, 2002, 12:35 AM
aint working :(
did you get it to work SlowLearner? (not my function, just drawing on the form)
Slow_Learner
Oct 15th, 2002, 01:41 AM
Nope :/ and I don't understand why either.
MrPolite
Oct 15th, 2002, 01:47 AM
Try this, it will draw my comp's icon on your form (assuming your windows path is the same as mine:D)
Private Sub DrawIcon()
Dim path As String = "C:\windows\explorer.exe"
Dim iconIndex As Integer = ExtractIcon(Me.Handle.ToInt32, path, 0)
Dim hdc As Integer = Me.CreateGraphics.GetHdc.ToInt32
DrawIcon(hdc, 0, 0, iconIndex)
End Sub
MrPolite
Oct 15th, 2002, 01:52 AM
btw I asked for help in gotdotnet forums and some other guy wrote the API function to get the variables as IntPtr rather than as Integer. So the code above would look like this: (I guess it's better this way)
Declare Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As IntPtr, ByVal lpszExeFileName As String, ByVal nIconIndex As Integer) As IntPtr
Private Declare Function DrawIcon Lib "user32" Alias "DrawIcon" (ByVal hdc As IntPtr, ByVal x As Integer, ByVal y As Integer, ByVal hIcon As IntPtr) As Integer
Private Sub DrawIcon()
Dim path As String = "C:\windows\explorer.exe"
Dim iconIndex As IntPtr = ExtractIcon(Me.Handle, path, 0)
Dim hdc As IntPtr = Me.CreateGraphics.GetHdc
DrawIcon(hdc, 0, 0, iconIndex)
End Sub
he also wrote this function which DOES return the icon. The only problem is that the icon has black outlines, which looks ugly (try it). (GotDotNet.com isnt working right now, I'll post a link to the thread later)
Declare Ansi Function ExtractIcon Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As IntPtr, ByVal lpszExeFileName As String, ByVal nIconIndex As Integer) As IntPtr
Private Function getMyComputerIcon() As Icon
Const MY_COMPUTER As String = "CLSID\{20D04FE0-3AEA-1069-A2D8-08002B30309D}"
Dim reg As RegistryKey = Registry.ClassesRoot.OpenSubKey(MY_COMPUTER & "\DefaultIcon\")
Dim IconPath As String = reg.GetValue("").ToString()
Dim myIcon As IntPtr
Dim myCompIcon As Icon
Dim iconIndex As Integer = CInt(IconPath.Substring(IconPath.IndexOf(",") + 1))
IconPath = IconPath.Substring(0, IconPath.IndexOf(","))
myIcon = ExtractIcon(Me.Handle, IconPath, iconIndex)
myCompIcon = Icon.FromHandle(myIcon)
Return myCompIcon
End Function
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim myCompIcon As Icon = getMyComputerIcon()
Dim bmpIcon As Bitmap = myCompIcon.ToBitmap()
Me.pic.Image = bmpIcon
End Sub
Slow_Learner
Oct 15th, 2002, 01:59 AM
:confused: :confused: :confused:
An unhandled exception of type 'System.OverflowException' occurred in ExtractIcon test.exe
Additional information: Arithmetic operation resulted in an overflow.
Aha! You're running Win98/ME aren't you!! No wonder I'm getting an overflow there (you're dealing with a smaller memory model as I recall)
Well the new example - FINALLY! - works correctly for me under Windows 2000. I think I'll build a holy shrine to it and sacrifice a few virgins. Thanks for bringing it over this way :)
PS: The last example, where you have the icon drawn in a picturebox - for me it doesn't have a black border around it? Looks normal.
MrPolite
Oct 15th, 2002, 02:02 AM
Originally posted by Slow_Learner
:confused: :confused: :confused:
An unhandled exception of type 'System.OverflowException' occurred in ExtractIcon test.exe
Additional information: Arithmetic operation resulted in an overflow.
Aha! You're running Win98/ME aren't you!! No wonder I'm getting an overflow there (you're dealing with a smaller memory model as I recall)
Well the new example - FINALLY! - works correctly for me under Windows 2000. I think I'll build a holy shrine to it and sacrifice a few virgins. Thanks for bringing it over this way :) :D I have winXP, I dont get it, why doesnt it work? maybe it doesnt like the idea of few virgins around your holy shrine :D
Slow_Learner
Oct 15th, 2002, 02:05 AM
No no, the GotDotNet example works, the earlier one does not ... chokes with an overflow error when I try to stick the return from ExtractIcon into an Integer - the number being returned was some huge ungodly thing, let me see if I can scrounge it back up amidst the furious edits.
MrPolite
Oct 15th, 2002, 02:06 AM
Originally posted by Slow_Learner
No no, the GotDotNet example works, the earlier one does not ... chokes with an overflow error when I try to stick the return from ExtractIcon into an Integer - the number being returned was some huge ungodly thing, let me see if I can scrounge it back up amidst the furious edits. did you get that evil ugly looking outline on the icon? I dont want it to have that! :mad:
Slow_Learner
Oct 15th, 2002, 02:09 AM
no outline, don't know why you're getting one.
Stumped as to why I was getting an overflow crash with code you could run, and both of us under > WinME.
MrPolite
Oct 15th, 2002, 02:11 AM
here:
http://www.vbforums.com/attachment.php?postid=1218594
Slow_Learner
Oct 15th, 2002, 02:14 AM
Well a significant difference is that I have a different My Computer icon...
MrPolite
Oct 15th, 2002, 02:16 AM
heh, old my comp icon :p
umm, why is it that it works fine when I draw it directly on the form (the little function that I wrote in a few posts above), but not when it returns an icon?:confused:
MrPolite
Oct 15th, 2002, 02:17 AM
Originally posted by Slow_Learner
Well a significant difference is that I have a different My Computer icon...
oooh, which function did you use ? GetMyComputerIcon? or DrawIcon() that I wrote?
DrawIcon() one works, but the one that's supposed to return an icon has that outline.
Slow_Learner
Oct 15th, 2002, 02:18 AM
Here's mine from the return-icon approach:
Dim myCompIcon As Icon = getMyComputerIcon()
Dim bmpIcon As Bitmap = myCompIcon.ToBitmap()
Me.pic.Image = bmpIcon
MrPolite
Oct 15th, 2002, 02:19 AM
aaaaaaaaah!! then how come it doesnt work here?!!!
maybe because I have a 32bit icon? is yours 32 bit?:confused: :confused: :confused: :confused:
Slow_Learner
Oct 15th, 2002, 02:21 AM
As in 32bit color palette? No, I believe mine are 8bit. The default desktop icons for Win2k.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.