【问题标题】:unable to add icon to exe using windres无法使用windres将图标添加到exe
【发布时间】:2025-11-23 13:35:01
【问题描述】:

我想在我用 mingw-gcc 编译的 exe 中添加一个图标。

我按照this SO post 中的说明进行操作,但图标未显示在 Windows 资源管理器中的我的 exe 中。

[编辑] 同时我发现windres 破坏了我的可执行文件。在应用 windres 之前,可执行文件按预期运行。应用windres 后调用可执行文件会导致 Windows 错误消息告诉(大致)此可执行文件与此 windows 版本不兼容。

我做错了什么?


这是我的目录布局:

$ ls -lR launcher/
launcher/:
total 508
drwxr-xr-x 1 me 1049089      0 Aug 20  2015 src/
drwxr-xr-x 1 me 1049089      0 Nov  7 10:56 target/

launcher/src:
total 0
drwxr-xr-x 1 me 1049089 0 Nov  7 10:51 main/

launcher/src/main:
total 4
drwxr-xr-x 1 me 1049089 0 Nov  7 10:52 cpp/
drwxr-xr-x 1 me 1049089 0 Apr 14  2016 resources/
drwxr-xr-x 1 me 1049089 0 Nov  4 15:11 scripts/

launcher/src/main/cpp:
total 8
-rw-r--r-- 1 me 1049089 6793 Nov  7 10:41 JavaLauncher.cpp

launcher/src/main/resources:
total 5
-rw-r--r-- 1 me 1049089   47 Nov  7 10:47 javaLauncher.rc
-rw-r--r-- 1 me 1049089 2238 Apr 14  2016 JavaLauncher.ico

launcher/src/main/scripts:
total 1
-rw-r--r-- 1 me 1049089 389 Nov  7 10:56 makefile

launcher/target:
total 4
-rwxr-xr-x 1 me 1049089 2502 Nov  7 10:56 JavaLauncher.exe*

这是我的资源文件:

0 ICON "launcher/src/main/resources/JavaLauncher.ico"

这是我的生成文件:

all: launcher/target/JavaLauncher.exe

launcher/target/JavaLauncher.exe: launcher/src/main/cpp/JavaLauncher.cpp launcher\target
    /Absolute/Path/to/mingw64/bin/g++.exe $< -o $@ -static -l winpthread
    /Absolute/Path/to/mingw64/bin/windres.exe -v -i launcher/src/main/resources/javaLauncher.rc -o $@


launcher\target:
    cmd /c md $@

这是make的输出:

/Project/root>/Absolute/Path/to/mingw64\bin\make.exe -f launcher\src\main\scripts\makefile
cmd /c md launcher\target
/Absolute/Path/to/mingw64/bin/g++.exe launcher/src/main/cpp/JavaLauncher.cpp -o launcher/target/JavaLauncher.exe -static -l winpthread
/Absolute/Path/to/mingw64/bin/windres.exe -v -i launcher/src/main/resources/javaLauncher.rc -o launcher/target/JavaLauncher.exe
Using `/Absolute/Path/to/mingw64/bin/gcc -E -xc -DRC_INVOKED  launcher/src/main/resources/javaLauncher.rc'
Using popen to read preprocessor output

/Project/root>

这是 Windows 资源管理器中的结果:


[编辑] 最终的工作解决方案是这样的:

mingwPath = $(realpath Path/to/mingw64/bin)
TARGET_DIR=target
TARGET_OBJECT_DIR=$(TARGET_DIR)/objects
TARGET_DIR_NAME=$(subst /,\, $(TARGET_DIR))
TARGET_OBJECT_DIR_NAME=$(subst /,\, $(TARGET_OBJECT_DIR))
SOURCE_DIR_NAME=src/main
APP_NAME=MyApp
TARGET_BASE_NAME=$(TARGET_DIR)/$(APP_NAME)
TARGET_ARCH=-m32

all: $(TARGET_OBJECT_DIR_NAME) $(TARGET_BASE_NAME).exe


$(TARGET_BASE_NAME).exe: $(TARGET_OBJECT_DIR)/$(APP_NAME).o\ 
 $(TARGET_OBJECT_DIR)/$(APP_NAME)Res.o $(TARGET_OBJECT_DIR_NAME)    
    $(mingwPath)/g++  $(TARGET_ARCH) -o $@ -static -l winpthread   $(filter %.o,$^)

$(TARGET_OBJECT_DIR)/$(APP_NAME).o: $(SOURCE_DIR_NAME)/cpp/$(APP_NAME).cpp
    $(mingwPath)/g++ $(TARGET_ARCH) -c $<  -o $@ 

$(TARGET_OBJECT_DIR)/$(APP_NAME)Res.o:  $(SOURCE_DIR_NAME)/resources/$(APP_NAME).rc
    $(mingwPath)/windres -v -i $< -o $@  --output-format=coff --target=pe-i386


$(TARGET_OBJECT_DIR_NAME):$(TARGET_DIR_NAME)
    echo $@
    cmd /c md $@

$(TARGET_DIR_NAME):
    echo $@
    cmd /c md $@

clean: 
    cmd /c del /s /q $(TARGET_DIR_NAME)

【问题讨论】:

    标签: windows gcc icons mingw windres


    【解决方案1】:

    我不确定windres 资源编译器是否可以编译资源数据并将其直接添加到 exe 文件中,但这就是您在此处尝试执行的操作。或许有可能,我搜索了一下,没有找到相关信息。

    我得到了这个工作并有一个 exe 图标。您需要将windres生成的资源对象指定给程序对象后的g++链接器。还要更改顺序并首先运行windres,以便在g++ 链接器链接程序和资源对象之前生成资源对象文件。

    all: launcher/target/JavaLauncher.exe
    
    launcher/target/JavaLauncher.exe: launcher/src/main/cpp/JavaLauncher.cpp launcher\target
        /Absolute/Path/to/mingw64/bin/windres.exe -v -i launcher/src/main/resources/JavaLauncher.rc -o launcher/src/main/resources/JavaLauncherRes.o
        /Absolute/Path/to/mingw64/bin/g++.exe $< -o $@ launcher/src/main/resources/JavaLauncherRes.o -static
    
    
    launcher\target:
        cmd /c md $@
    

    【讨论】:

    • 仍然无法确认,因为我现在遇到了 32 位目标的问题。见这里:*.com/questions/40584265/…
    • 你试过我告诉你的,改变windres顺序和它生成的目标文件吗?然后将该目标文件添加到 -o $@ 之后的 g++ 链接器
    • 是的,新的 make 文件现在首先创建一个 *.o 文件,windres 在该文件上添加图标。这就是我从你的回答中得到的。
    • 您在另一篇文章中获得的 makefile 是错误的,我仍然看到您在 g++ 链接器评论后获得了 windres。我稍后会检查你的错误,看看它是关于什么的,我会更新。
    • 更改为$(mingwPath)/windres -v -i $(SOURCE_DIR_NAME)/resources/$(APP_NAME).rc -o $(TARGET_BASE_NAME)Res.o --output-format=coff --target=pe-i386
    最近更新 更多