Globalizing the properties (details) of an EXE

127 Views Asked by At

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:

Product name: Lista de frutas

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.

0

There are 0 best solutions below