Windows服务操作技巧2016-01-20伴随着研究Windows服务,逐渐掌握了一些小技巧,现在与大家分享一下。将Windows服务转变为控制台程序由于默认的Windows服务程序,编译后为Win32的窗口程序。我们在程序启动或运行过程中,如果想看到一些调试信息,那么就只能通过DebugView或者输出到日志的方式了。因为如果我们通过printf或者std::cout输出调试信息的话,Win32窗口程序是无法显示的。此时,我们是多么怀念我们的经典的控制台程序啊,它可以很方便的将我们的调试信息输出出来,简直是太方便了。既然如此,那我们就让它一秒钟变格格吧,额,应该是一秒钟变控制台。下面分享一下我的实现代码
Collapse#ifdef _DEBUG//Debug版本,直接输出到控制台#define OUT(s) printf_s(s); #define OUT_LN(s) printf_s(s##"
"); #else//非Debug版本,则输出到调试器,一般使用DebugView#define OUT(s) OutputDebugString(s);#define OUT_LN(s) OutputDebugString(s);#endifclass CServicesModule : public ATL::CAtlServiceModuleT< CServicesModule, IDS_SERVICENAME >{public :DECLARE_LIBID(LIBID_ServicesLib)DECLARE_REGISTRY_APPID_RESOURCEID(IDR_SERVICES, "{0794CF96-5CC5-432E-8C1D-52B980ACBE0F}")HRESULT InitializeSecurity() throw(){return S_OK;}//服务启动HRESULT Load();//服务停止HRESULT UnLoad();HRESULT Run(_In_ int nShowCmd = SW_HIDE) throw(){HRESULT hr = S_OK;OUT_LN("准备启动服务");hr = Load();if(hr){OUT_LN("启动服务失败");return hr;}OUT_LN("Services服务已启动");hr = ATL::CAtlServiceModuleT< CServicesModule, IDS_SERVICENAME >::Run(nShowCmd);hr = UnLoad();OUT_LN("Services服务正常退出");return hr;}};CServicesModule _AtlModule;//#ifndef _DEBUG//非Debug版本,编译为Win32程序extern "C" int WINAPI _tWinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpCmdLine*/, int nShowCmd){return _AtlModule.WinMain(nShowCmd);}#else//Debug版本,编译为控制台程序int _tmain(int argc, _TCHAR* argv[]){return _AtlModule.WinMain(SW_SHOW);}#endifHRESULT CServicesModule::Load(){OUT_LN("服务正在启动");return 0;}HRESULT CServicesModule::UnLoad(){OUT_LN("服务正在停止");return 0;}
通过_DEBUG宏来区分是否编译成控制台程序。当指定编译Debug版本时,可以将程序编译为控制台程序,通过RegServer注册服务,然后直接运行服务exe程序,这样通过printf输出的信息,就可以在控制台上显示了,如下图。当指定编译Release版本时,将程序编译为Win32程序,通过Service注册服务,通过服务管理器管理服务的运行和停止。