Skip to content

Commit 37646a8

Browse files
committed
add more l10n
1 parent 8434830 commit 37646a8

File tree

9 files changed

+117
-53
lines changed

9 files changed

+117
-53
lines changed

i10n/bundle.l10n.zh-cn.json

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"This command is only expected to be used in the context menu": "此命令仅在上下文菜单中使用",
3+
"This command only supports iOS or Android": "此命令仅支持 iOS 或 Android",
4+
"Select destination folder": "选择目标文件夹",
5+
"frida-server not found on device, downloading...": "设备上未找到 frida-server,正在下载...",
6+
"Downloading frida-server": "正在下载 frida-server",
7+
"Done": "完成",
8+
"Open": "打开",
9+
"Dismiss": "关闭",
10+
"frida-server deployed to {0} successfully": "frida-server 已成功部署到 {0}",
11+
"sanity check: frida-server version on device {0}": "完整性检查:设备上的 frida-server 版本 {0}",
12+
"failed to dump application:\n{0}": "应用导出失败:\n{0}",
13+
"Successfully pulled package {0}": "成功导出软件包 {0}",
14+
"Failed to get package path: {0}": "获取软件包路径失败:{0}",
15+
"Unsupported device type": "不支持的设备类型",
16+
"Unsupported item type": "不支持的项目类型",
17+
"Target is not running": "目标未运行",
18+
"App \"{0}\" must be running before attaching to it": "必须先运行应用 \"{0}\" 才能附加到它",
19+
"Host or IP of the remote device": "远程设备的主机名或IP地址",
20+
"Frida - {0}": "Frida - {0}",
21+
"Install typescript typings": "安装 TypeScript 类型提示",
22+
"@types/frida-gum has been successfully installed": "@types/frida-gum 已成功安装",
23+
"Downloading typing info for frida-gum": "正在下载 frida-gum 的类型提示",
24+
"Failed to download typing info for frida-gum: {0}": "下载 frida-gum 的类型提示失败:{0}",
25+
"The command requires a workspace or an active document": "此命令需要工作区或活动文档",
26+
"This document is not Javascript or TypeScript": "此文档不是 JavaScript 或 TypeScript",
27+
"The current document is unsaved": "当前文档未保存",
28+
"This command is not applicable to the selected item": "此命令不适用于所选项目",
29+
"This command is not applicable to the local device": "此命令不适用于本地设备",
30+
"Warning: failed to launch App {0}\n{1}": "警告:启动应用 {0} 失败\n{1}",
31+
"You must select a folder to create the project": "您必须选择一个文件夹来创建项目",
32+
"This command only works in a workspace. Please open a workspace first": "此命令仅在工作区中有效。请先打开一个工作区",
33+
"{0} already exists. Do you want to overwrite it?": "{0} 已存在。您要覆盖它吗?",
34+
"Yes": "",
35+
"No": "",
36+
"Debug Command": "调试命令",
37+
"Debug configuration created. You can now start debugging by pressing F5": "调试配置已创建。您现在可以按 F5 开始调试",
38+
"inetcat not found": "未找到 inetcat",
39+
"inetcat exited with code {0}": "inetcat 以代码 {0} 退出",
40+
"Invalid protocol": "无效的协议",
41+
"No valid SSH port found": "未找到有效的 SSH 端口",
42+
"SSH: {0}": "安全外壳协议:{0}",
43+
"This feature is not enabled on Windows due to lack of inetcat": "由于缺少 inetcat,此功能在 Windows 上未启用",
44+
"inetcat command not present in $PATH": "inetcat 命令不在 $PATH 中",
45+
"OS type {0} is not supported": "操作系统类型 {0} 不受支持"
46+
}

