none
SOLVED: How to embed multiple icons into .NET Executables? (Native Resource Embedding, not managed resource)

    Question

  • I'm trying to embed 3 icons into a VB .NET exe. After searching for a number of hours, I ended up using this page as a guide.

    I made a .res file with my icons. But I cannot, for the life of me, find how to to import that .res file into my project using the IDE. The above mentioned guide mentions something about that, but no "Resources" group box is available in the Application tab of the Propeties Page of the project.

    After more searching, it seems that the only way a .res file can be imported is by using the /win32resource compiler switch. I can use that switch only if I use the command line to compile my project.

    Is there any way I can add that extra compiler switch in the IDE, so that every time I compile, the .res file is automatically imported?

    I'm using VB in VS 2008

    Thank you.

    Sunday, February 10, 2008 10:20 PM

Answers

  • Answering my own question: I just found the answer elsewhere (here).

    Source of Answer
    • Open the project script in the editor by right-clicking on the project and selecting Unload Project, then right clicking on the project and selecting Edit <project name>.
    • Add the following element to the project script, replacing ExeName with the name of the project.
    <PropertyGroup>
       <Win32Resource>ExeName.res</Win32Resource>
    </PropertyGroup>

     
    Note: You can ignore the syntax error that appears in the editor (i.e. squiggly blue line under the element name). Win32Resource is the correct element name.



    [Updated on Feb. 16, 2007] Since writing this, I've learned of a couple of issues that you should be aware of before deciding to use this approach: assembly version information is lost after the binary native resources are embedded into the executable


    Actually, replace "ExeName.res" with the file name of your own .res file name. For steps on creating the .res file with your icons et al, follow the guide that I had mentioned in my earlier post.

    Anjan
    Monday, February 11, 2008 6:36 PM

