VC實現系統熱鍵激活後台服務程序

摘要: 本文給出了一種通過設置系統熱鍵來呼出在系統後台隱藏運行的服務程序的一種方法,通過這種方法,可以實現後台服務程序在必要的時候同用戶的交互設置。

引言

通常情況下,用于後台監控的服務程序(Service)是沒有界面的,甚至也沒有提供任務欄圖標,因此絕大多數情況下服務程序是無法同用戶進行交互的。但是在實際應用中,這些服務程序雖然絕大多數時間是在後台運行,但是在某些必要的情況下還是需要用戶的幹預並同用戶進行一些必要的交互操作。但是由于服務程序沒有提供任何可供交互操作之用的界面,因此如何將其從後台激活(即呼出)成爲解決此問題的一個要害。本文下面就給出一種通過設置系統熱鍵的方法來激活運行于後台的服務程序。

設計思路

盡管從理論上可以有許多方法來激活後台運行的服務程序,比如可以通過尋找服務程序的窗口標題名而得到其窗口指針,然後再向此窗口發送消息使其出現到前台;也可以通過系統快照對當前系統進程進行枚舉,然後再將其激活到前台。但是以上這些方法都需要另外編寫應用程序,對後台服務程序的激活實際是再這些應用程序中進行的,這樣的處理方式顯然十分不便,最好的方法是對程序的激活和隱藏處理均在服務程序內部完成。因此可以考慮接收系統發出的消息,假如通過設置全局鈎子對設置事件進行攔截捕捉,顯然是相當煩瑣的。在此考慮使用系統熱鍵來激活後台服務程序,其實現過程非常簡單,只需先向操作系統添加一個全局原子(Atom),然後再向操作系統登記一個熱鍵,當程序在後台運行期間一旦有此熱鍵按下,操作系統將會抛出系統消息WM_HOTKEY,所以服務程序只需在 WM_HOTKEY消息響應函數中添加相應代碼即可實現服務程序的後台激活。

系統熱鍵的注冊

根據前面的介紹,不難寫出爲後台服務程序添加對系統熱鍵響應的功能代碼。首先通過函數GlobalFindAtom()查詢本服務程序所對應的全局原子是否已存在于全局原子表中,假如發現,則說明系統中已經存在有此服務,程序退出。假如沒有發現,則通過GlobalAddAtom()函數向全局原子表添加一個字串,並獲取得到一個唯一標識此字串的原子。以上兩函數原型分別爲:

以下是引用片段:

ATOM GlobalFindAtom(LPCTSTR lpString);

ATOM GlobalAddAtom(LPCTSTR lpString);

其中,輸入參數爲一個描述原子的字符串,假如GlobalFindAtom()從全局原子表中找到了指定的字串,那麽將返回此字串對應的原子,否則返回0。GlobalAddAtom()假如創建成功,將返回一個新創建的原子。

接下來,爲了能在程序運行期間捕捉到系統熱鍵,需要通過RegisterHotKey()定義一個系統範圍的熱鍵。該函數原形如下:

以下是引用片段:

BOOL RegisterHotKey(HWND hWnd, // 接收熱鍵響應的窗口句柄

int id, // 熱鍵的標識

UINT fsModifiers, // 控制鍵標志

UINT vk // 虛擬鍵值

);

其中,熱鍵標識id必須是一個範圍在0xC000到0xFFFF之間的全局唯一的值,爲了避免可能引起的熱鍵沖突,通常把GlobalAddAtom ()返回的原子作爲參數傳入,而且GlobalAddAtom()返回值的範圍同id參數的答應範圍是完全一致的。參數fsModifiers定義了同虛擬鍵值vk同時按下而産生出系統熱鍵消息WM_HOTKEY的控制鍵組合,如MOD_ALT、MOD_CONTROL、MOD_SHIFT和 MOD_WIN等。在本例中將要設定的系統熱鍵爲Alt+Ctrl+R,因此,參數fsModifiers和vk分別設置爲MOD_ALT MOD_CONTROL和VK_R。有關系統熱鍵的注冊實現方法可以整理如下:

以下是引用片段:

// 獲取當前窗口句柄

HWND handle = GetSafeHwnd();

// 尋找HotKey對應的原子是否存在于原子列表

if(GlobalFindAtom("Hotkey") == 0)

{

// 假如沒有存在于原子列表,則創建一個原子

id = GlobalAddAtom("Hotkey");

//注冊全局熱鍵Ctrl + Alt + R

RegisterHotKey(handle, id, CONTROL + ALT, R);

}

else // 假如HotKey已經存在于原子列表,則終止程序運行

PostQuitMessage(0);

服務程序的隱藏與激活

服務程序除了被激活後同用戶的交互,絕大部分時間都是在後台隱藏運行的,不僅界面是不可視的,而且在任務列表中也不應當出現。關于界面的隱藏比較簡單,可以通過向ShowWindow()函數設置SW_HIDE參數來實現,而在任務列表中的隱身則一般的做法是通過調用系統內核Kernel32.DLL的RegisterServiceProcess()函數將其設置成爲一個服務進程,這樣,在任務列表中也實現了隱身。但是RegisterServiceProcess()函數並非一個標准的API函數,使用起來有點煩瑣。首先要通過 GetModuleHandle()函數得到Kernel32.DLL模塊的句柄,並由此通過GetProcAddress()函數進一步得出 RegisterServiceProcess()函數在Kernel32.DLL中的入口地址,最後才能使用 RegisterServiceProcess()函數。該函數原型聲明如下:

