关于用VC写服务程序的一点小问题

Grim_Rapier 2013-11-18 05:38:24
请看以下程序:只列出主要函数的实现
#include <stdio.h>
#include <Windows.h>
#include <tchar.h>

TCHAR szServiceName[] = _T("MyTestService");
DWORD dwThreadID;
HANDLE hEvent = INVALID_HANDLE_VALUE;
SERVICE_STATUS status;
SERVICE_STATUS_HANDLE hServiceStatus;
void Init();
BOOL IsServiceInstalled();//TestService.exe /install
//TestService.exe /uninstall
BOOL InstallService();// Install service:
BOOL UninstallService();// Uninstall service:
BOOL ServiceCtrlStart();// Start service:
BOOL ServiceCtrlStop();// Stop service:
void WINAPI ServiceMain();
void WINAPI ServiceStrl(DWORD dwOpcode);
void LogEvent(LPCTSTR pszFormat, ...);
int main( int argc, char* argv[] )
{
Init();
dwThreadID = ::GetCurrentThreadId();
SERVICE_TABLE_ENTRY st[] =
{
{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
LPSTR lpCmdLine = argv[1];
if ( argc == 2 )
{
BOOL bRet;
if (stricmp(lpCmdLine, "/install") == 0)
{
bRet = InstallService();
if ( bRet == TRUE )
{
printf( "Install service %s success", szServiceName );
}else
{
printf( "Install service %s failed", szServiceName );
}
}
else if (stricmp(lpCmdLine, "/uninstall") == 0)
{
bRet = UninstallService();
if ( bRet == TRUE )
{
printf( "Uninstall service %s success", szServiceName );
}else
{
printf( "Uninstall service %s failed", szServiceName );
}
}else if (stricmp(lpCmdLine, "/start") == 0)
{
bRet = ServiceCtrlStart();
if ( bRet == TRUE )
{
printf( "Start service %s success", szServiceName );
}else
{
printf( "Start service %s failed", szServiceName );
}
}else if (stricmp(lpCmdLine, "/stop") == 0)
{
bRet = ServiceCtrlStop();
if ( bRet == TRUE )
{
printf( "Stop service %s success", szServiceName );
}else
{
printf( "Stop service %s failed", szServiceName );
}
}
else
{
if (!::StartServiceCtrlDispatcher(st))
{
LogEvent(_T("Register Service Main Function Error!"));
}
}
}else
{
if (!::StartServiceCtrlDispatcher(st))
{
LogEvent(_T("Register Service Main Function Error!"));
}
}
return 0;
}
//服务主线程函数,即用户选择开启服务时调用的函数
void WINAPI ServiceMain()
{
// Register the control request handler
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
LogEvent(_T("ServiceMain"));
//注册服务控制
hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);
if (hServiceStatus == NULL)
{
LogEvent(_T("Handler not installed"));
return;
}
SetServiceStatus(hServiceStatus, &status);
//如下代码可以为启动服务前的准备工作
hEvent = ::CreateEvent( NULL, TRUE, FALSE, NULL );
if ( hEvent == NULL )
{
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
LogEvent(_T("Failure to start service"));
return;
}
//
//更改服务状态为启动
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hServiceStatus, &status);
//等待用户选择停止服务,
//当然你也可以把你的服务代码用线程来执行,
//此时这里只需等待线程结束既可。
while ( WaitForSingleObject( hEvent, 1000 ) != WAIT_OBJECT_0 )
{
//模拟服务的运行,应用时将主要任务放于此即可
LogEvent(_T("Service runing..."));
::ShellExecute(NULL,"open","notepad.exe",NULL,NULL,SW_SHOW);//测试程序
}
//
//停止服务
status.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hServiceStatus, &status);
LogEvent(_T("Service stopped"));
}
为测试程序,我在servicemain()中写了::ShellExecute(NULL,"open","notepad.exe",NULL,NULL,SW_SHOW);
所以服务启动后会打开记事本,但是安装,启动服务都成功后,并未执行记事本程序,即没有执行servicemain()函数,原因何在?
...全文
285 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
版主大哥 2013-11-20
  • 打赏
  • 举报
回复
打日志是跟踪好方法... 提供一个好方法: 在void WINAPI ServiceMain()中用一个sleep(5000)或者更久,在sleep后加断点,运行服务,用debug attach 服务进程,等着到断点,实时调试看看
oyljerry 2013-11-20
  • 打赏
  • 举报
回复
引用 3 楼 pq159753159 的回复:
[quote=引用 2 楼 oyljerry 的回复:] 写Log吧,或者查看任务管理器,服务的exe是否启动 服务启动的记事本在不同session,你看不到的
查看services.msc服务已经启动,作为测验,在servicemain()放个消息框但并未显示,意味着程序好像没有走到servicemain()[/quote] 消息框一样的看不见,你还是打印Log来看代码走到哪了
Grim_Rapier 2013-11-19
  • 打赏
  • 举报
回复
引用 2 楼 oyljerry 的回复:
写Log吧,或者查看任务管理器,服务的exe是否启动 服务启动的记事本在不同session,你看不到的
查看services.msc服务已经启动,作为测验,在servicemain()放个消息框但并未显示,意味着程序好像没有走到servicemain()
oyljerry 2013-11-18
  • 打赏
  • 举报
回复
写Log吧,或者查看任务管理器,服务的exe是否启动 服务启动的记事本在不同session,你看不到的
zgl7903 2013-11-18
  • 打赏
  • 举报
回复
看看日志是否运行到了这里? 看ShellExecute返回什么值?
内容概要:本文针对无刷直流电机驱动的电子机械制动(EMB)执行器,建立了考虑Stribeck摩擦特性的非线性耦合动力学模型,并在Simulink环境中完成了系统级仿真分析。研究综合集成了电机动力学、齿轮传动机构与制动执行机构的动力学特性,构建了高保真的机电一体化系统模型。重点引入Stribeck摩擦模型以精确描述低速工况下执行器内部存在的静摩擦、粘滞摩擦与库仑摩擦之间的过渡行为,有效提升了系统在启停、反向运动等瞬态过程中的动态响应仿真精度。通过多工况仿真验证了模型的有效性,能够准确反映摩擦引起的爬行、滞后与定位误差等非线性现象,为EMB系统的高性能控制算法设计(如摩擦补偿、滑模控制)与结构优化提供了高可信度的仿真平台。; 适合人群:从事汽车电子制动系统、电机驱动控制、机电系统建模与仿真研究的研究生、科研人员及工程技术人员,需具备扎实的机械动力学、自动控制理论基础和MATLAB/Simulink仿真能力。; 使用场景及目标:①用于高精度电子机械制动系统的设计验证与性能预测;②为消除摩擦非线性影响的先进控制策略(如自适应控制、智能控制)提供精确的被控对象模型;③深入探究Stribeck摩擦等非线性因素对系统动态性能(如响应延迟、稳态误差)的作用机理; 阅读建议:读者应结合提供的Simulink模型文件,深入剖析Stribeck摩擦模块的数学实现与参数辨识方法,建议通过改变输入指令(如阶跃、正弦)和负载条件进行对比仿真,以直观理解非线性摩擦对系统动态特性的影响。

2,644

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