windows 平臺如何點擊網頁上的url ,會打開遠程桌面連接服務器

你可以使用自定義協議方案(Protocol Scheme)實現網頁上點擊URL后自動啟動遠程桌面連接(mstsc),參考你提供的C++代碼思路,如下實現:

第一步:注冊自定義協議

使用類似openmstsc://協議。

注冊示例 (reg 文件形式)
Windows Registry Editor Version 5.00[HKEY_CLASSES_ROOT\openmstsc]
@="URL:openmstsc Protocol"
"URL Protocol"=""[HKEY_CLASSES_ROOT\openmstsc\shell\open\command]
@="\"C:\\your-path\\open_mstsc.exe\" \"%1\""

或通過你的C++代碼自動完成注冊(代碼里已經包含該功能)。


第二步:網頁中調用協議URL

網頁端代碼(簡單HTML):

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>遠程桌面連接示例</title>
</head>
<body><a href="openmstsc://192.168.1.100:3389">連接遠程桌面 192.168.1.100</a>
</body>
</html>

注意:

  • 點擊此鏈接時,瀏覽器會提示用戶是否允許調用該協議(首次使用時會詢問),確認即可。

第三步:你的C++程序實現要點(已提供,以下強調注意點)

你的C++程序中關鍵實現點(你代碼中已經包含了):

  • 解析傳入的URL,提取IP:端口
  • 使用ShellExecuteExW調用mstsc.exe并傳入/v:IP:Port參數。

示例(摘錄):

void OpenWithMstsc(const std::wstring& serverIP) {if (serverIP.empty()) return;std::wstring mstscArgs = L"/v:" + serverIP;SHELLEXECUTEINFOW sei = { sizeof(sei) };sei.lpFile = L"mstsc.exe";sei.lpParameters = mstscArgs.c_str();sei.nShow = SW_SHOWNORMAL;sei.fMask = SEE_MASK_NOASYNC;ShellExecuteExW(&sei);
}

完整流程說明

  1. 網頁鏈接點擊 → 瀏覽器觸發openmstsc://IP:Port
  2. 瀏覽器調用注冊好的協議→ 執行open_mstsc.exe,傳入參數。
  3. 程序解析URL → 調用mstsc.exe→ 遠程桌面客戶端打開。

這樣即可實現點擊網頁上的鏈接自動打開遠程桌面連接的功能。

