1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2025-12-13 14:53:46 +00:00

Added translation support to windows install dialog

This commit is contained in:
Bryan Roe
2020-12-11 18:47:31 -08:00
parent ca78d1dc26
commit a37b647519
5 changed files with 191 additions and 53 deletions

Binary file not shown.

View File

@@ -104,22 +104,22 @@ CAPTION "Mesh Agent v2"
FONT 8, "MS Shell Dlg", 400, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
PUSHBUTTON "Close",IDCANCEL,260,127,50,14 PUSHBUTTON "Close",IDCANCEL,260,127,50,14
LTEXT "Click the buttons below to install or uninstall the mesh agent. When installed, this software runs in the background allowing this computer to be managed and controlled by a remote administrator.",IDC_STATIC,7,7,275,28 LTEXT "Click the buttons below to install or uninstall the mesh agent. When installed, this software runs in the background allowing this computer to be managed and controlled by a remote administrator.",IDC_DESCRIPTION,7,7,275,28
GROUPBOX "Installation Information",IDC_STATIC,7,38,303,87 GROUPBOX "Installation Information",IDC_STATIC,7,38,303,87
PUSHBUTTON "Install / Update",IDC_INSTALLBUTTON,7,127,65,14 PUSHBUTTON "Install / Update",IDC_INSTALLBUTTON,7,127,65,14
PUSHBUTTON "Uninstall",IDC_UNINSTALLBUTTON,75,127,65,14 PUSHBUTTON "Uninstall",IDC_UNINSTALLBUTTON,75,127,65,14
ICON IDI_ICON1,IDC_STATIC,288,7,20,20 ICON IDI_ICON1,IDC_STATIC,288,7,20,20
LTEXT "Current Agent Status",IDC_STATIC,14,51,70,8 LTEXT "Current Agent Status",IDC_AGENTSTATUS_TEXT,14,51,70,8
LTEXT "Unknown",IDC_STATUSTEXT,127,51,175,8,0,WS_EX_RIGHT LTEXT "Unknown",IDC_STATUSTEXT,127,51,175,8,0,WS_EX_RIGHT
LTEXT "New Agent Version",IDC_STATIC,14,63,62,8 LTEXT "New Agent Version",IDC_AGENT_VERSION,14,63,62,8
LTEXT "Unknown",IDC_VERSIONTEXT,127,63,175,8,0,WS_EX_RIGHT LTEXT "Unknown",IDC_VERSIONTEXT,127,63,175,8,0,WS_EX_RIGHT
LTEXT "New Mesh Identifier",IDC_STATIC,14,99,65,8 LTEXT "New Mesh Identifier",IDC_MESH_IDENTIFIER,14,99,65,8
LTEXT "Unknown",IDC_HASHTEXT,127,99,175,8,0,WS_EX_RIGHT LTEXT "Unknown",IDC_HASHTEXT,127,99,175,8,0,WS_EX_RIGHT
LTEXT "New Mesh Name",IDC_STATIC,14,87,54,8 LTEXT "New Mesh Name",IDC_MESH_NAME,14,87,54,8
LTEXT "Unknown",IDC_POLICYTEXT,127,87,175,8,0,WS_EX_RIGHT LTEXT "Unknown",IDC_POLICYTEXT,127,87,175,8,0,WS_EX_RIGHT
LTEXT "New Server Identifier",IDC_STATIC,14,111,70,8 LTEXT "New Server Identifier",IDC_SERVER_IDENTIFIER,14,111,70,8
LTEXT "Unknown",IDC_SERVERID,127,111,175,8,0,WS_EX_RIGHT LTEXT "Unknown",IDC_SERVERID,127,111,175,8,0,WS_EX_RIGHT
LTEXT "New Server Location",IDC_STATIC,14,75,67,8 LTEXT "New Server Location",IDC_SERVER_LOCATION,14,75,67,8
LTEXT "Unknown",IDC_SERVERLOCATION,127,75,175,8,0,WS_EX_RIGHT LTEXT "Unknown",IDC_SERVERLOCATION,127,75,175,8,0,WS_EX_RIGHT
PUSHBUTTON "Connect",IDC_CONNECTBUTTON,143,127,65,14 PUSHBUTTON "Connect",IDC_CONNECTBUTTON,143,127,65,14
END END

View File

