Join 136,524 C# Programmers for FREE! Get instant access to thousands of C# experts, tutorials, code snippets, and more! There are 1,833 people online right now. Registration is fast and FREE... Join Now!
I've started to program in C# not so long time ago, and I'm currently just learning the language by creating small applications. So far I could find my answers on the net, but I really need help with this one.
The program I'm writing is called Icon Changer, it goes into the needed extension key in the registry and modifies "DefaultIcon" to the needed icon.
I'm stuck at the point where I have 3 pictureboxes, a 16x16 one, a 32x32 one, and a 48x48 one, earlier today I found a code which I use to display the "Current Extension Icon" in the 2 small pictureboxes (the icon gets bad quality in 48x48, any help with that too?).
But! When I get to DefaultIcon values like "C:/Windows/System32/shell32.dll, 44", my application crashes. I've searched around the net and found something about ExtractIcon but I couldn't really understand it well.
Screenshots:
CODE
private const int SHGFI_ICON = 0x100; private const int SHGFI_SMALLICON = 0x1; private const int SHGFI_LARGEICON = 0x0; public struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; [DllImport("Shell32.dll")] public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, uint uFlags);
So to get this straight, it works on all values up to 44 and then when it gets to 44 of shell32.dll it crashes? If that is the case, it is probably because you are ending up with a null pointer because it can't find a shell32 icon with that index. I have applied a program called Reshacker to shell32.dll and see that once you get around 44 it goes into some not so default looking icons. Perhaps that is the problem.
Because if your code extracts up to 44 just fine, I see no reason why it shouldn't extract above 44 if they exist. Your error is also suggesting that the value retrieved in your SHFILEINFO structure for hIcon is turning out to be a null pointer and thus causing the exception.
Do you run into this crash with any other file that has icons in the low index number range? Like does it ever fail on a value in less than 15 on user32.dll? Then if it doesn't fail, try it on a value like 45 of user32.dll and see if it fails. If it then fails then that is what is happening is that you are running into a bad pointer.
As I said, I'm only begging to program in C#, my application crashes when It load ANY files that has an Index. My question is how to display an icon from a dll into a picturebox. Even if I get the path C:/gg.exe,0 it crashes.
public partial class Form1 : Form { // Here is our hookup to the Shell32's ExtractIconEx function [DllImport("Shell32", CharSet = CharSet.Auto)] private static extern int ExtractIconEx( string lpszFile, int nIconIndex, IntPtr[] phIconLarge, IntPtr[] phIconSmall, int nIcons);
public Form1() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e) { // Check to see how many icons there are int m_nIcons = ExtractIconEx("C:\\WINDOWS\\system32\\SHELL32.dLL",-1,null,null,0);
// If we have more than 0, lets extract if (m_nIcons >= 0) { // Array of pointers to large and small images IntPtr[] m_pIconsLarge = new IntPtr[m_nIcons]; IntPtr[] m_pIconsSmall = new IntPtr[m_nIcons];
// Lets extract image with index 1 ExtractIconEx("C:\\WINDOWS\\system32\\SHELL32.dLL", 1, m_pIconsLarge, m_pIconsSmall, (int)m_nIcons);
// Lets setup an icon object to the large version of the extracted icon // Then finally set that to the picturebox System.Drawing.Icon MyIcon = System.Drawing.Icon.FromHandle(m_pIconsLarge[0]); pictureBox1.Image = MyIcon.ToBitmap(); } }
As you can see above we are putting in the signature for the winapi ExtractIconEx function, we then call it to see if there are any icons in shell32.dll, if there are, extract the first one and put it into the picturebox.
Remember to include System.Runtime.InteropServices at the top. Also where you see the path to the DLL, you can change it to any file path as long as it is exe, dll etc.
You can read more on it at the following address...
Just one question, how do I get a high quality image in 48x48 size?
PS: Oh, just noticed that the application will give an error if the file path is like C:\Icons\Vista,Xp,winme\xxx.ico It will split the Lines between VIsta, XP and then WinME...
This post has been edited by Iouri: 10 Aug, 2008 - 05:34 AM
Well, to not to start another topic, I would like to ask another question... How can I extract Strings from a .dll file? Example: There is a value in registry which points to "@%SystemRoot%\system32\shell32.dll,-22915", this is a string, but I don't know how to "extract" it from there, any ideas?
The 48x48 icon thingy - I haven't solved that one yet..