1. 程式人生 > >如何在網頁中開啟一個本地桌面程式

如何在網頁中開啟一個本地桌面程式

通過網頁連結開啟本地本地程式,想到最多的方法就是通過activex控制元件,但這裡介紹一個通過註冊新協議來開啟本地程式的方法。

參考網上的對QQ的分析,原理很簡單:註冊新協議並且關聯該協議的執行程式,這樣當點選該協議的URL連結時就會啟動相應的執行程式。

具體原理方法可以參考以下內容~

複製程式碼
 如果你電腦中裝有QQ,在IE位址列輸入:“tencent://Message/?menu=yes&exe=&uin=13231462”然後[回車],立即可以與我的QQ建立臨時會話,
Skype也有類似的功能。到底是如何實現的呢?看MSDN中有這麼一段話:

  The IURLSearchHook interface
is used by the browser to translate the address of an unknown URL protocol. When attempting to browse to a URL address that does not contain a protocol, the browser will first attempt to determine the correct protocol from the address. If this is not successful, the browser will create URL Search Hook objects and call each object
's Translate method until the address is translated or all of the hooks have been queried.
  IURLSearchHook介面被瀏覽器用來轉換一個未知的URL協議地址。當瀏覽器企圖去開啟一個未知協議的URL地址時,瀏覽器首先嚐試從這個地址得到當前的協議,如果不成功,瀏覽器將建立在系統中註冊的URL Search Hook物件並呼叫每一個物件的Translate方法,直到地址被轉換或所有的URL Search Hook都嘗試過。
  也就是說,我們可以註冊一種目前不存在的協議(類似HTTP),當瀏覽器遇到新的協議時會自動呼叫Translate方法來翻譯我們的協議,甚至啟用我們自己的程式。

以下原始碼將實現註冊一個新的自定義的Web協議:

//
// 註冊自定義的Web協議
// return : ------------------------------------------------------------------------
// 0 - 失敗
// 1 - 成功
// 2 - 已經存在
//
int RegWebProtocol ( LPCTSTR lpszProtocolName, LPCTSTR lpszAssociatedApp, int nIconIndex/*=0*/ )
{
if ( !lpszProtocolName ||
lstrlen(lpszProtocolName) < 1 ||
!lpszAssociatedApp ||
lstrlen(lpszAssociatedApp) < 1 )
return 0;

CString csSubKey;
DWORD dwBufSize = 0;

// 該協議已經存在 HKEY hKey = NULL;
if ( RegOpenKeyEx ( HKEY_CLASSES_ROOT,
lpszProtocolName,
0,
KEY_ALL_ACCESS,
&hKey ) == ERROR_SUCCESS )
{
return 2;
}
else hKey = NULL;

// 建立協議子鍵 if ( !CreateRegisterSubKey ( HKEY_CLASSES_ROOT, lpszProtocolName ) )
return 0;

// 設定協議描述字串 CString csProtocolDesc; csProtocolDesc.Format ( _T("%sProtocol"), lpszProtocolName );
dwBufSize = csProtocolDesc.GetLength();
if ( !WriteRegister ( HKEY_CLASSES_ROOT, lpszProtocolName,
_T(""), REG_EXPAND_SZ, (PUCHAR)csProtocolDesc.GetBuffer(0),&dwBufSize) )
return 0;
CString csAppFile; csAppFile.Format ( _T("%s"), lpszAssociatedApp );
dwBufSize = csAppFile.GetLength();
if ( !WriteRegister ( HKEY_CLASSES_ROOT, lpszProtocolName,
_T("URL Protocol"), REG_EXPAND_SZ, (PUCHAR)csAppFile.GetBuffer(0),&dwBufSize) )
return 0;

// DefaultIcon 子鍵 csSubKey.Format ( _T("%s\\DefaultIcon"), lpszProtocolName );
if ( !CreateRegisterSubKey ( HKEY_CLASSES_ROOT, csSubKey ) )
return 0;
CString csIconParameter; csIconParameter.Format ( _T("%s,%d"), lpszAssociatedApp, nIconIndex );
dwBufSize = csIconParameter.GetLength();
if ( !WriteRegister ( HKEY_CLASSES_ROOT, csSubKey,
_T(""), REG_EXPAND_SZ, (PUCHAR)csIconParameter.GetBuffer(0),&dwBufSize) )
return 0;

// shell\open\command 子鍵 csSubKey.Format ( _T("%s\\shell\\open\\command"), lpszProtocolName );
if ( !CreateRegisterSubKey ( HKEY_CLASSES_ROOT, csSubKey ) )
return 0;
CString csCommand; csCommand.Format ( _T("\"%s\" \"%%1\""), lpszAssociatedApp );
dwBufSize = csCommand.GetLength();
if ( !WriteRegister ( HKEY_CLASSES_ROOT, csSubKey,
_T(""), REG_EXPAND_SZ, (PUCHAR)csCommand.GetBuffer(0),&dwBufSize) )
return 0;

return 1;
}

以下原始碼將刪除自定義的Web協議:
//// 解除安裝自定義的Web協議
//
BOOL UnRegWebProtocol ( LPCTSTR lpszProtocolName )
{
if ( !lpszProtocolName || lstrlen(lpszProtocolName) < 1 )
return FALSE;

return RegDeleteAllSubKey ( HKEY_CLASSES_ROOT, lpszProtocolName );
}

windows下注冊新協議當然就是寫登錄檔了,註冊內容如下:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\RunLocal]
@="RunLocal Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\RunLocal\DefaultIcon]
@="c:\\windows\\RunLocal.exe,1"

[HKEY_CLASSES_ROOT\RunLocal\shell]
@=""

[HKEY_CLASSES_ROOT\RunLocal\shell\open]
@=""

[HKEY_CLASSES_ROOT\RunLocal\shell\open\command]
@="\"c:\\windows\\RunLocal.exe\" \"%1\""

這裡我貼個Nsis指令碼,可以通過安裝程式註冊新協議。新協議為“RunLocal://######”,該指令碼會在$WINDIR目錄下安裝一個協議處理程式runlocal.exe,功能很簡單,就是執行“cmd.exe”。想實現複雜的功能只要編寫這個協議處理程式就可以了(提示:連結地址會當作引數傳給處理程式)。


Name "Runlocal install"
OutFile "install.exe"

Section "ThisNameIsIgnoredSoWhyBother?"
SetOutPath "$WINDIR"
SetOverwrite on
File "RunLocal.exe"

WriteRegStr HKCR "RunLocal" "" "RunLocal Protocol"
WriteRegStr HKCR "RunLocal" "URL Protocol" ""

WriteRegStr HKCR "RunLocal\DefaultIcon" "" '"$WINDIR\RunLocal.exe,1"'
WriteRegStr HKCR "RunLocal\shell" "" ""
WriteRegStr HKCR "RunLocal\shell\open" "" ""
WriteRegStr HKCR "RunLocal\shell\open\command" "" '"$WINDIR\RunLocal.exe" "%1"'
SectionEnd

; eof