Fix: Decode client file path correctly in client list and info popup
The client reports its own exe path as UTF-8 in RES_FILE_PATH. Two
display sites re-decoded those bytes with the wrong code page and turned
Chinese paths into mojibake on non-Chinese servers:
- The client-list "程序路径" column wrote ProgramPath through the ANSI
SetItemText path, so the UTF-8 bytes were misread as the system ACP.
Decode UTF-8 to wide and write with LVM_SETITEMTEXTW instead (same
pattern as the window/process lists).
- The double-click info popup normalized the client RES_* fields to the
system ACP and rendered strText with CP_ACP -> wide. The app's internal
ANSI convention is fixed GBK/936 (/execution-charset:.936 plus
setlocale(".936")), so on non-Chinese systems the path collapsed to '?'.
Normalize to 936 and decode 936 instead, which also fixes the popup's
GBK labels and username in the same pass.
Co-Authored-By: deepseek-v4-pro
This commit is contained in:
1 parent
ff6b290580
commit
f3a8406050
2 files changed
+35
-13
No files matched your search
@@ -5,6 +5,7 @@
|
||||
#include "afxdialogex.h"
|
||||
#include "CClientListDlg.h"
|
||||
#include "2015Remote.h"
|
||||
#include <string>
|
||||
|
||||
|
||||
// CClientListDlg 对话框
|
||||
@@ -93,6 +94,27 @@ static CString GetFieldValue(const ClientValue& val, GroupField field)
|
||||
}
|
||||
}
|
||||
|
||||
// 客户端自报的程序路径是 UTF-8(见 client/LoginServer.cpp 的 RES_FILE_PATH),
|
||||
// 这里用 LVM_SETITEMTEXTW 直接写宽字符串,绕开 ANSI→CP_ACP 回转,
|
||||
// 即使服务端运行在非中文 ACP(如德语)上,中文路径也能正常显示(与窗口/进程管理同法)。
|
||||
static void SetProgramPathText(CListCtrl& list, int iItem, int iSubItem, const char* sz)
|
||||
{
|
||||
std::wstring w;
|
||||
if (sz && sz[0]) {
|
||||
int wlen = MultiByteToWideChar(CP_UTF8, 0, sz, -1, NULL, 0);
|
||||
if (wlen > 1) {
|
||||
w.resize(wlen - 1);
|
||||
MultiByteToWideChar(CP_UTF8, 0, sz, -1, &w[0], wlen);
|
||||
}
|
||||
}
|
||||
LVITEMW lv = {};
|
||||
lv.mask = LVIF_TEXT;
|
||||
lv.iItem = iItem;
|
||||
lv.iSubItem = iSubItem;
|
||||
lv.pszText = w.empty() ? const_cast<LPWSTR>(L"") : &w[0];
|
||||
::SendMessageW(list.GetSafeHwnd(), LVM_SETITEMTEXTW, (WPARAM)iItem, (LPARAM)&lv);
|
||||
}
|
||||
|
||||
// 比较两个客户端的指定列,返回 <0, 0, >0
|
||||
static int CompareClientByColumn(const std::pair<ClientKey, ClientValue>& a,
|
||||
const std::pair<ClientKey, ClientValue>& b,
|
||||
@@ -299,7 +321,7 @@ void CClientListDlg::DisplayClients()
|
||||
m_ClientList.SetItemText(nItem, COL_OS, val.OsName);
|
||||
m_ClientList.SetItemText(nItem, COL_INSTALL_TIME, val.InstallTime);
|
||||
m_ClientList.SetItemText(nItem, COL_LAST_LOGIN, val.LastLoginTime);
|
||||
m_ClientList.SetItemText(nItem, COL_PROGRAM_PATH, CString(val.ProgramPath));
|
||||
SetProgramPathText(m_ClientList, nItem, COL_PROGRAM_PATH, val.ProgramPath);
|
||||
m_ClientList.SetItemText(nItem, COL_LEVEL, strLevel);
|
||||
m_ClientList.SetItemText(nItem, COL_AUTH, strAuth);
|
||||
m_ClientList.SetItemData(nItem, (DWORD_PTR)key);
|
||||
@@ -351,7 +373,7 @@ void CClientListDlg::DisplayClients()
|
||||
m_ClientList.SetItemText(nItem, COL_OS, val.OsName);
|
||||
m_ClientList.SetItemText(nItem, COL_INSTALL_TIME, val.InstallTime);
|
||||
m_ClientList.SetItemText(nItem, COL_LAST_LOGIN, val.LastLoginTime);
|
||||
m_ClientList.SetItemText(nItem, COL_PROGRAM_PATH, CString(val.ProgramPath));
|
||||
SetProgramPathText(m_ClientList, nItem, COL_PROGRAM_PATH, val.ProgramPath);
|
||||
m_ClientList.SetItemText(nItem, COL_LEVEL, strLevel);
|
||||
m_ClientList.SetItemText(nItem, COL_AUTH, strAuth);
|
||||
m_ClientList.SetItemData(nItem, (DWORD_PTR)key);
|
||||
|
||||
Reference in new issue
Block a user