// open_mstsc.cpp
// C++ 重寫版本:實現與 C# 相同功能,包括注冊自定義協議、解析 URL,并通過 WPS 打開文件,且不彈出控制臺窗口。
//語言功能 "結構化綁定" 需要編譯器標志 "/std:c++17"
//鏈接器-》系統-》子系統-》窗口模式
#include <windows.h>
#include <shlwapi.h>
#include <iostream>
#include <string>
#include <urlmon.h>
#include <shellapi.h>
#include <algorithm> // for std::transform
#pragma comment(lib, "Shlwapi.lib")
#pragma comment(lib, "urlmon.lib")
#include <cctype>
const std::wstring PROTOCOL_NAME = L"openMstsc";
#include <windows.h>
#include <shellapi.h>bool IsRunAsAdmin() {BOOL isAdmin = FALSE;PSID adminGroup;SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,0, 0, 0, 0, 0, 0, &adminGroup)) {CheckTokenMembership(NULL, adminGroup, &isAdmin);FreeSid(adminGroup);}return isAdmin;
}void RelaunchAsAdmin() {wchar_t exePath[MAX_PATH];GetModuleFileNameW(NULL, exePath, MAX_PATH);SHELLEXECUTEINFOW sei = { sizeof(sei) };sei.lpVerb = L"runas"; // 以管理員權限運行sei.lpFile = exePath;sei.nShow = SW_SHOWNORMAL;sei.fMask = SEE_MASK_NOASYNC;if (ShellExecuteExW(&sei)) {ExitProcess(0); // 關閉當前進程}
}
// 替代 HttpUtility.UrlDecode 的簡單實現
// 使用 UrlUnescapeW API 進行解碼
static std::wstring UrlDecode(const std::wstring& encoded) {if (encoded.empty()) return L"";// 預留緩沖區存放解碼后的結果const size_t BUFFER_SIZE = 4096;wchar_t buffer[BUFFER_SIZE];wcsncpy_s(buffer, encoded.c_str(), BUFFER_SIZE);DWORD dwSize = (DWORD)BUFFER_SIZE;HRESULT hr = UrlUnescapeW(buffer, NULL, &dwSize, URL_UNESCAPE_INPLACE);if (SUCCEEDED(hr)) {return std::wstring(buffer);}else {// 如果解碼失敗,可以根據需求返回空字符串或原始值return L"";}
}static std::wstring ProcessServerIP(const std::wstring& inputUrl, const std::wstring& protocolName)
{// 1) 構造 "{protocol}://" 的小寫形式std::wstring lowerProtocol = protocolName;std::transform(lowerProtocol.begin(), lowerProtocol.end(), lowerProtocol.begin(), ::towlower);std::wstring protocolPrefix = lowerProtocol + L"://";// 2) 轉換 inputUrl 為小寫進行查找std::wstring lowerInput = inputUrl;std::transform(lowerInput.begin(), lowerInput.end(), lowerInput.begin(), ::towlower);// 3) 移除 "protocol://"std::wstring url;size_t pos = lowerInput.find(protocolPrefix);if (pos != std::wstring::npos){url = inputUrl.substr(pos + protocolPrefix.size());}else{url = inputUrl;  // 原始 URL}// 4) URL 解碼(假設 UrlDecode 是可用函數)url = UrlDecode(url);// 5) 去除路徑部分,僅保留 "host:port"size_t pathPos = url.find(L'/');if (pathPos != std::wstring::npos){url = url.substr(0, pathPos);}return url;
}//-----------------------------------------------------------
// 下面是原有的函數聲明與實現
//-----------------------------------------------------------void RegisterUrlScheme(const std::wstring& protocol, const std::wstring& exePath);
std::wstring GetRegisteredPath(const std::wstring& protocol);void OpenWithMstsc(const std::wstring& fileUrl);
std::pair<std::wstring, std::wstring> GetWpsLauncherPath();
void EnsureUrlScheme(const std::wstring& protocol);int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
//int main(){if (!IsRunAsAdmin()) {RelaunchAsAdmin(); // 如果不是管理員權限,則重新以管理員權限運行return 0;}EnsureUrlScheme(PROTOCOL_NAME);int argc;LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);if (argv == NULL) return 0;if (argc < 2) {//MessageBoxW(NULL, L"?? 未檢測到 URL 參數。", L"提示", MB_OK | MB_ICONWARNING);return 0;}// 調用新版 ProcessUrlstd::wstring url = ProcessServerIP(argv[1], PROTOCOL_NAME);if (PathIsURLW(url.c_str())) {OpenWithMstsc(url);}else {}LocalFree(argv);return 0;
}void EnsureUrlScheme(const std::wstring& protocol) {wchar_t exePath[MAX_PATH];GetModuleFileNameW(NULL, exePath, MAX_PATH);std::wstring registeredPath = GetRegisteredPath(protocol);if (registeredPath.empty() || !_wcsicmp(registeredPath.c_str(), exePath) == 0) {RegisterUrlScheme(protocol, exePath);}
}std::wstring GetRegisteredPath(const std::wstring& protocol) {HKEY hKey;std::wstring regPath = L"";std::wstring keyPath = protocol + L"\\shell\\open\\command";if (RegOpenKeyExW(HKEY_CLASSES_ROOT, keyPath.c_str(), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {wchar_t value[MAX_PATH];DWORD value_length = sizeof(value);if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)value, &value_length) == ERROR_SUCCESS) {std::wstring commandLine(value);size_t firstQuoteEnd = commandLine.find(L'"', 1);if (firstQuoteEnd != std::wstring::npos) {regPath = commandLine.substr(1, firstQuoteEnd - 1);}}RegCloseKey(hKey);}return regPath;
}void RegisterUrlScheme(const std::wstring& protocol, const std::wstring& exePath) {HKEY hKey;std::wstring keyPath = protocol;if (RegCreateKeyExW(HKEY_CLASSES_ROOT, keyPath.c_str(), 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS) {RegSetValueExW(hKey, NULL, 0, REG_SZ, (const BYTE*)(L"URL:" + protocol + L" Protocol").c_str(),(DWORD)((protocol.size() + 10) * sizeof(wchar_t)));RegSetValueExW(hKey, L"URL Protocol", 0, REG_SZ, (const BYTE*)L"", sizeof(wchar_t));HKEY hCommandKey;if (RegCreateKeyExW(hKey, L"shell\\open\\command", 0, NULL, 0, KEY_WRITE, NULL, &hCommandKey, NULL) == ERROR_SUCCESS) {std::wstring command = L"\"" + exePath + L"\" \"%1\"";RegSetValueExW(hCommandKey, NULL, 0, REG_SZ, (const BYTE*)command.c_str(), (DWORD)(command.size() * sizeof(wchar_t)));RegCloseKey(hCommandKey);}RegCloseKey(hKey);MessageBoxW(NULL, L"遠程組件注冊成功。", L"成功", MB_OK | MB_ICONINFORMATION);}
}void OpenWithMstsc(const std::wstring& serverIP) {if (serverIP.empty()) {// MessageBoxW(NULL, L"? 服務器 IP 不能為空。", L"錯誤", MB_OK | MB_ICONERROR);return;}// 遠程桌面連接的完整命令行參數std::wstring mstscArgs = L"/v:" + serverIP;SHELLEXECUTEINFOW sei = { sizeof(sei) };sei.lpFile = L"mstsc.exe";  // 遠程桌面客戶端sei.lpParameters = mstscArgs.c_str();sei.nShow = SW_SHOWNORMAL;sei.fMask = SEE_MASK_NOASYNC;if (!ShellExecuteExW(&sei)) {// MessageBoxW(NULL, L"? 無法啟動遠程桌面連接。", L"錯誤", MB_OK | MB_ICONERROR);}
}

注意上面代碼要以管理員權限運行才能正確寫入注冊表,否則失敗

下面將繼續實現一下unbuntu上如何實現類似方法

sudo apt install freerdp2-x11 ?
xfreerdp /v:10.10.10.11:33389 /u:username /p:passwrod /cert-ignore /dynamic-resolution or( /w:1440 /h:900)


?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/72734.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/72734.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/72734.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

UniApp 運行的微信小程序如何進行深度優化

UniApp 運行的微信小程序如何進行深度優化 目錄 引言性能優化 1. 減少包體積2. 優化頁面加載速度3. 減少 setData 調用4. 使用分包加載 代碼優化 1. 減少不必要的代碼2. 使用條件編譯3. 優化圖片資源 用戶體驗優化 1. 優化交互體驗2. 預加載數據3. 使用骨架屏 調試與監控 1. …

ESP32S3N16R8驅動ST7701S屏幕(vscode+PlatfoemIO)

1.開發板配置 本人開發板使用ESP32S3-wroom1-n16r8最小系統板 由于基于vscode與PlatformIO框架開發&#xff0c;無espidf框架&#xff0c;因此無法直接燒錄程序&#xff0c;配置開發板參數如下&#xff1a; 在platformio.ini文件中&#xff0c;配置使用esp32-s3-devkitc-1開發…

ASP.NET 微服務網關 Ocelot+Consul+Skywalking

ASP.NET 微服務網關 OcelotConsulSkywalking APIGateWaySample簡介網關相關技術核心其它 請求處理流程環境搭建代碼運行效果圖 APIGateWaySample Ocelot Consul Skywalking 簡介 系統設計圖 網關 API網關&#xff08;Gateway&#xff09;是一個服務器&#xff0c;是系統…

頻譜分析儀的使用

頻譜分析儀設置帶寬的方式&#xff1a; 可以利用同軸線纜來制作近場探頭&#xff1a; 區別dB和dBm兩個單位&#xff1a; 無線電波的發射功率是指在給定頻段范圍內的能量&#xff0c;通常有兩種衡量 或測量標準&#xff1a;   1、功率&#xff08;W&#xff09;&#xff1a;相…

【數據分析】轉錄組基因表達的KEGG通路富集分析教程

禁止商業或二改轉載,僅供自學使用,侵權必究,如需截取部分內容請后臺聯系作者! 文章目錄 介紹差異分析(limma)KEGG富集分析(enrichKEGG)可視化加載R包數據下載導入數據基因差異分析火山圖KEGG通路富集分析可視化通路結果另一個案例總結系統信息參考介紹 KEGG富集分析,可…

關于sqlalchemy的使用

關于sqlalchemy的使用 說明一、sqlachemy總體使用思路二、安裝與創建庫、連結庫三、創建表、增加數據四、查詢記錄五、更新或刪除六、關聯表定義 說明 本教程所需軟件及庫python3.10、sqlalchemy安裝與創建庫、連結庫創建表、增加數據查詢記錄 一、sqlachemy總體使用思路 在…

在 IntelliJ IDEA 中使用 JUnit 進行單元測試

1. 介紹 JUnit JUnit 是 Java 語言中最流行的單元測試框架之一。它基于 xUnit 設計模式&#xff0c;支持 測試自動化、斷言&#xff08;Assertions&#xff09;和測試生命周期管理&#xff0c;是 Java 開發中進行 TDD&#xff08;測試驅動開發&#xff09; 的重要工具。 JUni…

單片機的發展

一、引言 單片機自誕生以來&#xff0c;經歷了四十多年的風風雨雨&#xff0c;從最初的工業控制逐步擴展到家電、通信、智能家居等各個領域。其發展過程就像是一場精彩的冒險&#xff0c;每一次技術的革新都像是在未知的海域中開辟新的航線。 二、單片機的發展歷程 &#xff…

常見的博弈模型有哪些

常見的博弈模型有哪些 目錄 常見的博弈模型有哪些**1. 重復博弈(Repeated Game)****2. 進化博弈論(Evolutionary Game Theory)****3. 機制設計(Mechanism Design)****4. 微分博弈(Differential Game)****5. 貝葉斯博弈(Bayesian Game)****6. 合作博弈(Cooperative G…

【MySQL-數據類型】數據類型分類+數值類型+文本、二進制類型+String類型

一、數據類型分類 二、數值類型 1.bit類型 測試環境ubuntu 基本語法&#xff1a; bit[(M)]&#xff1a;位字段類型&#xff0c;M表示每個值的位數&#xff0c;范圍從1&#xff5e;64&#xff1b;如果M被忽略&#xff0c;默認為1舉例&#xff1a; create table testBit(id i…

golang從入門到做牛馬:第一篇-我與golang的緣分,go語言簡介

還記得2018年的夏天,剛畢業的我不知道該做些什么,于是自學了一周的go語言,想要找一份go語言工作的代碼,當時的go還沒有go mod來管理依賴包,在北京找了一個月的工作,找到了一個小公司做了后端開發,當然使用go語言開發,帶著興奮勁,年輕身體也好,邊努力學習,邊工作。 時…

【數據庫】MySQL常見聚合查詢詳解

在數據庫操作中&#xff0c;聚合查詢是非常重要的一部分。通過聚合查詢&#xff0c;我們可以對數據進行匯總、統計和分析。MySQL提供了豐富的聚合函數來滿足不同的需求。本文將詳細介紹MySQL中常見的40個聚合函數及其使用場景&#xff0c;并通過8個的案例展示它們的用法。 一、…

調研:如何實現智能分析助手(Agent)(AutoCoder、FastGPT、AutoGen、DataCopilot)

文章目錄 調研&#xff1a;如何實現智能分析助手&#xff08;Agent&#xff09;&#xff08;AutoCoder、FastGPT、AutoGen、DataCopilot&#xff09;一、交互流程二、數據流程三、架構分類四、開源產品4.1 AutoCoder&#xff08;知識庫變體&#xff09;4.2 FastGPT&#xff08;…

【Vue CLI腳手架開發】——6.scoped樣式

文章目錄 一、scoped是什么二、應用案例1.使用代碼2.原理3父組件App未添加scoped影響 一、scoped是什么 我們知道vue為了防止css樣式污染&#xff0c;在每個組件中提供了 scoped屬性進行限定css作用域&#xff1b;當<style>標簽有 scoped 屬性時&#xff0c;它的 CSS 只…

高精算法的用法及其優勢

高精度問題是指當數據的位數非常大&#xff08;超出標準數據類型的范圍&#xff09;時&#xff0c;如何進行計算和存儲的問題。常見場景包括大整數的加、減、乘、除、取模等操作。以下是解決高精度問題的常用方法與技巧&#xff1a; 一、數據存儲 數組存儲 用整型數組存儲&am…

VM+CentOS虛擬機

關于VMCentOS虛擬機的配置和使用&#xff0c;可以參考以下博客中的詳細教程&#xff1a; **一、VMCentOS虛擬機配置** 1. **虛擬機網絡配置** - 在VMware中&#xff0c;點擊“編輯”→“虛擬網絡編輯器”&#xff0c;選擇VMnet8并進行相關設置。 - 子網IP可以改成如192.168.1…

設置 CursorRules 規則

為什么要設置CursorRules&#xff1f; 設置 CursorRules 可以幫助優化代碼生成和開發流程&#xff0c;提升工作效率。具體的好處包括&#xff1a; 1、自動化代碼生成 &#xff1a;通過定義規則&#xff0c;Cursor 可以根據你的開發需求自動生成符合規定的代碼模板&#xff0c…

pip install速度太慢的多種解決方案

目錄 問題描述為什么 pip 速度這么慢&#xff1f;解決方案1. 使用國內鏡像源2. 配置多個鏡像源3. 使用第三方工具4. 手動下載后本地安裝5. 優化網絡環境6. 更新 pip 版本 測試效果 問題描述 在使用 Python 進行開發時&#xff0c;我們經常需要使用 pip 來安裝第三方庫。然而&am…

Java阻塞隊列深度解析:高并發場景下的安全衛士

一、阻塞隊列的核心價值 在電商秒殺系統中&#xff0c;瞬時涌入的10萬請求如果直接沖擊數據庫&#xff0c;必然導致系統崩潰。阻塞隊列如同一個智能緩沖帶&#xff0c;通過流量削峰和異步解耦兩大核心能力&#xff0c;成為高并發系統的核心組件。 二、Java阻塞隊列實現類對比 …

基于RapidOCR與DeepSeek的智能表格轉換技術實踐

基于RapidOCR與DeepSeek的智能表格轉換技術實踐 一、技術背景與需求場景 在金融分析、數據報表處理等領域&#xff0c;存在大量圖片格式的表格數據需要結構化處理。本文介紹基于開源RapidOCR表格識別與DeepSeek大模型的智能轉換方案&#xff0c;實現以下典型場景&#xff1a; …