src/commands/android.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ function getServerPath() {
1616

1717
export async function startServer(target: TargetItem) {
1818
if (!(target instanceof DeviceItem)) {
19-
vscode.window.showErrorMessage('This command is only expected to be used in the context menu');
19+
vscode.window.showErrorMessage(vscode.l10n.t('This command is only expected to be used in the context menu'));
2020
return;
2121
}
2222

2323
const server = getServerPath();
2424
const adb = new ADB(target.data.id);
2525
const installed = await adb.shell(server, '--version').then((ver: string) => {
26-
logger.appendLine(`sanity check: frida-server version on device ${ver}`);
26+
logger.appendLine(vscode.l10n.t('sanity check: frida-server version on device {0}', ver));
2727
return true;
2828
}).catch(() => {
29-
logger.appendLine('frida-server not found on device, downloading...');
29+
logger.appendLine(vscode.l10n.t('frida-server not found on device, downloading...'));
3030
return false;
3131
});
3232

@@ -38,21 +38,21 @@ export async function startServer(target: TargetItem) {
3838
const shellPath = await interpreter();
3939
await vscode.window.withProgress({
4040
location: vscode.ProgressLocation.Notification,
41-
title: 'Downloading frida-server',
41+
title: vscode.l10n.t('Downloading frida-server'),
4242
cancellable: false
4343
}, async (progress) => {
4444
await run({
4545
name: `Download frida-server`,
4646
shellPath,
4747
shellArgs: [py, abi, tmp]
4848
});
49-
progress.report({ message: 'Done' });
49+
progress.report({ message: vscode.l10n.t('Done') });
5050
});
5151

5252
const uri = vscode.Uri.file(tmp);
5353
await adb.push(uri, server);
5454

55-
vscode.window.showInformationMessage(`frida-server deployed to ${server} successfully`);
55+
vscode.window.showInformationMessage(vscode.l10n.t('frida-server deployed to {0} successfully', server));
5656
await adb.shell('chmod', '755', server);
5757
}
5858

src/commands/boilerplate.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ async function create(template: string) {
2323
if (fileUri?.length) {
2424
dest = fileUri[0];
2525
} else {
26-
vscode.window.showInformationMessage('You just cancelled the operation.');
26+
vscode.window.showInformationMessage(
27+
vscode.l10n.t('You must select a folder to create the project'));
2728
return;
2829
}
2930
}
@@ -81,7 +82,8 @@ export async function debug(node?: AppItem | ProcessItem) {
8182
const { workspaceFolders } = vscode.workspace;
8283

8384
if (!workspaceFolders?.length) {
84-
showInformationMessage('You must open a workspace first.');
85+
showInformationMessage(
86+
vscode.l10n.t('This command only works in a workspace. Please open a workspace first'));
8587
return;
8688
}
8789

@@ -104,10 +106,12 @@ export async function debug(node?: AppItem | ProcessItem) {
104106
// check if launch.json exists
105107
for (const file of [launchJSON, tasksJSON]) {
106108
if (await isFile(file)) {
107-
const msg = `${file} already exists. Do you want to overwrite it?`;
108-
const answer = await showInformationMessage(msg, 'Yes', 'No');
109-
if (answer === 'No') { return; }
110-
if (answer === 'Yes') { break; } // only have to answer yes once
109+
const msg = vscode.l10n.t('{0} already exists. Do you want to overwrite it?', file);
110+
const y = vscode.l10n.t('Yes');
111+
const n = vscode.l10n.t('No');
112+
const answer = await showInformationMessage(msg, y, n);
113+
if (answer === n) { return; }
114+
if (answer === y) { break; } // only have to answer yes once
111115
}
112116
}
113117
} else {
@@ -141,7 +145,7 @@ export async function debug(node?: AppItem | ProcessItem) {
141145
const placeHolder = cmd.join(' ');
142146
const userInput = await showInputBox({
143147
placeHolder,
144-
prompt: "Debug Command",
148+
prompt: vscode.l10n.t('Debug Command'),
145149
value: placeHolder,
146150
});
147151

@@ -162,5 +166,7 @@ export async function debug(node?: AppItem | ProcessItem) {
162166
content.tasks[0].args = [...tokenize(userInput)];
163167
await fsp.writeFile(tasksJSON, JSON.stringify(content, null, 2));
164168

165-
showInformationMessage('Debug config added to workspace. Press F5 to start debugging.');
169+
showInformationMessage(
170+
vscode.l10n.t('Debug configuration created. You can now start debugging by pressing F5')
171+
);
166172
}

src/commands/clipboard.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { env } from 'vscode';
1+
import { env, l10n } from 'vscode';
22
import { TargetItem, AppItem, ProcessItem, DeviceItem } from "../providers/devices";
33

44
export function copy(item: TargetItem) {
@@ -10,7 +10,7 @@ export function copy(item: TargetItem) {
1010
} else if (item instanceof DeviceItem) {
1111
text = item.data.id;
1212
} else {
13-
throw new Error('Unsupported item type');
13+
throw new Error(l10n.t('Unsupported item type'));
1414
}
1515

1616
env.clipboard.writeText(text);

src/commands/dump.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ import { cmd } from '../utils';
88

99
export default async function dump(target: TargetItem) {
1010
if (!(target instanceof AppItem)) {
11-
vscode.window.showErrorMessage('This command is only expected to be used in the context menu');
11+
vscode.window.showErrorMessage(vscode.l10n.t('This command is only expected to be used in the context menu'));
1212
return;
1313
}
1414

1515
if (target.device.os !== 'ios' && target.device.os !== 'android') {
16-
vscode.window.showErrorMessage('This command only supports iOS or Android');
16+
vscode.window.showErrorMessage(vscode.l10n.t('This command only supports iOS or Android'));
1717
return;
1818
}
1919

@@ -25,7 +25,7 @@ export default async function dump(target: TargetItem) {
2525
canSelectFolders: true,
2626
canSelectMany: false,
2727
openLabel: 'Select',
28-
title: 'Select destination folder'
28+
title: vscode.l10n.t('Select destination folder')
2929
});
3030

3131
if (!destinations?.length) { return; }
@@ -46,17 +46,22 @@ export default async function dump(target: TargetItem) {
4646
artifact = vscode.Uri.joinPath(destURI, `${target.data.identifier}.apk`);
4747
await pull(target, artifact);
4848
} else {
49-
vscode.window.showErrorMessage('This command only supports iOS or Android');
49+
vscode.window.showErrorMessage(vscode.l10n.t('This command only supports iOS or Android'));
5050
return;
5151
}
5252
} catch (e) {
53-
vscode.window.showInformationMessage(`failed to dump application:\n${(e as Error).message}`);
53+
vscode.window.showInformationMessage(
54+
vscode.l10n.t('failed to dump application:\n{0}', (e as Error).message));
5455
return;
5556
}
5657

58+
const actionOpen = vscode.l10n.t('Open');
5759
const option = await vscode.window.showInformationMessage(
58-
`Successfully pulled package ${target.data.identifier}`, 'Open', 'Dismiss');
59-
if (option === 'Open') {
60+
vscode.l10n.t('Successfully pulled package {0}', target.data.identifier),
61+
actionOpen,
62+
vscode.l10n.t('Dismiss'));
63+
64+
if (option === actionOpen) {
6065
vscode.commands.executeCommand('revealFileInOS', artifact);
6166
}
6267
}
@@ -68,7 +73,7 @@ async function pull(target: AppItem, output: vscode.Uri) {
6873
if (path.startsWith('package:')) {
6974
await adb.pull(path.substring(8).trimEnd(), output);
7075
} else {
71-
vscode.window.showErrorMessage(`Failed to get package path: ${path}`);
76+
vscode.window.showErrorMessage(vscode.l10n.t('Failed to get package path: {0}', path));
7277
}
7378
}
7479

@@ -82,7 +87,7 @@ async function bagbak(target: AppItem, output: vscode.Uri) {
8287
if (target.device.id !== 'usb') { shellArgs.push.apply(shellArgs, ['-D', target.device.id]); }
8388
break;
8489
default:
85-
vscode.window.showErrorMessage('Unsupported device type');
90+
vscode.window.showErrorMessage(vscode.l10n.t('Unsupported device type'));
8691
return;
8792
}
8893

src/commands/objection.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as vscode from 'vscode';
2+
import { l10n } from 'vscode';
23

34
import { launch } from '../driver/frida';
45
import { AppItem, ProcessItem, TargetItem } from "../providers/devices";
@@ -8,12 +9,12 @@ import { interpreter } from '../utils';
89

910
export async function explore(target: TargetItem) : Promise<void> {
1011
if (!target) {
11-
vscode.window.showErrorMessage('This command is only expected to be used in the context menu');
12+
vscode.window.showErrorMessage(l10n.t('This command is only expected to be used in the context menu'));
1213
return;
1314
}
1415

1516
if (!(target instanceof AppItem || target instanceof ProcessItem)) {
16-
vscode.window.showErrorMessage('This command is not applicable to the selected item');
17+
vscode.window.showErrorMessage(l10n.t('This command is not applicable to the selected item'));
1718
return;
1819
}
1920

@@ -28,7 +29,7 @@ export async function explore(target: TargetItem) : Promise<void> {
2829
break;
2930
case DeviceType.Local:
3031
device = [];
31-
vscode.window.showErrorMessage('This command is not applicable to the local device');
32+
vscode.window.showErrorMessage(l10n.t('This command is not applicable to the local device'));
3233
return;
3334
case DeviceType.USB:
3435
default:
@@ -41,7 +42,8 @@ export async function explore(target: TargetItem) : Promise<void> {
4142
try {
4243
gadget = (await launch(target.device.id, target.data.identifier)).toString();
4344
} catch (e) {
44-
vscode.window.showWarningMessage(`Warning: failed to launch App ${target.data.identifier}\n${e}`);
45+
vscode.window.showWarningMessage(
46+
l10n.t('Warning: failed to launch App {0}\n{1}', target.data.identifier, `${e}`));
4547
gadget = target.data.name;
4648
}
4749
}

src/commands/repl.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { expandDevParam, interpreter, refresh } from '../utils';
1010
const terminals = new Set<vscode.Terminal>();
1111

1212
async function repl(args: string[], id: string) {
13-
const name = `Frida - ${id}`;
13+
const name = vscode.l10n.t('Frida - {0}', id);
1414
const shellPath = await interpreter();
1515
const py = path.join(__dirname, '..', '..', 'backend', 'pause.py');
1616
const shellArgs = [py, shellPath, '-m', 'frida_tools.repl', ...args];
@@ -47,7 +47,7 @@ export function kill(node?: TargetItem) {
4747
terminate(node.device.id, node.data.pid.toString());
4848
refresh();
4949
} else {
50-
vscode.window.showWarningMessage(`Target is not running`);
50+
vscode.window.showWarningMessage(vscode.l10n.t('Target is not running'));
5151
}
5252
}
5353

@@ -56,7 +56,8 @@ export function attach(node?: TargetItem) {
5656

5757
if (node instanceof AppItem || node instanceof ProcessItem) {
5858
if (!node.data.pid) {
59-
vscode.window.showErrorMessage(`App "${node.data.name}" must be running before attaching to it`);
59+
vscode.window.showErrorMessage(
60+
vscode.l10n.t('App "{0}" must be running before attaching to it', node.data.name));
6061
}
6162

6263
repl([node.data.pid.toString(), ...expandDevParam(node)], node.data.pid.toString());
@@ -65,8 +66,8 @@ export function attach(node?: TargetItem) {
6566

6667
export async function addRemote() {
6768
const host = await vscode.window.showInputBox({
68-
placeHolder: "192.168.1.2:27042",
69-
prompt: "Host or IP of the remote device",
69+
placeHolder: '192.168.1.2:27042',
70+
prompt: vscode.l10n.t('Host or IP of the remote device'),
7071
value: ''
7172
});
7273

src/commands/ssh.ts

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { spawn } from 'child_process';
2-
import { commands, window } from 'vscode';
2+
import { commands, window, l10n } from 'vscode';
33

44
import { os } from '../driver/backend';
55
import { DeviceItem, TargetItem } from '../providers/devices';
@@ -22,22 +22,22 @@ async function findSSHPort(device: DeviceItem) {
2222
inetcat
2323
.on('error', (err) => {
2424
if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
25-
reject(new ToolNotFoundError('inetcat not found'));
25+
reject(new ToolNotFoundError(l10n.t('inetcat not found')));
2626
} else {
2727
reject(err);
2828
}
2929
})
3030
.on('close', (code) => {
3131
if (code !== 0) {
32-
reject(new InvalidProtocolError(`inetcat exited with code ${code}`));
32+
reject(new InvalidProtocolError(l10n.t('inetcat exited with code {0}', `${code}`)));
3333
}
3434
});
3535

3636
inetcat.stdout.once('data', (data) => {
3737
if (data.slice(0, magic.length).equals(magic)) {
3838
resolve(true);
3939
} else {
40-
reject(new InvalidProtocolError(`port ${port} did not return SSH banner`));
40+
reject(new InvalidProtocolError(l10n.t('Invalid protocol')));
4141
}
4242
inetcat.stdin.end();
4343
});
@@ -61,12 +61,13 @@ async function findSSHPort(device: DeviceItem) {
6161
}
6262
}
6363

64-
throw new PortNotFoundError('No valid SSH port found');
64+
throw new PortNotFoundError(l10n.t('No valid SSH port found'));
6565
}
6666

6767
export async function shell(node: TargetItem) {
6868
if (!(node instanceof DeviceItem)) {
69-
window.showErrorMessage('This command is only avaliable on context menu');
69+
window.showErrorMessage(
70+
l10n.t('This command is only expected to be used in the context menu'));
7071
return;
7172
}
7273

@@ -77,12 +78,13 @@ export async function shell(node: TargetItem) {
7778
}
7879

7980
const system = await os(node.data.id);
80-
const name = `SSH: ${node.data.name}`;
81+
const name = l10n.t('SSH: {0}', node.data.name);
8182
let shellPath, shellArgs;
8283

8384
if (system === 'ios') {
8485
if (process.platform === 'win32') {
85-
window.showErrorMessage('This feature is not enabled on Windows due to lack of inetcat');
86+
window.showErrorMessage(
87+
l10n.t('This feature is not enabled on Windows due to lack of inetcat'));
8688
return
8789
}
8890

@@ -98,10 +100,10 @@ export async function shell(node: TargetItem) {
98100
];
99101
} catch (err) {
100102
if (err instanceof ToolNotFoundError) {
101-
window.showErrorMessage('inetcat command not present in $PATH');
103+
window.showErrorMessage(l10n.t('inetcat command not present in $PATH'));
102104
return;
103105
} else if (err instanceof PortNotFoundError) {
104-
window.showErrorMessage(`No valid SSH port found for device ${node.data.name}`);
106+
window.showErrorMessage(l10n.t('No valid SSH port found for device {0}', node.data.name));
105107
return;
106108
}
107109
}
@@ -110,7 +112,7 @@ export async function shell(node: TargetItem) {
110112
shellPath = executable('adb');
111113
shellArgs = ['-s', node.data.id, 'shell'];
112114
} else {
113-
window.showErrorMessage(`OS type "${system}" is not supported`);
115+
window.showErrorMessage(l10n.t("OS type {0} is not supported", system));
114116
return;
115117
}
116118

0 commit comments

Comments
 (0)