伴随着研究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##"\r\n"); #else //非Debug版本,则输出到调试器,一般使用DebugView #define OUT(s) OutputDebugString(s); #define OUT_LN(s) OutputDebugString(s); #endif class 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); } #endif HRESULT CServicesModule::Load() { OUT_LN("服务正在启动"); return 0; } HRESULT CServicesModule::UnLoad() { OUT_LN("服务正在停止"); return 0; }
通过_DEBUG宏来区分是否编译成控制台程序。
当指定编译Debug版本时,可以将程序编译为控制台程序,通过RegServer注册服务,然后直接运行服务exe程序,这样通过printf输出的信息,就可以在控制台上显示了,如下图。
当指定编译Release版本时,将程序编译为Win32程序,通过Service注册服务,通过服务管理器管理服务的运行和停止。
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索控制台
, 程序
, debugview
, return
, hresult e_fail
, 服务
, 输出
, hresult
, Debug技巧
停止输出
windows10操作技巧、windows操作技巧、windows10操作小技巧、windows7操作技巧、windows10使用技巧,以便于您获取更多的相关知识。