All replies

  • 1.  In the VB IDE do Ctrl + Shift + A

    2.  In the "Add New Item" window double click the "Resources File" icon.

    3.  On the newly created "Resources" tab, click the down-arrow next to "Add Resource" and pick "Add Existing File...".

    4.  Locate your icon and add it to your project.

    5.  Repeat steps 3 and 4 for the remaining icons.

     

     

     

    Sunday, February 10, 2008 11:02 PM
  • Thanks for replying.

    I don't think I made myself clear. The purpose of embedding icons in the EXE is not to use the icons during runtime. I want the icons to be used by Windows Explorer.

    If you had visited the link I had mentioned, you would have read the following in the first sentence:

    Code Snippet

    "...how to embed multiple icons into a .NET executable, not embed them in the .NET resources (resx files) but accessible by Windows Explorer and the like."


    I'm posting the link here again: http://www.codeproject.com/KB/dotnet/embedmultipleiconsdotnet.aspx

    Using a .resx file only makes the icon resource available during run-time.

    I have a couple of file classes associated with my program. I want my program to have the icons embedded which will then be used by those file classes. I could have a registry key named "DefaultIcon" with a default value of (for example) "C:\MyProgram.exe,1".

    Currently there seems to be two options to do that.

    1. Use the command prompt to compile with /win32resource switch.
    2. Compile using the IDE, then open the compiled EXE inside the IDE and add the icons to the EXE.

    Both methods are unacceptable, because the exe gets overwritten if I compile again.

    Any suggestions would be appreciated.
    Monday, February 11, 2008 5:40 PM
  • Answering my own question: I just found the answer elsewhere (here).

    Source of Answer
    • Open the project script in the editor by right-clicking on the project and selecting Unload Project, then right clicking on the project and selecting Edit <project name>.
    • Add the following element to the project script, replacing ExeName with the name of the project.
    <PropertyGroup>
       <Win32Resource>ExeName.res</Win32Resource>
    </PropertyGroup>

     
    Note: You can ignore the syntax error that appears in the editor (i.e. squiggly blue line under the element name). Win32Resource is the correct element name.



    [Updated on Feb. 16, 2007] Since writing this, I've learned of a couple of issues that you should be aware of before deciding to use this approach: assembly version information is lost after the binary native resources are embedded into the executable


    Actually, replace "ExeName.res" with the file name of your own .res file name. For steps on creating the .res file with your icons et al, follow the guide that I had mentioned in my earlier post.

    Anjan
    Monday, February 11, 2008 6:36 PM
  • Dude,

    If you're still around, I'm having a related issue.  I'm writing a C# project with Visual Studio 2008, but I'm only targeting the .NET 2.0 framework.  I have 8 different Solution Configurations (pairs of 4 Debug + 4 Release) for four different companies.  The bulk of the code is identical for each of the four companies, and I have a little bit of #if...#endif code throughout the project to differentiate between them.

    I actually found the link you point out before I found your link, and I've been able to successfully add a .res file and get it to compile.  Now my problem is in selecting the right icon for each build.  MyProject.res contains all four icons, but all four builds seem to be pulling out the first icon in that file for all the builds.

    So, once you get all those icons embedded into the project as a resource, how do you select which icon will be displayed in a Windows Explorer list?

    Thanks,

    Jeff Elliott
    CGuru (at) Elmore period RR period com
    Tuesday, May 5, 2009 8:38 PM
  • As Anjan T_ writes, this solves the Problem.

    Source of Answer
    • Open the project script in the editor by right-clicking on the project and selecting Unload Project, then right clicking on the project and selecting Edit <project name>.
    • Add the following element to the project script, replacing ExeName with the name of the project.
    <PropertyGroup>
       <Win32Resource>ExeName.res</Win32Resource>
    </PropertyGroup>

    To get the Properties of the DLL back the .res file have to have an additional entry 'Version'.
    The properties at the project settings are ignored after adding the .res file.

    I used this way at a addin dll that creates buttons at a 3rd party application that only accept IDs as a Button Bitmap Recource.

    The best way to create the .res file seems to be to take one from a sample vb6 project and edit it.
    Friday, June 26, 2009 2:42 PM
  • Anjan, Not sure if you're monitoring this message queue or not, but I'll ask anyway. I've tried to do what you reccommend, but for the life of me cannot find any way under VS2008 SP1 to "Unload" the project. Right clicking on the project name in the solution explorer does not have an option to "Unload".

    What is the project script to which you are referring where I can insert the XML code listed above? Also, since VS2008 does not support .res files (only .resx files) would everything else you say apply to the <EXENAME>.resx file?

    Thanks.
    Tuesday, March 2, 2010 9:30 PM
  • Dude,

    If you're still around, I'm having a related issue.  I'm writing a C# project with Visual Studio 2008, but I'm only targeting the .NET 2.0 framework.  I have 8 different Solution Configurations (pairs of 4 Debug + 4 Release) for four different companies.  The bulk of the code is identical for each of the four companies, and I have a little bit of #if...#endif code throughout the project to differentiate between them.

    I actually found the link you point out before I found your link, and I've been able to successfully add a .res file and get it to compile.  Now my problem is in selecting the right icon for each build.  MyProject.res contains all four icons, but all four builds seem to be pulling out the first icon in that file for all the builds.

    So, once you get all those icons embedded into the project as a resource, how do you select which icon will be displayed in a Windows Explorer list?

    Thanks,

    Jeff Elliott
    CGuru (at) Elmore period RR period com

    This how you get icon from win32resources, it can be dll or exe file. All it take is the file name and index of the icon.  For executable file, the main i con will be at index of 0. You can convert the code to C# at any of the links below.

    Try the code below
    Imports System.Runtime.InteropServices
        Public Declare Auto Function ExtractIcon Lib "shell32" (ByVal hInstance As IntPtr, ByVal FileName As String, ByVal IconIndex As Integer) As IntPtr
        Public Function getIconFromFile(ByVal fileLocation As String, ByVal iconIndex As Integer) As Drawing.Icon
            Try
                Dim img As Icon
                Dim bmptr As IntPtr = ExtractIcon(System.Diagnostics.Process.GetCurrentProcess.Handle, fileLocation, iconIndex)
                If Not bmptr.Equals(IntPtr.Zero) Then
                    img = Icon.FromHandle(bmptr)
                    Return img
                Else
                    Return Nothing
                End If
                
            Catch ex As Exception
    
            End Try
            Return Nothing
        End Function
    
        'USAGE:
        Dim ic As Icon = getIconFromFile("C:\Windows\System32\shell32.dll", 2)
    

    kaymaf

    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Tuesday, March 2, 2010 10:43 PM
  • Anjan, Not sure if you're monitoring this message queue or not, but I'll ask anyway. I've tried to do what you reccommend, but for the life of me cannot find any way under VS2008 SP1 to "Unload" the project. Right clicking on the project name in the solution explorer does not have an option to "Unload".

    What is the project script to which you are referring where I can insert the XML code listed above? Also, since VS2008 does not support .res files (only .resx files) would everything else you say apply to the <EXENAME>.resx file?

    Thanks.

    There are three type of resources that i know
    -Embedded resource : Everything stay inside your executable directly. This can be any file
    -Win32Resources (Native) : This take only bitmap, icon, menu, dialog, string table, version and others
    -Managed Resources (.Net resources) : All files type

    So what you try to do is different from what Anjan posted here. If you want to use win32res, you have to convert your xml to string format and create win32resources file (.res) using Native Resources Template. 

    You can  either use  embedded resources or managed resources for your xml. For embedded resources, you will use reflection to read it.

    kaymaf 
     


    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Tuesday, March 2, 2010 11:14 PM
  • Kaymaf, thanks for replying, but your answer did not get to the heart of the question. This is what I want to do:

    1. Create a shortcut to the .EXE file on the Windows desktop
    2. Allow the user to right click the shortcut, click the "Change ICON" button and have several icons from the EXE file available to the user.

    Now with that said, I have been able to achieve this goal only by compiling my project and modifying the .EXE file inside the IDE. The problem with that (as stated at the beginning of this thread) is that this process must be completed every time the project is compiled.

    I have tried adding a resource file in all the ways that you described, but the icons are not imbedded in the EXE file.

    Anjan claims to have solved the issue but his instructions do not appear to have been done using VS2008 (even though he states that it did).

    To quote from his post:

    Source of Answer

    • Open the project script in the editor by right-clicking on the project and selecting Unload Project, then right clicking on the project and selecting Edit <project name>.
    • Add the following element to the project script, replacing ExeName with the name of the project.

    <PropertyGroup>
       <Win32Resource>ExeName.res</Win32Resource>
    </PropertyGroup>

    What script file is Anjan referring to (second bullet point)?

    Has anyone else tried this solution?

    Wednesday, March 3, 2010 12:51 PM
  • Well, i was try to explain the difference between all resources type. In your previous post you want to embed XML file and you cannot do that with win32resources.  Anjan issue was about win32resources.

    If you use embedded/manage resources, no other programs can access the resources and that is why win32resources is better. 


     
    Yes, the solution works.  For Icon, Let me try to explain it with this steps

    1) Create resources File using Native resources template. Read this article http://www.codeproject.com/KB/dotnet/embedmultipleiconsdotnet.aspx

    What script file is Anjan referring to (second bullet point)? :  If you can't follow the steps from VS to edit the project, try this, Close your project, go to project directory and open your project (.Vbproj file) with text editor program (I use Textpad), then you will see the XML file and just paste the text there

    Image 1 : projectName.vbproj file


     If you create your resource file, it should look like image in box2 above

    Image 2  : xml file from vbproj file opened in textpad

     

    You can see that the name of my resources file match the name in the xml file.

    Finally, add your resources file to your project  as existing item, select the resources file from solution explorer and in properties window, set Build Action to content

    That should solve the propblem.

    kaymaf

    CODE CONVERTER SITE

    http://www.carlosag.net/Tools/CodeTranslator/.

    http://www.developerfusion.com/tools/convert/csharp-to-vb/.

    Wednesday, March 3, 2010 2:54 PM
  • kaymaf,

    Worked perfectly. Until the XML code is added to the project script file (<projname>.vbproj) the icons do not show up as expected. Once the change is made to the project script file, everything worked as I was hoping it would.

    Many thanks!

    Thursday, March 4, 2010 7:50 PM
  • Btw there is another way without editing the .csproj and possibly getting conflict for the winresource since for visual studio 2005 provided c++ component is installed and not express version

    see the  codeproejct article:

    Embedding Multiple Icons into .NET Executables ...

    On the the other hand for vstdio 2012 pro the hand editing of .csproj will lead to conflict. Otherwise attempt to specify the .resx for the application tab for icon will lead to invlaid format

    Saturday, October 18, 2014 3:00 AM