In Windows 10, when you right-click on an executable (EXE) file, select Properties, and click on "Details", you see some strings and numbers that come from the resources section of the executable.
I am a stickler for details, so I am wondering if it is possible to make a single executable (EXE) file that holds multiple translations of those strings so that Windows will show those strings in the user's own language when possible. For example, I'd like my executable to have versions of those strings in both English and Spanish. English users should see the English strings and Spanish users should see the Spanish strings.
Unfortunately, it seems like the Details tab always takes its strings from the first translation listed in the Translations
list in the VarFileInfo
block, regardless of the user's preferred language.
I'll include enough info here so that you can reproduce these results yourself using MSYS2's MINGW64 environment.
I have a file named r.rc
with contents:
#include <winnls.h>
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0" // English (United States), unicode
BEGIN
VALUE "ProductName", "List of fruits"
END
BLOCK "040A04B0" // Spanish (Spain), unicode
BEGIN
VALUE "ProductName", "Lista de Frutas"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation",
0x040A, 1200, // Spanish (Spain), unicode
0x0409, 1200 // English (United States), unicode
END
END
LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
STRINGTABLE
BEGIN
1, "Fresa"
END
LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
STRINGTABLE
BEGIN
1, "Stawberry"
END
I have a file named main.c
with contents:
#include <windows.h>
#include <stdio.h>
int main()
{
// Uncomment one of these to test a language:
// SetThreadUILanguage(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US));
// SetThreadUILanguage(MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MEXICAN));
printf("GetThreadUILanguage: 0x%x\n", GetThreadUILanguage());
WCHAR buffer[256];
LoadStringW(NULL, 1, buffer, 256);
printf("LoadString: %ls\n", buffer);
}
(The string tables and the call to LoadString
are there in the code above to demonstrate that LoadString
can properly take into account the user's language when finding strings, making it all the more confusing that the "Details" tab would not do this.)
I build these files into an executable in MSYS2's MINGW64 environment by running this script:
#!/usr/bin/bash
set -ue
windres r.rc r.o
gcc -Wall -Wextra main.c r.o -o test
After doing this, the "Details" tab of test.exe shows a Spanish string for the "Product name" even though my computer is configured to use English and I provided an English version of that string in resources file. Here is what it looks like:
Does anyone know how to make the English version show up there for users using English, without listing English first in the Translations list?
The ideal answer would work for Windows 10 and Windows 11. I don't really care about older versions. (I have not tested Windows 11 yet.)
I tried changing 0x0409 (English US) to 0x0009 (English neutral) in the two places it is written, but that doesn't help.