mirror of
https://github.com/yuanyuanxiang/SimpleRemoter.git
synced 2026-01-21 23:13:08 +08:00
Fix client offline issue and virtual desktop opening issue
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user