將基於MFC的對話方塊應用程式修改為服務程式

2021-05-06 09:44:09 字數 4397 閱讀 9400

windows(nt/2000)下有很多服務程式(它們在系統登入前執行),它們一般都沒有介面,我們可以在服務管理器(執行services.msc)中啟動和關閉它們。下面我試著修改乙個有介面的mfc對話方塊程式,使它成為乙個服務程式。網上提到了一種方法就是,從建立乙個com服務程式入手,然後將乙個mfc專案改造成服務程式,最後讓這一程式在啟動時可以顯示圖形介面。這種方法的優點就是,程式嚮導已經幫我們寫好了服務程式的主要**,我們的任務就是把它們移植到mfc程式中(這個方法很不錯!)。我的方法和這種方法思想基本一致,但也不完全一樣。我是直接將有些寫在cui服務程式中的**移植過來。主要思想就是把主服務函式等定義為全域性函式,這樣在主對話方塊類中就可以訪問它們了。

此程式需要注意的地方:

一次只能安裝乙個服務,如果已安裝過乙個服務,先將其解除安裝再安裝其他服務,設定其他應用程式時,在scm啟動後,因沒有相應啟動請求會被kill掉。本來以為任何程式都可以被設定為服務程式,後來實驗發現,一般的應用程式被設定為服務程式後,由於它不能夠與scm進行通訊,所以scm無法將其啟動。錯誤提示如下:(下面wcdj是我的服務名字)

本地計算機無法啟動wcdj服務

錯誤1053:服務沒有及時響應啟動或控制請求

這個服務程式的主要流程如下:

service_table_entry dispatchtable=,}; 

if (!startservicectrldispatcher(dispatchtable))

else if (nresponse == idcancel)}

否則程式會執行**函式:

void winapi servicemain(dword argc, lptstr *argv)

else if (nresponse == idcancel)

...} }

具體的細節看下面的步驟,主要步驟如下:

(1)首先生成乙個基於對話方塊的應用程式框架,假設我的工程名稱為test。

(2)在test.cpp中新增幾個全域性變數和幾個全域性函式。

//設定兩個全域性變數

service_status m_servicestatus;

service_status_handle m_servicestatushandle;

//新增幾個全域性函式

////函式宣告

void winapi servicemain(dword argc, lptstr *argv);

void winapi servicectrlhandler(dword opcode);

bool installservice(cstring &strpath);

bool deleteservice(); //

//函式定義

void winapi servicemain(dword argc, lptstr *argv)

m_servicestatus.dwcurrentstate       = service_running;

m_servicestatus.dwcheckpoint         = 0;

m_servicestatus.dwwaithint           = 0; 

if (!setservicestatus (m_servicestatushandle, &m_servicestatus))

//brunning=true;

//while(brunning)

while(1)

else if (nresponse == idcancel)

exit(0);//後面退出不了,只能強行退出

}#ifdef _temp_delete//使用下面**,只能關閉對話方塊不能關閉程式

//關閉對話方塊用,傳遞訊息

msg msg;

while (getmessage(&msg, 0, 0, 0))

dispatchmessage(&msg);

}#endif}

return; }

void winapi servicectrlhandler(dword opcode)

return; }

bool installservice(cstring &strpath)//無法建立其他應用程式為服務,因為它們不能響應啟動請求

;handle schscmanager,schservice;

//   getcurrentdirectory(1024,strdir);

//   strcat(strdir,"

//test.exe

");

schscmanager = openscmanager(null,null,sc_manager_all_access); 

if (schscmanager == null)

return false;

//lpctstr lpszbinarypathname=strdir;

lpctstr lpszbinarypathname;

if (strpath=="")

else

schservice = createservice(schscmanager,"service1","wcdj",// service name to display

service_all_access,        // desired access

service_win32_own_process|service_interactive_process, // service type

//service_demand_start,      // start type

service_auto_start,        //系統啟動時自動啟動

service_error_normal,      // error control type

lpszbinarypathname,        // service's binary

null,                      // no load ordering group

null,                      // no tag identifier

null,                      // no dependencies

null,                      // localsystem account

null);                     // no password

if (schservice == null)

return false; 

closeservicehandle(schservice);

return true;}

bool deleteservice()

//在別處顯示對話方塊

//  ctestdlg dlg;

//  m_pmainwnd = &dlg;

//  int nresponse = dlg.domodal();

//  if (nresponse == idok)

//  

//  else if (nresponse == idcancel)

//  

//啟動服務(兩種方式:雙擊執行和scm啟動,執行流程如剛開始提到的那樣),對話方塊在下面顯示

service_table_entry dispatchtable=,}; 

//startservicectrldispatcher(dispatchtable);

if (!startservicectrldispatcher(dispatchtable))

else if (nresponse == idcancel)}

再在上面宣告全域性函式:

extern void winapi servicemain(dword argc, lptstr *argv);

void ctestdlg::onbutton1() //安裝服務

else}

void ctestdlg::onbutton2() //刪除服務

else}

void ctestdlg::onbutton3() //開啟服務管理器

void ctestdlg::onbutton4() //顯示啟動項

最後別忘了在開頭宣告全域性函式:

extern void winapi servicectrlhandler(dword opcode);

extern bool installservice(cstring &strpath);

extern bool deleteservice();

這個服務程式還不是很完善,應該再新增一些判斷和logevent記錄資訊,但是主要的服務程式框架應該都包含了。

最後,希望讀到此篇文章的朋友提出自己的意見。 :)

MFC基於對話方塊程式

001 020 else if nresponse idcancel 如果對話方塊是用取消來關閉的,則 021 025 026 由於對話方塊已關閉,所以將返回 false 以便退出應用程式,027 而不是啟動應用程式的訊息幫浦。028 return false 029 因為initinstance ...

隱藏基於對話方塊的MFC應用程式視窗的方法

很多人可能會將視窗建立出來,然後用乙個 showwindow sw hide 的方法去隱藏視窗,當然這是可以做到隱藏的功能,但是有一點不足的地方就是視窗在隱藏之前會有一下短瞬的閃爍,而以下這種方法可以解決這種問題 c dlg dlg m pmainwnd dlg int nresponse dlg....

MFC 對話方塊程式 模式對話方塊與非模式對話方塊

一 根據主視窗型別,mfc軟體工程可以分為以下幾種架構模型 例如 記事本和畫筆等。2 mdi multiple document inte ce 多文件介面,乙個主框架視窗下可以同時編輯多份文件。例如 vc 6.0,photoshop等軟體。3 基於對話方塊的軟體模型 主視窗是通過資源管理器,在對話...