用 VC++ 2008 编写 Windows Service(系统服务)
用 VC++ 2008 編寫 Windows Service(系統(tǒng)服務(wù))
2008-03-30 08:08
現(xiàn)在許多 Windows Service 應(yīng)用都可以用 c# 很好的完成,不過畢竟是托管代碼,性能上不及非托管的 VC。網(wǎng)上能找到的 VC 寫系統(tǒng)服務(wù)的例子,多數(shù)都用的 VC6(ATL3.0)。ATL3.0 寫系統(tǒng)服務(wù)也很不錯,只是封裝的不很完善,還需要用戶寫不少代碼。ATL7.0 及后續(xù)帶的系統(tǒng)服務(wù)的模板有了更新,用起來簡單多了。本文以 ATL 9.0 為例。
文章只是流水般的寫了一下步驟。要再具體一些,恐怕就不是一篇文章能做到的了。市面上講 COM 的書很多,不妨買來看看。
下面就是用 Visual Studio 2008 中的 VC++ 2008 寫系統(tǒng)服務(wù)的詳細(xì)步驟(我用的 VC 是英文版的):
1. 新建項目。
1-1. 啟動 Visual Studio 2008。選擇 File -> New -> Project...。
1-2. 在 New Project 對話框中,選擇 Visual C++ 中的 ATL Project 模板,寫入項目名稱:ShowjiSvc,點 OK。
1-3. 在打開的 ATL Project Wizard - ShowjiSvc 中,點 Application Settings,選擇 Server type 為 Service(EXE),點 Finish。
2. 安裝、卸載服務(wù)。
2-1. 編譯項目。
2-2. 打開命令提示符,切換到編譯后的目錄,執(zhí)行以下命令安裝服務(wù):
ShowjiSvc /Service
2-3. 打開服務(wù)管理,能找到一個名為 ShowjiSvc 的服務(wù),啟動類型是 Manual。可以啟動服務(wù)、停止服務(wù)。
2-4. 停止服務(wù),然后用以下命令卸載服務(wù):
ShowjiSvc /UnRegServer
3. 修改服務(wù)的配置。
3-1. 修改服務(wù)名稱:
在 Resource View 中打開 String Table,修改 IDS_SERVICENAME 的 Caption 為服務(wù)的名稱:Showji Mobile Service。
3-2. 修改服務(wù)的描述:
打開 ShowjiSvc.cpp 文件,在 CShowjiSvcModule 的聲明中增加以下函數(shù)聲明:
HRESULT RegisterAppId(bool bService);
再增加此函數(shù)的定義:
HRESULT CShowjiSvcModule::RegisterAppId(bool bService = false ) throw ()
{
HRESULT hr = S_OK;
BOOL res = __super ::RegisterAppId(bService);
if (bService)
{
if (IsInstalled())
{
SC_HANDLE hSCM = ::OpenSCManagerW(NULL, NULL, SERVICE_CHANGE_CONFIG);
SC_HANDLE hService = NULL;
if (hSCM == NULL)
hr = AtlHresultFromLastError();
else
{
hService = ::OpenService(hSCM, m_szServiceName, SERVICE_CHANGE_CONFIG);
if (hService != NULL)
{
::ChangeServiceConfig(hService, SERVICE_NO_CHANGE,
SERVICE_AUTO_START, // 修改服務(wù)為自動啟動
NULL, NULL, NULL, NULL, NULL, NULL, NULL,
m_szServiceName); // 通過修改資源IDS_SERVICENAME 修改服務(wù)的顯示名字
SERVICE_DESCRIPTION Description;
TCHAR szDescription[1024];
ZeroMemory(szDescription, 1024);
ZeroMemory(&Description, sizeof (SERVICE_DESCRIPTION));
lstrcpy(szDescription, _T("www.showji.com 示例服務(wù),by yangwei@ligsoft.com" ));
Description.lpDescription = szDescription;
::ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &Description);
::CloseServiceHandle(hService);
}
else
hr = AtlHresultFromLastError();
::CloseServiceHandle(hSCM);
}
}
}
return hr;
}
3-3. 測試修改后的服務(wù)。
重新注冊服務(wù),在服務(wù)管理器中可以看到服務(wù)的新名稱和描述,并且啟動狀態(tài)已經(jīng)修改為 Automatic。
測試成功后,注銷服務(wù)。
4. 修改服務(wù)的進(jìn)程安全設(shè)置。
打開 ShowjiSvc.cpp,在 CShowjiSvcModule 的聲明中,找到 InitializeSecurity 函數(shù),修改如下:
HRESULT InitializeSecurity() throw ()
{
return CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL );
}
要根據(jù)自己的情況,做相關(guān)的安全性設(shè)置。如果沒有什么特殊的安全性要求,就按照上面的格式寫就行了。
如果沒有設(shè)置進(jìn)程安全性的代碼,那么 VC 客戶端創(chuàng)建對象的時候,會返回 E_ACCESSDENIED 的錯誤。
VB 客戶端的錯誤提示如下:
實時錯誤 '70': 拒絕的權(quán)限(Run-time error '70': Permission denied)。
5. 增加服務(wù)的初始化和釋放操作。
打開 ShowjiSvc.cpp,在 CShowjiSvcModule 的聲明中,增加以下聲明:
HRESULT PreMessageLoop(int nShowCmd);
HRESULT PostMessageLoop();
增加以上聲明的相關(guān)定義:
HRESULT CShowjiSvcModule::PreMessageLoop(int nShowCmd) throw ()
{
HRESULT hr = __super ::PreMessageLoop(nShowCmd);
if (SUCCEEDED(hr))
{
// Add any custom code to initialize your service
}
return hr;
}
?
HRESULT CShowjiSvcModule::PostMessageLoop() throw ()
{
HRESULT hr = __super ::PostMessageLoop();
if (SUCCEEDED(hr))
{
// Add any custom code to uninitialize your service
}
return hr;
}
在相關(guān)的描述位置增加自己的代碼即可。
6. 為服務(wù)增加一個叫做 MyMath 的示例組件。
6-1. 選中 ShowjiSvc 項目,點菜單 Project -> Add Class...,選擇 ATL 中的 ATL Simple Object,點 Add。
6-2. 在打開的 ATL Simple Object Wizard - ShowjiSvc 對話框的 Short name 中寫入組件名稱:MyMath。其它名稱會自動填好(當(dāng)然您也可以修改)。
6-3. 在 Option 中可以看到許多選項。如果您搞不懂這些,就保留默認(rèn)值吧(建議看一下 COM 的相關(guān)書籍)。
6-4. 打開 MyMath.rgs,為組件增加服務(wù)程序的 ID(代碼中的紅色粗體部分):
HKCR
{
ShowjiSvc.MyMath.1 = s 'MyMath Class'
{
CLSID = s '{37F47E87-7D33-43CD-B591-DA01023F90BC}'
}
ShowjiSvc.MyMath = s 'MyMath Class'
{
CLSID = s '{37F47E87-7D33-43CD-B591-DA01023F90BC}'
CurVer = s 'ShowjiSvc.MyMath.1'
}
NoRemove CLSID
{
ForceRemove {37F47E87-7D33-43CD-B591-DA01023F90BC} = s 'MyMath Class'
{
ProgID = s 'ShowjiSvc.MyMath.1'
VersionIndependentProgID = s 'ShowjiSvc.MyMath'
ForceRemove 'Programmable'
LocalServer32 = s '%MODULE%'
val AppID = s '%APPID%'
'TypeLib' = s '{55E58774-E86F-4482-A521-38AE8C85FD1D}'
}
}
}
AppID 必須設(shè)置,否則客戶端創(chuàng)建對象的時候會超時并報錯誤:80080005 server execution failed。
并且,系統(tǒng)日志中會出現(xiàn)一個錯誤:The server {uuid} did not register with DCOM within the required timeout.
VB 客戶端的錯誤提示如下:
實時錯誤 '429': ActiveX 部件不能創(chuàng)建對象(Run-time error '429': ActiveX component can't create object)。
7. 為 MyMath 組件增加一個方法。
7-1. 在 Class View 中,右擊 IMyMath,選擇 Add -> Add Method...。
7-2. 在打開的 Add Method Wizard - ShowjiSvc 對話框中,輸入 Method name: Sum;
Parameter type 選擇 LONG,Parameter name 寫 a,Parameter attributes 選擇 in,點一下 Add;
Parameter type 選擇 LONG,Parameter name 寫 b,Parameter attributes 選擇 in,點一下 Add;
Parameter type 選擇 LONG*,Parameter name 寫 s,Parameter attributes 選擇 retval,點一下 Add;
點 Finish 添加這個方法。
7-3. 打開 MyMath.cpp 文件,找到 Sum 方法,修改如下:
STDMETHODIMP CMyMath::Sum(LONG a, LONG b, LONG* s)
{
*s = a + b;
return S_OK;
}
8. 編譯、注冊、啟動服務(wù)。
8-1. 編譯代碼。
8-2. 注冊服務(wù),執(zhí)行以下命令行代碼:
ShowjiSvc /Service
8-3. 啟動服務(wù),執(zhí)行以下命令行代碼:
net start "Showji Mobile Service"
當(dāng)然,也可以在服務(wù)管理器中啟動服務(wù)。
相對應(yīng)的停止服務(wù)的命令是:
net stop "Showji Mobile Service"
9. 客戶端訪問測試(用 VB6 舉例)。
9-1. 打開 Visual Basic 6.0。
9-2. 新建“標(biāo)準(zhǔn) EXE”工程。
9-3. 點菜單:工程 -> 引用...,找到 ShowjiSvc 1.0 Type Library 并勾選,點確定。
9-4. 雙擊 Form1 窗體,進(jìn)入代碼模式,輸入以下代碼:
Private Sub Form_Load()
Dim math As ShowjiSvcLib.MyMath
Set math = New ShowjiSvcLib.MyMath
MsgBox math.Sum(10, 19)
Set math = Nothing
End Sub
執(zhí)行后可以看到,VB 正常初始化了系統(tǒng)服務(wù)中的 COM 對象,并調(diào)用了其中的方法。
10. 部署。
要將項目部署到其它電腦,需要安裝 Microsoft Visual C++ 2008 Redistributable Package,否則會提示錯誤:系統(tǒng)無法執(zhí)行指定的程序(The system cannot execute the specified program.)。
Microsoft Visual C++ 2008 Redistributable Package 下載地址:
x86 版:http://www.microsoft.com/downloads/details.aspx?FamilyID=9b2da534-3e03-4391-8a4d-074b9f2bc1bf
x64 版:http://www.microsoft.com/downloads/details.aspx?FamilyID=bd2a6171-e2d6-4230-b809-9a8d7548c1b6
11. 相關(guān)代碼下載:
http://cid-95d89389d5c6e944.skydrive.live.com/self.aspx/Src/VC2008Svc.zip (22k)
?
本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/ljz888666555/archive/2009/11/06/4777331.aspx
總結(jié)
以上是生活随笔為你收集整理的用 VC++ 2008 编写 Windows Service(系统服务)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sql server 2008 远程连接
- 下一篇: VS2005 ATL WINDOWS服务