Вы должны войти, чтобы создавать сообщения и темы.

Включаем русский язык в десктопном приложении Google для Windows одним кликом

Привет!

Думаю, многие уже слышали про новое десктопное приложение Google для Windows. Если вас расстроило отсутствие русского языка в интерфейсе — я (ну, по большей части Claude) написал небольшую утилиту, которая патчит нужные байты прямо в Скопированоgoogle.exe, переключая язык с английского на русский (и обратно).

1. Скачайте программу (или соберите из исходного кода, если не доверяете мне)
2. Закройте приложение Google — через Диспетчер задач или командой:

Stop-Process -Name "google" -Force

3. Запустите Скопированоgoogle-lang-switch.exe — достаточно просто дважды кликнуть, без терминала.

Готово! Чтобы вернуть английский язык — повторите те же шаги: программа сама определит текущий язык и переключит на противоположный.

Исходный код

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static unsigned char b[1048576];

int main(void) {
    char path[512];
    const unsigned char en[] = {0x68,0x6C,0x00,0x65,0x6E,0x00,0x26};
    const unsigned char ru[] = {0x68,0x6C,0x00,0x72,0x75,0x00,0x26};
    size_t n, i; long p; FILE *f;
    snprintf(path, sizeof path, "%s\\AppData\\Local\\Google\\Google\\latest\\google.exe", getenv("USERPROFILE"));
    f = fopen(path, "r+b");
    while ((n = fread(b, 1, sizeof b, f)) > 0) {
        p = ftell(f);
        for (i = 0; i + sizeof en <= n; i++) {
            if (!memcmp(b+i, en, sizeof en)) { fseek(f, -(long)(n-i)+3, SEEK_CUR); fwrite("ru", 1, 2, f); return 0; }
            if (!memcmp(b+i, ru, sizeof ru)) { fseek(f, -(long)(n-i)+3, SEEK_CUR); fwrite("en", 1, 2, f); return 0; }
        }
        fseek(f, -(long)(sizeof en - 1), SEEK_CUR);
    }
    return 1;
}

UPD: поменяется только язык ответов — интерфейс останется английским.

UPD: для новой версии код устарел. Вот актуальный:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static unsigned char b[1048576];

int main(void) {
    char path[512];
    const unsigned char en[] = {0x68,0x6C,0x00,0x65,0x6E,0x00}; // hl\0en\0
    const unsigned char ru[] = {0x68,0x6C,0x00,0x72,0x75,0x00}; // hl\0ru\0
    size_t n, i; FILE *f;
    snprintf(path, sizeof path, "%s\\AppData\\Local\\Google\\Google\\latest\\google.exe", getenv("USERPROFILE"));
    f = fopen(path, "r+b");
    if (!f) { perror("fopen"); return 2; }
    while ((n = fread(b, 1, sizeof b, f)) > 0) {
        for (i = 0; i + sizeof en <= n; i++) {
            if (!memcmp(b+i, en, sizeof en)) { fseek(f, -(long)(n-i)+3, SEEK_CUR); fwrite("ru", 1, 2, f); fclose(f); return 0; }
            if (!memcmp(b+i, ru, sizeof ru)) { fseek(f, -(long)(n-i)+3, SEEK_CUR); fwrite("en", 1, 2, f); fclose(f); return 0; }
        }
        fseek(f, -(long)(sizeof en - 1), SEEK_CUR);
    }
    fclose(f);
    printf("Pattern not found\n");
    return 1;
}

Бинарник можно скачать по ссылке 1, 2 (стал меньше за счёт флагов)

После обновления всё снова поломалось. Вот актуальный код:

// cl /O2 /MD /GS- /Fe:google-lang-switch.exe google-lang-switch.c /link /INCREMENTAL:NO /OPT:REF /OPT:ICF

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static unsigned char b[1048576];

int main(void) {
    char path[512];
    const unsigned char en[] = {0x68,0x6C,0x00,0x00,0x65,0x6E,0x00,0x00}; // hl\0\0en\0\0
    const unsigned char ru[] = {0x68,0x6C,0x00,0x00,0x72,0x75,0x00,0x00}; // hl\0\0ru\0\0
    size_t n, i; FILE *f;
    snprintf(path, sizeof path, "%s\\AppData\\Local\\Google\\Google\\latest\\google.exe", getenv("USERPROFILE"));
    f = fopen(path, "r+b");
    if (!f) { perror("fopen"); return 2; }
    while ((n = fread(b, 1, sizeof b, f)) > 0) {
        for (i = 0; i + sizeof en <= n; i++) {
            if (!memcmp(b+i, en, sizeof en)) { fseek(f, -(long)(n-i)+4, SEEK_CUR); fwrite("ru", 1, 2, f); fclose(f); return 0; }
            if (!memcmp(b+i, ru, sizeof ru)) { fseek(f, -(long)(n-i)+4, SEEK_CUR); fwrite("en", 1, 2, f); fclose(f); return 0; }
        }
        fseek(f, -(long)(sizeof en - 1), SEEK_CUR);
    }
    fclose(f);
    printf("Pattern not found\n");
    return 1;
}

Бинарник можно скачать по ссылке: раз, два.

В свежей версии снова изменилась структура байтов и вдобавок перестали корректно отображаться названия кнопок в трее. Скорее всего, вы ими всё равно не пользуетесь, так что вот актуальный код:

// cl /O2 /MD /GS- /Fe:google-lang-switch.exe google-lang-switch.c /link /INCREMENTAL:NO /OPT:REF /OPT:ICF

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static unsigned char b[1048576];

int main(void) {
    char path[512];
    const unsigned char en[] = {0x73,0x65,0x61,0x72,0x63,0x68,0x00,0x00,0x00,0x65,0x6E,0x00,0x00}; // search\0\0\0en\0\0
    const unsigned char ru[] = {0x73,0x65,0x61,0x72,0x63,0x68,0x00,0x00,0x00,0x72,0x75,0x00,0x00}; // search\0\0\0ru\0\0
    size_t n, i; FILE *f;
    snprintf(path, sizeof path, "%s\\AppData\\Local\\Google\\Google\\latest\\google.exe", getenv("USERPROFILE"));
    f = fopen(path, "r+b");
    if (!f) { perror("fopen"); return 2; }
    while ((n = fread(b, 1, sizeof b, f)) > 0) {
        for (i = 0; i + sizeof en <= n; i++) {
            if (!memcmp(b+i, en, sizeof en)) { fseek(f, -(long)(n-i)+9, SEEK_CUR); fwrite("ru", 1, 2, f); fclose(f); return 0; }
            if (!memcmp(b+i, ru, sizeof ru)) { fseek(f, -(long)(n-i)+9, SEEK_CUR); fwrite("en", 1, 2, f); fclose(f); return 0; }
        }
        fseek(f, -(long)(sizeof en - 1), SEEK_CUR);
    }
    fclose(f);
    printf("Pattern not found\n");
    return 1;
}

Бинарник можно скачать по ссылке: раз, два.