@@ -62,7 +62,7 @@ MeshAgentHostContainer *agent = NULL;
DWORD g_serviceArgc; DWORD g_serviceArgc;
char **g_serviceArgv; char **g_serviceArgv;
extern int gRemoteMouseRenderDefault; extern int gRemoteMouseRenderDefault;
char *DIALOG_LANG = NULL;
/* /*
extern int g_TrustedHashSet; extern int g_TrustedHashSet;
@@ -809,6 +809,8 @@ int wmain(int argc, char* wargv[])
} }
else else
{ {
int skip = 0;
// See if we are running as a service // See if we are running as a service
if (RunService(argc, argv) == 0 && GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) if (RunService(argc, argv) == 0 && GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
{ {
@@ -832,6 +834,36 @@ int wmain(int argc, char* wargv[])
} }
else else
{ {
if (argc == 2 && strcmp(argv[1], "-lang") == 0)
{
char *lang = NULL;
char selfexe[_MAX_PATH];
WCHAR wselfexe[MAX_PATH];
GetModuleFileNameW(NULL, wselfexe, sizeof(wselfexe) / 2);
ILibWideToUTF8Ex(wselfexe, -1, selfexe, (int)sizeof(selfexe));
void *dialogchain = ILibCreateChain();
ILibChain_PartialStart(dialogchain);
duk_context *ctx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(0, 0, dialogchain, NULL, NULL, selfexe, NULL, NULL, dialogchain);
if (duk_peval_string(ctx, "require('util-language').current.toUpperCase().split('-').join('_');") == 0)
{
lang = (char*)duk_safe_to_string(ctx, -1);
printf("Current Language: %s\n", lang);
}
Duktape_SafeDestroyHeap(ctx);
ILibStopChain(dialogchain);
ILibStartChain(dialogchain);
argc = 1;
skip = 1;
}
if (argc == 2 && strlen(argv[1]) > 6 && strncmp(argv[1], "-lang=", 6) == 0)
{
DIALOG_LANG = argv[1] + 1 + ILibString_IndexOf(argv[1], strlen(argv[1]), "=", 1);
argc = 1;
}
if (argc != 1) if (argc != 1)
{ {
printf("Mesh Agent available switches:\r\n"); printf("Mesh Agent available switches:\r\n");
@@ -854,7 +886,7 @@ int wmain(int argc, char* wargv[])
printf(" --WebProxy=\"http://proxyhost:port\" Specify an HTTPS proxy.\r\n"); printf(" --WebProxy=\"http://proxyhost:port\" Specify an HTTPS proxy.\r\n");
printf(" --agentName=\"alternate name\" Specify an alternate name to be provided by the agent.\r\n"); printf(" --agentName=\"alternate name\" Specify an alternate name to be provided by the agent.\r\n");
} }
else else if(skip==0)
{ {
// This is only supported on Windows 8 / Windows Server 2012 R2 and newer // This is only supported on Windows 8 / Windows Server 2012 R2 and newer
FreeConsole(); FreeConsole();
@@ -879,7 +911,7 @@ int wmain(int argc, char* wargv[])
SetProcessDPIAware(); SetProcessDPIAware();
} }
DialogBox(NULL, MAKEINTRESOURCE(IDD_INSTALLDIALOG), NULL, DialogHandler); DialogBoxW(NULL, MAKEINTRESOURCEW(IDD_INSTALLDIALOG), NULL, DialogHandler);
} }
} }
} }
@@ -967,6 +999,35 @@ char* getMshSettings(char* fileName, char* selfexe, char** meshname, char** mesh
#ifndef _MINCORE #ifndef _MINCORE
WCHAR *Dialog_GetTranslationEx(void *ctx, char *utf8)
{
WCHAR *ret = NULL;
if (utf8 != NULL)
{
int wlen = ILibUTF8ToWideCount(utf8);
ret = (WCHAR*)Duktape_PushBuffer(ctx, sizeof(WCHAR)*wlen + 1);
duk_swap_top(ctx, -2);
ILibUTF8ToWideEx(utf8, -1, ret, wlen);
}
return(ret);
}
WCHAR *Dialog_GetTranslation(void *ctx, char *property)
{
WCHAR *ret = NULL;
char *utf8 = Duktape_GetStringPropertyValue(ctx, -1, property, NULL);
if (utf8 != NULL)
{
int wlen = ILibUTF8ToWideCount(utf8);
ret = (WCHAR*)Duktape_PushBuffer(ctx, sizeof(WCHAR)*wlen + 1);
duk_swap_top(ctx, -2);
ILibUTF8ToWideEx(utf8, -1, ret, wlen);
}
return(ret);
}
WCHAR closeButtonText[255] = { 0 };
int closeButtonTextSet = 0;
// Message handler for dialog box. // Message handler for dialog box.
INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{ {
@@ -979,15 +1040,84 @@ INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
{ {
char selfexe[_MAX_PATH]; char selfexe[_MAX_PATH];
char *lang = NULL; char *lang = NULL;
void *chain = ILibCreateChain();
ILibChain_PartialStart(chain); WCHAR *agentstatus = NULL;
duk_context *ctx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(0, 0, chain, NULL, NULL, "", NULL, NULL, chain); WCHAR *agentversion = NULL;
if (duk_peval_string(ctx, "require('util-language').current;") == 0) { lang = (char*)duk_safe_to_string(ctx, -1); } WCHAR *serverlocation = NULL;
WCHAR *meshname = NULL;
WCHAR *meshidentitifer = NULL;
WCHAR *serveridentifier = NULL;
WCHAR *dialogdescription = NULL;
WCHAR *install_buttontext = NULL;
WCHAR *update_buttontext = NULL;
WCHAR *uninstall_buttontext = NULL;
WCHAR *connect_buttontext = NULL;
WCHAR *cancel_buttontext = NULL;
WCHAR *disconnect_buttontext = NULL;
WCHAR *state_notinstalled = NULL;
WCHAR *state_running = NULL;
WCHAR *state_notrunning = NULL;
// Get current executable path // Get current executable path
WCHAR wselfexe[MAX_PATH]; WCHAR wselfexe[MAX_PATH];
GetModuleFileNameW(NULL, wselfexe, sizeof(wselfexe) / 2); GetModuleFileNameW(NULL, wselfexe, sizeof(wselfexe) / 2);
ILibWideToUTF8Ex(wselfexe, -1, selfexe, (int)sizeof(selfexe)); ILibWideToUTF8Ex(wselfexe, -1, selfexe, (int)sizeof(selfexe));
void *dialogchain = ILibCreateChain();
ILibChain_PartialStart(dialogchain);
duk_context *ctx = ILibDuktape_ScriptContainer_InitializeJavaScriptEngineEx(0, 0, dialogchain, NULL, NULL, selfexe, NULL, NULL, dialogchain);
if (duk_peval_string(ctx, "require('util-language').current.toUpperCase().split('-').join('_');") == 0) { lang = (char*)duk_safe_to_string(ctx, -1); }
if (duk_peval_string(ctx, "(function foo(){return(JSON.parse(_MSH().translation));})()") == 0)
{
if (DIALOG_LANG != NULL) { lang = DIALOG_LANG; }
if (duk_has_prop_string(ctx, -1, lang))
{
duk_get_prop_string(ctx, -1, lang);
agentstatus = Dialog_GetTranslation(ctx, "statusDescription");
if (agentstatus != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_AGENTSTATUS_TEXT), agentstatus); }
agentversion = Dialog_GetTranslation(ctx, "agentVersion");
if (agentversion != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_AGENT_VERSION), agentversion); }
serverlocation = Dialog_GetTranslation(ctx, "url");
if (serverlocation != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_SERVER_LOCATION), serverlocation); }
meshname = Dialog_GetTranslation(ctx, "meshName");
if (meshname != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_MESH_NAME), meshname); }
meshidentitifer = Dialog_GetTranslation(ctx, "meshId");
if (meshidentitifer != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_MESH_IDENTIFIER), meshidentitifer); }
serveridentifier = Dialog_GetTranslation(ctx, "serverId");
if (serveridentifier != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_SERVER_IDENTIFIER), serveridentifier); }
dialogdescription = Dialog_GetTranslation(ctx, "description");
if (dialogdescription != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_DESCRIPTION), dialogdescription); }
install_buttontext = Dialog_GetTranslation(ctx, "install");
update_buttontext = Dialog_GetTranslation(ctx, "update");
uninstall_buttontext = Dialog_GetTranslation(ctx, "uninstall");
cancel_buttontext = Dialog_GetTranslation(ctx, "cancel");
disconnect_buttontext = Dialog_GetTranslation(ctx, "disconnect");
if (disconnect_buttontext != NULL)
{
wcscpy_s(closeButtonText, sizeof(closeButtonText) / 2, disconnect_buttontext);
closeButtonTextSet = 1;
}
if (uninstall_buttontext != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_UNINSTALLBUTTON), uninstall_buttontext); }
connect_buttontext = Dialog_GetTranslation(ctx, "connect");
if (connect_buttontext != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDC_CONNECTBUTTON), connect_buttontext); }
if (cancel_buttontext != NULL) { SetWindowTextW(GetDlgItem(hDlg, IDCANCEL), cancel_buttontext); }
duk_get_prop_string(ctx, -1, "status"); // [Array]
state_notinstalled = Dialog_GetTranslationEx(ctx, Duktape_GetStringPropertyIndexValue(ctx, -1, 0, NULL));
state_running = Dialog_GetTranslationEx(ctx, Duktape_GetStringPropertyIndexValue(ctx, -1, 1, NULL));
state_notrunning = Dialog_GetTranslationEx(ctx, Duktape_GetStringPropertyIndexValue(ctx, -1, 2, NULL));
}
}
fileName = MeshAgent_MakeAbsolutePath(selfexe, ".msh"); fileName = MeshAgent_MakeAbsolutePath(selfexe, ".msh");
{ {
DWORD dwSize = 0; DWORD dwSize = 0;
@@ -1073,46 +1203,29 @@ INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
// Get the current service running state // Get the current service running state
int r = GetServiceState(meshServiceName != NULL ? meshServiceName : serviceFile); int r = GetServiceState(meshServiceName != NULL ? meshServiceName : serviceFile);
char* txt = ""; SetWindowTextW(GetDlgItem(hDlg, IDC_INSTALLBUTTON), update_buttontext);
SetWindowTextA(GetDlgItem(hDlg, IDC_INSTALLBUTTON), "Update");
switch (r) switch (r)
{ {
case 0:
txt = "Error";
break;
case SERVICE_STOPPED:
txt = "Stopped";
break;
case SERVICE_START_PENDING:
txt = "Start Pending";
break;
case SERVICE_STOP_PENDING:
txt = "Stop Pending";
break;
case SERVICE_RUNNING: case SERVICE_RUNNING:
txt = "Running"; SetWindowTextW(GetDlgItem(hDlg, IDC_STATUSTEXT), state_running);
break; break;
case SERVICE_CONTINUE_PENDING: case 0:
txt = "Continue Pending"; case 100: // Not installed
break; SetWindowTextW(GetDlgItem(hDlg, IDC_STATUSTEXT), state_notinstalled);
case SERVICE_PAUSE_PENDING:
txt = "Pause Pending";
break;
case SERVICE_PAUSED:
txt = "Paused";
break;
case 100:
txt = "Not Installed";
ShowWindow(GetDlgItem(hDlg, IDC_UNINSTALLBUTTON), SW_HIDE); ShowWindow(GetDlgItem(hDlg, IDC_UNINSTALLBUTTON), SW_HIDE);
SetWindowTextA(GetDlgItem(hDlg, IDC_INSTALLBUTTON), "Install"); SetWindowTextW(GetDlgItem(hDlg, IDC_INSTALLBUTTON), install_buttontext);
break;
default: // Not running
SetWindowTextW(GetDlgItem(hDlg, IDC_STATUSTEXT), state_notrunning);
break; break;
} }
SetWindowTextA(GetDlgItem(hDlg, IDC_STATUSTEXT), txt);
if (mshfile != NULL) { free(mshfile); } if (mshfile != NULL) { free(mshfile); }
Duktape_SafeDestroyHeap(ctx); Duktape_SafeDestroyHeap(ctx);
ILibStopChain(chain); ILibStopChain(dialogchain);
ILibStartChain(chain); ILibStartChain(dialogchain);
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
case WM_COMMAND: case WM_COMMAND:
@@ -1175,6 +1288,8 @@ INT_PTR CALLBACK DialogHandler(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
DWORD pid = GetCurrentProcessId(); DWORD pid = GetCurrentProcessId();
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "connect --disableUpdate=1 --hideConsole=1 --exitPID=%u", pid); sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "connect --disableUpdate=1 --hideConsole=1 --exitPID=%u", pid);
if (RunAsAdmin(ILibScratchPad, IsAdmin() == TRUE) == 0) { RunAsAdmin(ILibScratchPad, 1); } if (RunAsAdmin(ILibScratchPad, IsAdmin() == TRUE) == 0) { RunAsAdmin(ILibScratchPad, 1); }
if (closeButtonTextSet != 0) { SetWindowTextW(GetDlgItem(hDlg, IDCANCEL), closeButtonText); }
return (INT_PTR)TRUE; return (INT_PTR)TRUE;
} }
break; break;

View File

@@ -15,9 +15,16 @@
#define IDC_POLICYTEXT 1008 #define IDC_POLICYTEXT 1008
#define IDC_UNINSTALLBUTTON2 1009 #define IDC_UNINSTALLBUTTON2 1009
#define IDC_CONNECTBUTTON 1009 #define IDC_CONNECTBUTTON 1009
#define IDC_AGENTSTATUS_TEXT 1010
#define IDC_HASHTEXT3 1011 #define IDC_HASHTEXT3 1011
#define IDC_SERVERID 1011 #define IDC_SERVERID 1011
#define IDC_SERVERLOCATION 1012 #define IDC_SERVERLOCATION 1012
#define IDC_AGENT_VERSION 1013
#define IDC_SERVER_LOCATION 1014
#define IDC_MESH_NAME 1015
#define IDC_MESH_IDENTIFIER 1016
#define IDC_SERVER_IDENTIFIER 1017
#define IDC_DESCRIPTION 1018
// Next default values for new objects // Next default values for new objects
// //
@@ -25,7 +32,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 106 #define _APS_NEXT_RESOURCE_VALUE 106
#define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1006 #define _APS_NEXT_CONTROL_VALUE 1019
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View File

@@ -96,8 +96,12 @@ limitations under the License.
EN_US: EN_US:
{ {
agent: 'Agent', agent: 'Agent',
agentVersion: 'New Agent Version',
group: 'Device Group', group: 'Device Group',
url: 'Server URL', url: 'Server URL',
meshName: 'Mesh Name',
meshId: 'Mesh Identifier',
serverId: 'Server Identifier',
setup: 'Setup', setup: 'Setup',
update: 'Update', update: 'Update',
install: 'Install', install: 'Install',
@@ -112,13 +116,19 @@ limitations under the License.
commands: 'You can run the text version from the command line with the following command(s)', commands: 'You can run the text version from the command line with the following command(s)',
graphicalerror: 'The graphical version of this installer canot run on this system', graphicalerror: 'The graphical version of this installer canot run on this system',
zenity: 'Try installing/updating Zenity, and run again', zenity: 'Try installing/updating Zenity, and run again',
status: ['NOT INSTALLED', 'RUNNING', 'NOT RUNNING'] status: ['NOT INSTALLED', 'RUNNING', 'NOT RUNNING'],
statusDescription: 'Current Agent Status',
description: 'Click the buttons below to install or uninstall the mesh agent. When installed, this software runs in the background allowing this computer to be managed and controlled by a remote administrator.'
}, },
KO_KR: KO_KR:
{ {
agent: '에이전트', agent: '에이전트',
agentVersion: '새에이전트 버전',
group: '장치 그룹', group: '장치 그룹',
url: '서버 위치', url: '서버 위치',
meshName: '메시의 이름',
meshId: '메시의 식별자',
serverId: '서버의 식별자',
setup: '설정하다', setup: '설정하다',
update: '개조하다', update: '개조하다',
install: '설치하려면', install: '설치하려면',
@@ -133,7 +143,9 @@ limitations under the License.
commands: '다음 명령을 사용하여 콘솔에서 텍스트 버전을 실행할 수 있습니다', commands: '다음 명령을 사용하여 콘솔에서 텍스트 버전을 실행할 수 있습니다',
graphicalerror: '이 프로그램의 그래픽 버전이 시스템에서 실행할 수 없습니다', graphicalerror: '이 프로그램의 그래픽 버전이 시스템에서 실행할 수 없습니다',
zenity: '"Zenity"를 설치 또는 업데이트하고 다시 시도하십시오', zenity: '"Zenity"를 설치 또는 업데이트하고 다시 시도하십시오',
status: ['없다', '운영', '중지됨'] status: ['없다', '운영', '중지됨'],
statusDescription: '에이전트 상태',
description: '메시 에이전트를 설치 또는 제거하려면 아래 버튼을 클릭하십시오. 이 프로그램은 설치하면 백그라운드에서 실행되므로 원격 관리자가이 컴퓨터를 관리하고 제어 할 수 있습니다.'
} }
}; };
@@ -224,7 +236,11 @@ limitations under the License.
console.log(JSON.stringify(msh, null, 2)); console.log(JSON.stringify(msh, null, 2));
process.exit(); process.exit();
} }
if (process.argv.includes('-translations'))
{
console.log(JSON.stringify(translation));
process.exit();
}
if (process.argv.includes('-help')) if (process.argv.includes('-help'))
{ {
console.log("\n" + translation[lang].commands + ": "); console.log("\n" + translation[lang].commands + ": ");