以下是引用片段:

DWORD RegisterServiceProcess(DWORD dwProcessId,DWORD dwType);

其第一個參數指定了將要注冊爲服務進程的進程標識,參數dwType指定是去注冊一個服務進程(爲1時)還是去卸載一個服務進程(爲0時)。其具體服務注冊過程如下:

typedef DWORD (WINAPI *RSP)(DWORD dwProcessId,DWORD dwType);

// 獲取Kernel32.DLL模塊句柄

HMODULE m_hKernel = ::GetModuleHandle("Kernel32.DLL");

// 得到RegisterServiceProcess()函數入口地址

RSP m_rsp = (RSP)::GetProcAddress(m_hKernel, "RegisterServiceProcess");

// 注冊當前進程爲服務進程

m_rsp(::GetCurrentProcessId(),1);

在服務程序後台運行期間,一旦有系統熱鍵Alt+Ctrl+R按下,將發出系統熱鍵消息WM_HOTKEY,該消息的消息響應函數不能通過 ClassWizard來添加,而只能手工完成消息映射。在消息響應函數中,通過對消息參數 wParam的判定可以確定出是否是本服務程序所設定的系統熱鍵,假如是,通過ShowWindow(SW_SHOW)將程序界面顯示出來,以進行同用戶的交互操作:

以下是引用片段:

void CServiceDlg::OnHotKey(WPARAM wParam, LPARAM lParam)

{

// 判定是否是本服務程序設置的系統熱鍵

if (wParam == id)

{

……

// 在此發送WM_PAINT消息,在OnPain()中通過

// ShowWindow(SW_SHOW)將界面設置爲可視

PostMessage(WM_PAINT, 0, 0);

}

}

系統熱鍵的卸載

由于前面將系統熱鍵、全局原子等都注冊到系統,因此必須在服務程序退出之前將其卸載,否則將導致下次注冊時的失敗。函數UnregisterHotKey()負責完成對系統熱鍵的釋放,GlobalDeleteAtom()將全局原子從全局原子列表刪除。

小結

通過本文所述方法爲後台運行的系統服務程序添加此熱鍵呼出功能可以真正實現程序的後台隱蔽運行、熱鍵激活,非常有利于治理員和用戶的治理與使用。本文所述程序在windows 2000 Professional下,由Microsoft Visual C++ 6.0編譯通過。

如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢?
以下是代碼:<html><br /><head><br /><script language='<a href="http://www.chinaitpower.com/Dev/Programme/Java/index.html" target="_blank">java</a>script'><...查看完整版>>如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢?
 
如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢?
如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢? 如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢? 以下是代碼:<html><head><script language='javascript'><!--function issueCommand(x){...查看完整版>>如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢?
 
如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢?
以下是代碼:<html><head><script language='javascript'><!--function issueCommand(x){ if (document.layers) { if (x.which==99||x.which==67) window.close(); ...查看完整版>>如何讓程序檢測你的按鍵,實現WEB熱鍵功能呢?
 
用VC實現支持多語言的程序
用VC實現支持多語言的程序 作者:新奧特視頻公司 最近要做個程序要求有中文和英文兩個版本,因此要把應用程序的資源文件COPY一份英文的。 方法一:在資源中用InsertCopy COPY一...查看完整版>>用VC實現支持多語言的程序
 
java程序破解天意商務系統後台帳號
  Java程序破解天意商務系統後台帳號/** 文件名 : AttackTY.java 描述 : 針對天意商務系統的java程序,破解後台治理員用戶名和密碼,利用SQL Injection漏洞 注入地址爲本網動態的某個新聞,這裏以www.ejl.c...查看完整版>>java程序破解天意商務系統後台帳號
 
java程序破解天意商務系統後台帳號
java程序破解天意商務系統後台帳號/** 文件名 : AttackTY.java 描述 : 針對天意商務系統的java程序,破解後台管理員用戶名和密碼,利用SQL Injection漏洞 注入地址爲本網動態的某個新聞,這裏以爲例 作者: 慈...查看完整版>>java程序破解天意商務系統後台帳號
 
沈陽中興百貨ERP系統後台服務器案例
全國零售行業的龍頭企業沈陽中興百貨緊跟國內信息化建設步伐,在推進信息化建設方面是國內零售行業的代表。爲了使企業業務穩定發展並應對激烈的市場競爭,沈陽中興百貨采用IBM eServer i系列720服務器和長益科技商友...查看完整版>>沈陽中興百貨ERP系統後台服務器案例
 
服務器秘訣:Metabase還原程序可能需要系統狀態備份
  當您需要重新安裝運行 Microsoft Windows 2000 的服務器時,例如在嚴重的硬件毀損之後,或當您要更新硬件及安裝 Exchange 2000 到相同名稱的新服務器之前,您應該也要備份 Metabase。備份 Metabase 有幾個不同的...查看完整版>>服務器秘訣:Metabase還原程序可能需要系統狀態備份
 
實現熱鍵激活後台進程
實現熱鍵激活後台進程 (湖南 張波雲) 在DOS下編寫常駐內存的應用(TSR)程序時,一般設置了熱鍵激活方式,DOS用戶對此非常熟悉。在Windows 9X環境下,有的時侯前台運行程序隱藏了Windows的任務欄,使用戶不能切...查看完整版>>實現熱鍵激活後台進程
 
 
回到王朝網路首頁